From 6eb328e788e0e1813259dbc85ec3e618743f90e7 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 28 Apr 2014 16:45:59 +0100 Subject: [PATCH 001/349] Create a GET endpoint for getting doc lines --- services/docstore/.gitignore | 4 + services/docstore/Gruntfile.coffee | 89 ++++++++++++++ services/docstore/app.coffee | 23 ++++ .../docstore/app/coffee/DocManager.coffee | 31 +++++ .../docstore/app/coffee/HttpController.coffee | 14 +++ .../docstore/app/coffee/MongoManager.coffee | 6 + services/docstore/app/coffee/mongojs.coffee | 7 ++ .../docstore/config/settings.defaults.coffee | 11 ++ services/docstore/package.json | 25 ++++ .../test/unit/coffee/DocManagerTests.coffee | 111 ++++++++++++++++++ .../unit/coffee/HttpControllerTests.coffee | 53 +++++++++ .../test/unit/coffee/MongoManagerTests.coffee | 27 +++++ 12 files changed, 401 insertions(+) create mode 100644 services/docstore/.gitignore create mode 100644 services/docstore/Gruntfile.coffee create mode 100644 services/docstore/app.coffee create mode 100644 services/docstore/app/coffee/DocManager.coffee create mode 100644 services/docstore/app/coffee/HttpController.coffee create mode 100644 services/docstore/app/coffee/MongoManager.coffee create mode 100644 services/docstore/app/coffee/mongojs.coffee create mode 100644 services/docstore/config/settings.defaults.coffee create mode 100644 services/docstore/package.json create mode 100644 services/docstore/test/unit/coffee/DocManagerTests.coffee create mode 100644 services/docstore/test/unit/coffee/HttpControllerTests.coffee create mode 100644 services/docstore/test/unit/coffee/MongoManagerTests.coffee diff --git a/services/docstore/.gitignore b/services/docstore/.gitignore new file mode 100644 index 0000000000..6617e40b2a --- /dev/null +++ b/services/docstore/.gitignore @@ -0,0 +1,4 @@ +node_modules +app/js/ +test/unit/js +app.js diff --git a/services/docstore/Gruntfile.coffee b/services/docstore/Gruntfile.coffee new file mode 100644 index 0000000000..6c4eaf711b --- /dev/null +++ b/services/docstore/Gruntfile.coffee @@ -0,0 +1,89 @@ +spawn = require("child_process").spawn + +module.exports = (grunt) -> + grunt.initConfig + coffee: + app_src: + expand: true, + flatten: true, + cwd: "app" + src: ['coffee/*.coffee'], + dest: 'app/js/', + ext: '.js' + + app: + src: "app.coffee" + dest: "app.js" + + unit_tests: + expand: true + cwd: "test/unit/coffee" + src: ["**/*.coffee"] + dest: "test/unit/js/" + ext: ".js" + + acceptance_tests: + expand: true + cwd: "test/acceptance/coffee" + src: ["**/*.coffee"] + dest: "test/acceptance/js/" + ext: ".js" + + smoke_tests: + expand: true + cwd: "test/smoke/coffee" + src: ["**/*.coffee"] + dest: "test/smoke/js" + ext: ".js" + + clean: + app: ["app/js/"] + unit_tests: ["test/unit/js"] + acceptance_tests: ["test/acceptance/js"] + smoke_tests: ["test/smoke/js"] + + execute: + app: + src: "app.js" + + mochaTest: + unit: + options: + reporter: "spec" + src: ["test/unit/js/**/*.js"] + acceptance: + options: + reporter: "spec" + timeout: 40000 + grep: grunt.option("grep") + src: ["test/acceptance/js/**/*.js"] + smoke: + options: + reported: "spec" + timeout: 10000 + src: ["test/smoke/js/**/*.js"] + + grunt.loadNpmTasks 'grunt-contrib-coffee' + grunt.loadNpmTasks 'grunt-contrib-clean' + grunt.loadNpmTasks 'grunt-mocha-test' + grunt.loadNpmTasks 'grunt-shell' + grunt.loadNpmTasks 'grunt-execute' + grunt.loadNpmTasks 'grunt-bunyan' + + grunt.registerTask 'compile:app', ['clean:app', 'coffee:app', 'coffee:app_src', 'coffee:smoke_tests'] + grunt.registerTask 'run', ['compile:app', 'bunyan', 'execute'] + + grunt.registerTask 'compile:unit_tests', ['clean:unit_tests', 'coffee:unit_tests'] + grunt.registerTask 'test:unit', ['compile:app', 'compile:unit_tests', 'mochaTest:unit'] + + grunt.registerTask 'compile:acceptance_tests', ['clean:acceptance_tests', 'coffee:acceptance_tests'] + grunt.registerTask 'test:acceptance', ['compile:acceptance_tests', 'mochaTest:acceptance'] + + grunt.registerTask 'compile:smoke_tests', ['clean:smoke_tests', 'coffee:smoke_tests'] + grunt.registerTask 'test:smoke', ['compile:smoke_tests', 'mochaTest:smoke'] + + grunt.registerTask 'install', 'compile:app' + + grunt.registerTask 'default', ['run'] + + diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee new file mode 100644 index 0000000000..b3932ffd46 --- /dev/null +++ b/services/docstore/app.coffee @@ -0,0 +1,23 @@ +Settings = require('settings-sharelatex') +logger = require('logger-sharelatex') +logger.initialize("docstore") + +express = require('express') +HttpController = require "./app/js/HttpController" + +app = express() + +app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc + +app.get '/status', (req, res)-> + res.send('docstore is alive') + +app.use (error, req, res, next) -> + logger.error err: error, "request errored" + res.send(500, "Oops, something went wrong") + +port = Settings.internal.docstore.port +host = Settings.internal.docstore.host +app.listen port, host, (error) -> + throw error if error? + logger.log("docstore listening on #{host}:#{port}") diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee new file mode 100644 index 0000000000..201868f882 --- /dev/null +++ b/services/docstore/app/coffee/DocManager.coffee @@ -0,0 +1,31 @@ +MongoManager = require "./MongoManager" + +module.exports = DocManager = + getDoc: (project_id, doc_id, callback = (error, doc) ->) -> + MongoManager.findProject project_id, (error, project) -> + return callback(error) if error? + return callback null, null if !project? + DocManager.findDocInProject project, doc_id, (error, doc) -> + return callback(error) if error? + return callback null, doc + + findDocInProject: (project, doc_id, callback = (error, doc, mongoPath) ->) -> + result = @_findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" + if result? + callback null, result.doc, result.mongoPath + else + callback null, null, null + + _findDocInFolder: (folder, doc_id, currentPath) -> + for doc, i in folder.docs or [] + if doc._id.toString() == doc_id.toString() + return { + doc: doc + mongoPath: "#{currentPath}.docs.#{i}" + } + + for childFolder, i in folder.folders or [] + result = @_findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}" + return result if result? + + return null \ No newline at end of file diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee new file mode 100644 index 0000000000..d3eef4fa7d --- /dev/null +++ b/services/docstore/app/coffee/HttpController.coffee @@ -0,0 +1,14 @@ +DocManager = require "./DocManager" +logger = require "logger-sharelatex" + +module.exports = HttpController = + getDoc: (req, res, next = (error) ->) -> + project_id = req.params.project_id + doc_id = req.params.doc_id + logger.log project_id: project_id, doc_id: doc_id, "getting doc" + DocManager.getDoc project_id, doc_id, (error, doc) -> + return next(error) if error? + if !doc? + res.send 404 + else + res.send JSON.stringify({ lines: doc.lines }) \ No newline at end of file diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee new file mode 100644 index 0000000000..a3f97f73b1 --- /dev/null +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -0,0 +1,6 @@ +{db, ObjectId} = require "./mongojs" + +module.exports = MongoManager = + findProject: (project_id, callback = (error, project) ->) -> + db.projects.find _id: ObjectId(project_id.toString()), {}, (error, projects = []) -> + callback error, projects[0] \ No newline at end of file diff --git a/services/docstore/app/coffee/mongojs.coffee b/services/docstore/app/coffee/mongojs.coffee new file mode 100644 index 0000000000..86ce73809a --- /dev/null +++ b/services/docstore/app/coffee/mongojs.coffee @@ -0,0 +1,7 @@ +Settings = require "settings-sharelatex" +mongojs = require "mongojs" +db = mongojs.connect(Settings.mongo.url, ["projects"]) +module.exports = + db: db + ObjectId: mongojs.ObjectId + diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee new file mode 100644 index 0000000000..8a3fc9197f --- /dev/null +++ b/services/docstore/config/settings.defaults.coffee @@ -0,0 +1,11 @@ +http = require('http') +http.globalAgent.maxSockets = 300 + +module.exports = + internal: + docstore: + port: 3016 + host: "localhost" + + mongo: + url: 'mongodb://127.0.0.1/sharelatex' diff --git a/services/docstore/package.json b/services/docstore/package.json new file mode 100644 index 0000000000..efad89535d --- /dev/null +++ b/services/docstore/package.json @@ -0,0 +1,25 @@ +{ + "name": "docstore-sharelatex", + "version": "0.0.0", + "description": "A CRUD API for handling text documents in projects", + "author": "ShareLaTeX ", + "dependencies": { + "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master", + "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", + "mongojs": "0.9.11", + "express": "~4.1.1" + }, + "devDependencies": { + "grunt-execute": "~0.2.1", + "grunt-contrib-clean": "~0.5.0", + "grunt-shell": "~0.7.0", + "grunt-contrib-coffee": "~0.10.1", + "grunt-mocha-test": "~0.10.2", + "grunt": "~0.4.4", + "bunyan": "~0.22.3", + "grunt-bunyan": "~0.5.0", + "sinon": "~1.5.2", + "sandboxed-module": "~0.3.0", + "chai": "~1.9.1" + } +} diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee new file mode 100644 index 0000000000..7afc546964 --- /dev/null +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -0,0 +1,111 @@ +SandboxedModule = require('sandboxed-module') +sinon = require('sinon') +chai = require('chai') +chai.should() +expect = chai.expect +modulePath = require('path').join __dirname, '../../../app/js/DocManager' +ObjectId = require("mongojs").ObjectId + +describe "DocManager", -> + beforeEach -> + @DocManager = SandboxedModule.require modulePath, requires: + "./MongoManager": @MongoManager = {} + @doc_id = ObjectId().toString() + @project_id = ObjectId().toString() + @callback = sinon.stub() + + describe "getDoc", -> + describe "when the project exists", -> + beforeEach -> + @project = { name: "mock-project" } + @doc = { _id: @doc_id, lines: ["mock-lines"] } + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) + @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc @project_id, @doc_id, @callback + + it "should get the project from the database", -> + @MongoManager.findProject + .calledWith(@project_id) + .should.equal true + + it "should find the doc in the project", -> + @DocManager.findDocInProject + .calledWith(@project, @doc_id) + .should.equal true + + it "should return the doc", -> + @callback.calledWith(null, @doc).should.equal true + + describe "when the project does not exist", -> + beforeEach -> + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @null) + @DocManager.findDocInProject = sinon.stub() + @DocManager.getDoc @project_id, @doc_id, @callback + + it "should not try to find the doc in the project", -> + @DocManager.findDocInProject.called.should.equal false + + it "should return null", -> + @callback.calledWith(null, null).should.equal true + + describe "findDocInProject", -> + it "should find the doc when it is in the root folder", (done) -> + @DocManager.findDocInProject { + rootFolder: [{ + docs: [{ + _id: ObjectId(@doc_id) + }] + }] + }, @doc_id, (error, doc, mongoPath) => + expect(doc).to.deep.equal { _id: ObjectId(@doc_id) } + mongoPath.should.equal "rootFolder.0.docs.0" + done() + + it "should find the doc when it is in a sub folder", (done) -> + @DocManager.findDocInProject { + rootFolder: [{ + folders: [{ + docs: [{ + _id: ObjectId(@doc_id) + }] + }] + }] + }, @doc_id, (error, doc, mongoPath) => + expect(doc).to.deep.equal { _id: ObjectId(@doc_id) } + mongoPath.should.equal "rootFolder.0.folders.0.docs.0" + done() + + it "should find the doc when it there are other docs", (done) -> + @DocManager.findDocInProject { + rootFolder: [{ + folders: [{ + docs: [{ + _id: ObjectId() + }] + }, { + docs: [{ + _id: ObjectId() + }, { + _id: ObjectId(@doc_id) + }] + }], + docs: [{ + _id: ObjectId() + }] + }] + }, @doc_id, (error, doc, mongoPath) => + expect(doc).to.deep.equal { _id: ObjectId(@doc_id) } + mongoPath.should.equal "rootFolder.0.folders.1.docs.1" + done() + + it "should return null when the doc doesn't exist", (done) -> + @DocManager.findDocInProject { + rootFolder: [{ + folders: [{ + docs: [] + }] + }] + }, @doc_id, (error, doc, mongoPath) => + expect(doc).to.be.null + expect(mongoPath).to.be.null + done() diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee new file mode 100644 index 0000000000..5dfaf4de7c --- /dev/null +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -0,0 +1,53 @@ +SandboxedModule = require('sandboxed-module') +sinon = require('sinon') +chai = require('chai') +chai.should() +expect = chai.expect +modulePath = require('path').join __dirname, '../../../app/js/HttpController' + +describe "HttpController", -> + beforeEach -> + @HttpController = SandboxedModule.require modulePath, requires: + "./DocManager": @DocManager = {} + "logger-sharelatex": @logger = { log: sinon.stub() } + @res = { send: sinon.stub() } + @req = {} + @next = sinon.stub() + @project_id = "mock-project-id" + @doc_id = "mock-doc-id" + @doc = { + _id: @doc_id + lines: ["mock", "lines"] + } + + describe "getDoc", -> + describe "when the doc exists", -> + beforeEach -> + @req.params = + project_id: @project_id + doc_id: @doc_id + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @HttpController.getDoc @req, @res, @next + + it "should get the document", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should return the doc as JSON", -> + @res.send + .calledWith(JSON.stringify(lines: @doc.lines)) + .should.equal true + + describe "when the doc does not exist", -> + beforeEach -> + @req.params = + project_id: @project_id + doc_id: @doc_id + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null) + @HttpController.getDoc @req, @res, @next + + it "should return a 404", -> + @res.send + .calledWith(404) + .should.equal true \ No newline at end of file diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee new file mode 100644 index 0000000000..b3706004f1 --- /dev/null +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -0,0 +1,27 @@ +SandboxedModule = require('sandboxed-module') +sinon = require('sinon') +require('chai').should() +modulePath = require('path').join __dirname, '../../../app/js/MongoManager' +ObjectId = require("mongojs").ObjectId + +describe "MongoManager", -> + beforeEach -> + @MongoManager = SandboxedModule.require modulePath, requires: + "./mongojs": + db: @db = { projects: {} } + ObjectId: ObjectId + @project_id = ObjectId().toString() + @callback = sinon.stub() + + describe "findProject", -> + beforeEach -> + @project = { name: "mock-project" } + @db.projects.find = sinon.stub().callsArgWith(2, null, [@project]) + @MongoManager.findProject @project_id, @callback + + it "should find the project without the doc lines", -> + @db.projects.find + .calledWith({ + _id: ObjectId(@project_id) + }, {}) + .should.equal true From f09444de3b893c8f18ae972970ed8adf1b6778f5 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 28 Apr 2014 16:48:36 +0100 Subject: [PATCH 002/349] Create .travis.yml --- services/docstore/.travis.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 services/docstore/.travis.yml diff --git a/services/docstore/.travis.yml b/services/docstore/.travis.yml new file mode 100644 index 0000000000..6f9b984892 --- /dev/null +++ b/services/docstore/.travis.yml @@ -0,0 +1,21 @@ +language: node_js + +node_js: + - "0.10" + +before_install: + - npm install -g grunt-cli + +install: + - npm install + - grunt install + +before_script: + - grunt forever:app:start + +script: + - grunt test:unit + - grunt test:acceptance + +services: + - mongodb From f4e7b47b9001241b5dd70935f00d376875f045a5 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 28 Apr 2014 16:50:23 +0100 Subject: [PATCH 003/349] Create README.md --- services/docstore/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 services/docstore/README.md diff --git a/services/docstore/README.md b/services/docstore/README.md new file mode 100644 index 0000000000..9b6ba5dd83 --- /dev/null +++ b/services/docstore/README.md @@ -0,0 +1,13 @@ +docstore-sharelatex +=================== + +A CRUD API for storing and updating text documents in projects + +[![Build Status](https://travis-ci.org/sharelatex/docstore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/docstore-sharelatex) + +License +------- + +The code in this repository is released under the GNU AFFERO GENERAL PUBLIC LICENSE, version 3. A copy can be found in the `LICENSE` file. + +Copyright (c) ShareLaTeX, 2014. From 4adfcc0e5e7325691097449d4b2842d4f86a3653 Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 28 Apr 2014 16:50:47 +0100 Subject: [PATCH 004/349] Create LICENSE --- services/docstore/LICENSE | 662 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 662 insertions(+) create mode 100644 services/docstore/LICENSE diff --git a/services/docstore/LICENSE b/services/docstore/LICENSE new file mode 100644 index 0000000000..ac8619dcb9 --- /dev/null +++ b/services/docstore/LICENSE @@ -0,0 +1,662 @@ + + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. From 22b13077b25659244ed691fdb5229ab654b8774e Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 28 Apr 2014 16:53:51 +0100 Subject: [PATCH 005/349] Add in grunt forever command --- services/docstore/Gruntfile.coffee | 5 +++++ services/docstore/package.json | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/services/docstore/Gruntfile.coffee b/services/docstore/Gruntfile.coffee index 6c4eaf711b..099955bc9b 100644 --- a/services/docstore/Gruntfile.coffee +++ b/services/docstore/Gruntfile.coffee @@ -2,6 +2,10 @@ spawn = require("child_process").spawn module.exports = (grunt) -> grunt.initConfig + forever: + app: + options: + index: "app.js" coffee: app_src: expand: true, @@ -69,6 +73,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-shell' grunt.loadNpmTasks 'grunt-execute' grunt.loadNpmTasks 'grunt-bunyan' + grunt.loadNpmTasks 'grunt-forever' grunt.registerTask 'compile:app', ['clean:app', 'coffee:app', 'coffee:app_src', 'coffee:smoke_tests'] grunt.registerTask 'run', ['compile:app', 'bunyan', 'execute'] diff --git a/services/docstore/package.json b/services/docstore/package.json index efad89535d..02466a9fd7 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -20,6 +20,7 @@ "grunt-bunyan": "~0.5.0", "sinon": "~1.5.2", "sandboxed-module": "~0.3.0", - "chai": "~1.9.1" + "chai": "~1.9.1", + "grunt-forever": "~0.4.4" } } From 94b25055fcf705dcbcb8f629f1406d87b8ab0a5b Mon Sep 17 00:00:00 2001 From: James Allen Date: Mon, 28 Apr 2014 17:43:19 +0100 Subject: [PATCH 006/349] Add in DocManager.updateDoc method --- services/docstore/.gitignore | 1 + services/docstore/app.coffee | 6 +- .../docstore/app/coffee/DocManager.coffee | 30 +++++- .../docstore/app/coffee/MongoManager.coffee | 11 ++- services/docstore/package.json | 3 +- .../test/unit/coffee/DocManagerTests.coffee | 93 ++++++++++++++++++- .../test/unit/coffee/MongoManagerTests.coffee | 25 +++++ 7 files changed, 158 insertions(+), 11 deletions(-) diff --git a/services/docstore/.gitignore b/services/docstore/.gitignore index 6617e40b2a..fadf405279 100644 --- a/services/docstore/.gitignore +++ b/services/docstore/.gitignore @@ -2,3 +2,4 @@ node_modules app/js/ test/unit/js app.js +forever diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index b3932ffd46..b61287fec6 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -4,6 +4,7 @@ logger.initialize("docstore") express = require('express') HttpController = require "./app/js/HttpController" +Errors = require "./app/js/Errors" app = express() @@ -14,7 +15,10 @@ app.get '/status', (req, res)-> app.use (error, req, res, next) -> logger.error err: error, "request errored" - res.send(500, "Oops, something went wrong") + if error instanceof Errors.NotFoundError + res.send 404 + else + res.send(500, "Oops, something went wrong") port = Settings.internal.docstore.port host = Settings.internal.docstore.host diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 201868f882..047d32f552 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -1,13 +1,35 @@ MongoManager = require "./MongoManager" +Errors = require "./Errors" +logger = require "logger-sharelatex" +_ = require "underscore" module.exports = DocManager = - getDoc: (project_id, doc_id, callback = (error, doc) ->) -> + getDoc: (project_id, doc_id, callback = (error, doc, mongoPath) ->) -> MongoManager.findProject project_id, (error, project) -> return callback(error) if error? - return callback null, null if !project? - DocManager.findDocInProject project, doc_id, (error, doc) -> + return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? + DocManager.findDocInProject project, doc_id, (error, doc, mongoPath) -> return callback(error) if error? - return callback null, doc + return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? + return callback null, doc, mongoPath + + updateDoc: (project_id, doc_id, lines, callback = (error) ->) -> + DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> + return callback(error) if error? + return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? + + if _.isEqual(doc.lines, lines) + logger.log { + project_id: project_id, doc_id: doc_id, rev: doc.rev + }, "doc lines have not changed" + return callback() + else + logger.log { + project_id: project_id, doc_id: doc_id, oldDocLines: doc.lines, newDocLines: lines, rev: doc.rev + }, "updating doc lines" + MongoManager.updateDoc project_id, mongoPath, lines, (error) -> + return callback(error) if error? + callback() findDocInProject: (project, doc_id, callback = (error, doc, mongoPath) ->) -> result = @_findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index a3f97f73b1..422e678255 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -3,4 +3,13 @@ module.exports = MongoManager = findProject: (project_id, callback = (error, project) ->) -> db.projects.find _id: ObjectId(project_id.toString()), {}, (error, projects = []) -> - callback error, projects[0] \ No newline at end of file + callback error, projects[0] + + updateDoc: (project_id, docPath, lines, callback = (error) ->) -> + update = + $set: {} + $inc: {} + update.$set["#{docPath}.lines"] = lines + update.$inc["#{docPath}.rev"] = 1 + + db.projects.update _id: ObjectId(project_id), update, callback \ No newline at end of file diff --git a/services/docstore/package.json b/services/docstore/package.json index 02466a9fd7..94335c97f4 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -7,7 +7,8 @@ "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", "mongojs": "0.9.11", - "express": "~4.1.1" + "express": "~4.1.1", + "underscore": "~1.6.0" }, "devDependencies": { "grunt-execute": "~0.2.1", diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 7afc546964..525bf7cb7e 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -5,11 +5,13 @@ chai.should() expect = chai.expect modulePath = require('path').join __dirname, '../../../app/js/DocManager' ObjectId = require("mongojs").ObjectId +Errors = require "../../../app/js/Errors" describe "DocManager", -> beforeEach -> @DocManager = SandboxedModule.require modulePath, requires: "./MongoManager": @MongoManager = {} + "logger-sharelatex": @logger = {log: sinon.stub()} @doc_id = ObjectId().toString() @project_id = ObjectId().toString() @callback = sinon.stub() @@ -19,8 +21,9 @@ describe "DocManager", -> beforeEach -> @project = { name: "mock-project" } @doc = { _id: @doc_id, lines: ["mock-lines"] } + @mongoPath = "mock.mongo.path" @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) - @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) @DocManager.getDoc @project_id, @doc_id, @callback it "should get the project from the database", -> @@ -34,7 +37,7 @@ describe "DocManager", -> .should.equal true it "should return the doc", -> - @callback.calledWith(null, @doc).should.equal true + @callback.calledWith(null, @doc, @mongoPath).should.equal true describe "when the project does not exist", -> beforeEach -> @@ -45,8 +48,90 @@ describe "DocManager", -> it "should not try to find the doc in the project", -> @DocManager.findDocInProject.called.should.equal false - it "should return null", -> - @callback.calledWith(null, null).should.equal true + it "should return a NotFoundError", -> + @callback + .calledWith(new Errors.NotFoundError("No such project: #{@project_id}")) + .should.equal true + + describe "when the doc does not exist", -> + beforeEach -> + @project = { name: "mock-project" } + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) + @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null) + @DocManager.getDoc @project_id, @doc_id, @callback + + it "should try to find the doc in the project", -> + @DocManager.findDocInProject + .calledWith(@project, @doc_id) + .should.equal true + + it "should return a NotFoundError", -> + @callback + .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) + .should.equal true + + describe "updateDoc", -> + beforeEach -> + @oldDocLines = ["old", "doc", "lines"] + @newDocLines = ["new", "doc", "lines"] + @doc = { _id: @doc_id, lines: @oldDocLines, rev: 42 } + @mongoPath = "mock.mongo.path" + + @MongoManager.updateDoc = sinon.stub().callsArg(3) + + describe "when the doc lines have changed", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + + it "should get the existing doc", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should update the doc with the new doc lines", -> + @MongoManager.updateDoc + .calledWith(@project_id, @mongoPath, @newDocLines) + .should.equal true + + it "should log out the old and new doc lines", -> + @logger.log + .calledWith( + project_id: @project_id + doc_id: @doc_id + oldDocLines: @oldDocLines + newDocLines: @newDocLines + rev: @doc.rev + "updating doc lines" + ) + .should.equal true + + it "should return the callback", -> + @callback.called.should.equal true + + describe "when the doc lines have not changed", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback + + it "should not update the doc", -> + @MongoManager.updateDoc.called.should.equal false + + it "should return the callback", -> + @callback.called.should.equal true + + describe "when the doc does not exist", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + + it "should not try to update the doc", -> + @MongoManager.updateDoc.called.should.equal false + + it "should return a NotFoundError", -> + @callback + .calledWith(new Errors.NotFoundError("No such project/doc: #{@project_id}/#{@doc_id}")) + .should.equal true describe "findDocInProject", -> it "should find the doc when it is in the root folder", (done) -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index b3706004f1..61c0b45de6 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -25,3 +25,28 @@ describe "MongoManager", -> _id: ObjectId(@project_id) }, {}) .should.equal true + + it "should call the callback with the project", -> + @callback.calledWith(null, @project).should.equal true + + describe "updateDoc", -> + beforeEach -> + @lines = ["mock-lines"] + @docPath = "rootFolder.0.folders.1.docs.0" + @db.projects.update = sinon.stub().callsArg(2) + @MongoManager.updateDoc @project_id, @docPath, @lines, @callback + + it "should update the doc lines and increment the TPDS rev", -> + @db.projects.update + .calledWith({ + _id: ObjectId(@project_id) + }, { + $set: + "rootFolder.0.folders.1.docs.0.lines": @lines + $inc: + "rootFolder.0.folders.1.docs.0.rev": 1 + }) + .should.equal true + + it "should call the callback with the project", -> + @callback.called.should.equal true From 2e8582874f424b18b62778dbf69b78d8a0736793 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 29 Apr 2014 11:49:09 +0100 Subject: [PATCH 007/349] Add POST end point for updating doc lines --- services/docstore/.gitignore | 1 + services/docstore/app.coffee | 16 ++-- .../docstore/app/coffee/DocManager.coffee | 6 +- services/docstore/app/coffee/Errors.coffee | 10 +++ .../docstore/app/coffee/HttpController.coffee | 23 ++++- services/docstore/package.json | 6 +- .../acceptance/coffee/GettingDocsTests.coffee | 30 +++++++ .../coffee/UpdatingDocsTests.coffee | 89 +++++++++++++++++++ .../coffee/helpers/DocstoreClient.coffee | 37 ++++++++ .../test/unit/coffee/DocManagerTests.coffee | 4 +- .../unit/coffee/HttpControllerTests.coffee | 83 ++++++++++++----- 11 files changed, 265 insertions(+), 40 deletions(-) create mode 100644 services/docstore/app/coffee/Errors.coffee create mode 100644 services/docstore/test/acceptance/coffee/GettingDocsTests.coffee create mode 100644 services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee create mode 100644 services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee diff --git a/services/docstore/.gitignore b/services/docstore/.gitignore index fadf405279..99832d28c8 100644 --- a/services/docstore/.gitignore +++ b/services/docstore/.gitignore @@ -1,5 +1,6 @@ node_modules app/js/ test/unit/js +test/acceptance/js app.js forever diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index b61287fec6..e3acb4529f 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -1,14 +1,16 @@ -Settings = require('settings-sharelatex') -logger = require('logger-sharelatex') -logger.initialize("docstore") - -express = require('express') +Settings = require "settings-sharelatex" +logger = require "logger-sharelatex" +express = require "express" +bodyParser = require "body-parser" +Errors = require "./app/js/Errors" HttpController = require "./app/js/HttpController" -Errors = require "./app/js/Errors" + +logger.initialize("docstore") app = express() -app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc +app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc +app.post '/project/:project_id/doc/:doc_id', bodyParser.json(), HttpController.updateDoc app.get '/status', (req, res)-> res.send('docstore is alive') diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 047d32f552..db60024a99 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -13,7 +13,7 @@ module.exports = DocManager = return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? return callback null, doc, mongoPath - updateDoc: (project_id, doc_id, lines, callback = (error) ->) -> + updateDoc: (project_id, doc_id, lines, callback = (error, modified) ->) -> DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? @@ -22,14 +22,14 @@ module.exports = DocManager = logger.log { project_id: project_id, doc_id: doc_id, rev: doc.rev }, "doc lines have not changed" - return callback() + return callback null, false else logger.log { project_id: project_id, doc_id: doc_id, oldDocLines: doc.lines, newDocLines: lines, rev: doc.rev }, "updating doc lines" MongoManager.updateDoc project_id, mongoPath, lines, (error) -> return callback(error) if error? - callback() + callback null, true findDocInProject: (project, doc_id, callback = (error, doc, mongoPath) ->) -> result = @_findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" diff --git a/services/docstore/app/coffee/Errors.coffee b/services/docstore/app/coffee/Errors.coffee new file mode 100644 index 0000000000..4a29822efc --- /dev/null +++ b/services/docstore/app/coffee/Errors.coffee @@ -0,0 +1,10 @@ +NotFoundError = (message) -> + error = new Error(message) + error.name = "NotFoundError" + error.__proto__ = NotFoundError.prototype + return error +NotFoundError.prototype.__proto__ = Error.prototype + +module.exports = Errors = + NotFoundError: NotFoundError + diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index d3eef4fa7d..fc30f1adb9 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -4,11 +4,30 @@ logger = require "logger-sharelatex" module.exports = HttpController = getDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id - doc_id = req.params.doc_id + doc_id = req.params.doc_id logger.log project_id: project_id, doc_id: doc_id, "getting doc" DocManager.getDoc project_id, doc_id, (error, doc) -> return next(error) if error? if !doc? res.send 404 else - res.send JSON.stringify({ lines: doc.lines }) \ No newline at end of file + res.json { + lines: doc.lines + } + + updateDoc: (req, res, next = (error) ->) -> + project_id = req.params.project_id + doc_id = req.params.doc_id + lines = req.body?.lines + + if !lines? or lines not instanceof Array + logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided" + res.send 400 # Bad Request + return + + logger.log project_id: project_id, doc_id: doc_id, "updating doc" + DocManager.updateDoc project_id, doc_id, lines, (error, modified) -> + return next(error) if error? + res.json { + modified: modified + } \ No newline at end of file diff --git a/services/docstore/package.json b/services/docstore/package.json index 94335c97f4..d3d13b2278 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -8,7 +8,8 @@ "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", "mongojs": "0.9.11", "express": "~4.1.1", - "underscore": "~1.6.0" + "underscore": "~1.6.0", + "body-parser": "~1.0.2" }, "devDependencies": { "grunt-execute": "~0.2.1", @@ -22,6 +23,7 @@ "sinon": "~1.5.2", "sandboxed-module": "~0.3.0", "chai": "~1.9.1", - "grunt-forever": "~0.4.4" + "grunt-forever": "~0.4.4", + "request": "~2.34.0" } } diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee new file mode 100644 index 0000000000..398f8b3690 --- /dev/null +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -0,0 +1,30 @@ +sinon = require "sinon" +chai = require("chai") +chai.should() +{ObjectId} = require "mongojs" + +DocstoreClient = require "./helpers/DocstoreClient" + +describe "Applying updates to a doc", -> + beforeEach (done) -> + @project_id = ObjectId() + @lines = ["original", "lines"] + DocstoreClient.createDoc @project_id, @lines, (error, @doc_id) => + done() + + afterEach (done) -> + DocstoreClient.deleteProject @project_id, done + + describe "when the doc exists", -> + it "should get the doc lines", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + doc.lines.should.deep.equal @lines + done() + + describe "when the doc does not exist", -> + it "should return a 404", (done) -> + missing_doc_id = ObjectId() + DocstoreClient.getDoc @project_id, missing_doc_id, (error, res, doc) -> + res.statusCode.should.equal 404 + done() + diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee new file mode 100644 index 0000000000..107967ebd3 --- /dev/null +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -0,0 +1,89 @@ +sinon = require "sinon" +chai = require("chai") +chai.should() +{ObjectId} = require "mongojs" + +DocstoreClient = require "./helpers/DocstoreClient" + +describe "Applying updates to a doc", -> + beforeEach (done) -> + @project_id = ObjectId() + @originalLines = ["original", "lines"] + @newLines = ["new", "lines"] + DocstoreClient.createDoc @project_id, @originalLines, (error, @doc_id) => + done() + + afterEach (done) -> + DocstoreClient.deleteProject @project_id, done + + describe "when the content has changed", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, @newLines, (error, res, @body) => + done() + + it "should return modified = true", -> + @body.modified.should.equal true + + it "should update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + doc.lines.should.deep.equal @newLines + done() + + describe "when the content has not been updated", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, (error, res, @body) => + done() + + it "should return modified = false", -> + @body.modified.should.equal false + + it "should not update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + done() + + describe "when the doc does not exist", -> + beforeEach (done) -> + missing_doc_id = ObjectId() + DocstoreClient.updateDoc @project_id, missing_doc_id, @originalLines, (error, @res, @body) => + done() + + it "should return a 404", -> + @res.statusCode.should.equal 404 + + describe "when the project does not exist", -> + beforeEach (done) -> + missing_project_id = ObjectId() + DocstoreClient.updateDoc missing_project_id, @doc_id, @originalLines, (error, @res, @body) => + done() + + it "should return a 404", -> + @res.statusCode.should.equal 404 + + describe "when malformed doc lines are provided", -> + describe "when the lines are not an array", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, (error, @res, @body) => + done() + + it "should return 400", -> + @res.statusCode.should.equal 400 + + it "should not update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + done() + + describe "when the lines are not present", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, null, (error, @res, @body) => + done() + + it "should return 400", -> + @res.statusCode.should.equal 400 + + it "should not update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + done() + diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee new file mode 100644 index 0000000000..f80afcd1af --- /dev/null +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -0,0 +1,37 @@ +request = require("request").defaults(jar: false) +{db, ObjectId} = require("../../../../app/js/mongojs") + +module.exports = DocstoreClient = + createDoc: (project_id, lines, callback = (error, doc_id) ->) -> + doc_id = ObjectId() + db.projects.insert { + _id: project_id + rootFolder: [{ + docs: [{ + _id: doc_id, + lines: lines + }] + }] + }, (error) -> + return callback(error) if error? + callback null, doc_id + + deleteProject: (project_id, callback = (error, res, body) ->) -> + db.projects.remove _id: project_id, callback + + getDoc: (project_id, doc_id, callback = (error, doc) ->) -> + request.get { + url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + json: true + }, callback + + updateDoc: (project_id, doc_id, lines, callback = (error, res, body) ->) -> + request.post { + url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + json: + lines: lines + }, callback + + + + diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 525bf7cb7e..e884be28af 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -107,7 +107,7 @@ describe "DocManager", -> .should.equal true it "should return the callback", -> - @callback.called.should.equal true + @callback.calledWith(null, true).should.equal true describe "when the doc lines have not changed", -> beforeEach -> @@ -118,7 +118,7 @@ describe "DocManager", -> @MongoManager.updateDoc.called.should.equal false it "should return the callback", -> - @callback.called.should.equal true + @callback.calledWith(null, false).should.equal true describe "when the doc does not exist", -> beforeEach -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 5dfaf4de7c..f942b4dbf0 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -9,8 +9,8 @@ describe "HttpController", -> beforeEach -> @HttpController = SandboxedModule.require modulePath, requires: "./DocManager": @DocManager = {} - "logger-sharelatex": @logger = { log: sinon.stub() } - @res = { send: sinon.stub() } + "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } + @res = { send: sinon.stub(), json: sinon.stub() } @req = {} @next = sinon.stub() @project_id = "mock-project-id" @@ -21,33 +21,68 @@ describe "HttpController", -> } describe "getDoc", -> - describe "when the doc exists", -> - beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) - @HttpController.getDoc @req, @res, @next + beforeEach -> + @req.params = + project_id: @project_id + doc_id: @doc_id + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @HttpController.getDoc @req, @res, @next - it "should get the document", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id) + it "should get the document", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should return the doc as JSON", -> + @res.json + .calledWith(lines: @doc.lines) + .should.equal true + + describe "updateDoc", -> + beforeEach -> + @req.params = + project_id: @project_id + doc_id: @doc_id + + describe "when the doc lines exist and were updated", -> + beforeEach -> + @req.body = + lines: @lines = ["hello", "world"] + @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, true) + @HttpController.updateDoc @req, @res, @next + + it "should update the document", -> + @DocManager.updateDoc + .calledWith(@project_id, @doc_id, @lines) .should.equal true - it "should return the doc as JSON", -> - @res.send - .calledWith(JSON.stringify(lines: @doc.lines)) + it "should return a modified status", -> + @res.json + .calledWith(modified: true) .should.equal true - describe "when the doc does not exist", -> + describe "when the doc lines exist and were not updated", -> beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null) - @HttpController.getDoc @req, @res, @next + @req.body = + lines: @lines = ["hello", "world"] + @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, false) + @HttpController.updateDoc @req, @res, @next - it "should return a 404", -> + it "should return a modified status", -> + @res.json + .calledWith(modified: false) + .should.equal true + + describe "when the doc lines are not provided", -> + beforeEach -> + @req.body = {} + @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, false) + @HttpController.updateDoc @req, @res, @next + + it "should not update the document", -> + @DocManager.updateDoc.called.should.equal false + + it "should return a 400 (bad request) response", -> @res.send - .calledWith(404) - .should.equal true \ No newline at end of file + .calledWith(400) + .should.equal true From 9be5265f32924a615c72e6b3ff799bbe202302f3 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 29 Apr 2014 12:31:30 +0100 Subject: [PATCH 008/349] Update gruntfile with configurable report --- services/docstore/Gruntfile.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/services/docstore/Gruntfile.coffee b/services/docstore/Gruntfile.coffee index 099955bc9b..a9ac6e5180 100644 --- a/services/docstore/Gruntfile.coffee +++ b/services/docstore/Gruntfile.coffee @@ -53,17 +53,17 @@ module.exports = (grunt) -> mochaTest: unit: options: - reporter: "spec" + reporter: grunt.option('reporter') or 'spec' src: ["test/unit/js/**/*.js"] acceptance: options: - reporter: "spec" + reporter: grunt.option('reporter') or 'spec' timeout: 40000 grep: grunt.option("grep") src: ["test/acceptance/js/**/*.js"] smoke: options: - reported: "spec" + reporter: grunt.option('reporter') or 'spec' timeout: 10000 src: ["test/smoke/js/**/*.js"] @@ -75,7 +75,7 @@ module.exports = (grunt) -> grunt.loadNpmTasks 'grunt-bunyan' grunt.loadNpmTasks 'grunt-forever' - grunt.registerTask 'compile:app', ['clean:app', 'coffee:app', 'coffee:app_src', 'coffee:smoke_tests'] + grunt.registerTask 'compile:app', ['clean:app', 'coffee:app', 'coffee:app_src'] grunt.registerTask 'run', ['compile:app', 'bunyan', 'execute'] grunt.registerTask 'compile:unit_tests', ['clean:unit_tests', 'coffee:unit_tests'] From 885d5de191001b229d7fb3be46146707cf0bb9bf Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 29 Apr 2014 15:07:22 +0100 Subject: [PATCH 009/349] Add in DocManager.deleteDoc method --- .../docstore/app/coffee/DocManager.coffee | 8 ++++ .../docstore/app/coffee/MongoManager.coffee | 7 +++- .../test/unit/coffee/DocManagerTests.coffee | 38 +++++++++++++++++++ .../test/unit/coffee/MongoManagerTests.coffee | 19 ++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index db60024a99..0d730ad7de 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -31,6 +31,14 @@ module.exports = DocManager = return callback(error) if error? callback null, true + deleteDoc: (project_id, doc_id, callback = (error) ->) -> + DocManager.getDoc project_id, doc_id, (error, doc) -> + return callback(error) if error? + return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? + MongoManager.insertDoc project_id, doc_id, { lines: doc.lines, deleted: true }, (error) -> + return callback(error) if error? + callback() + findDocInProject: (project, doc_id, callback = (error, doc, mongoPath) ->) -> result = @_findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" if result? diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 422e678255..a988c9bd01 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -12,4 +12,9 @@ module.exports = MongoManager = update.$set["#{docPath}.lines"] = lines update.$inc["#{docPath}.rev"] = 1 - db.projects.update _id: ObjectId(project_id), update, callback \ No newline at end of file + db.projects.update _id: ObjectId(project_id), update, callback + + insertDoc: (project_id, doc_id, attributes, callback = (error) ->) -> + attributes._id = ObjectId(doc_id) + attributes.project_id = ObjectId(project_id) + db.projects.insert attributes, callback \ No newline at end of file diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index e884be28af..0ab746e2d2 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -70,6 +70,44 @@ describe "DocManager", -> .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) .should.equal true + describe "deleteDoc", -> + describe "when the doc exists", -> + beforeEach -> + @lines = ["mock", "doc", "lines"] + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, lines: @lines) + @MongoManager.insertDoc = sinon.stub().callsArg(3) + @DocManager.deleteDoc @project_id, @doc_id, @callback + + it "should get the doc", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "insert the doc as a deleted doc", -> + @MongoManager.insertDoc + .calledWith(@project_id, @doc_id, { + lines: @lines + deleted: true + }) + .should.equal true + + it "should return the callback", -> + @callback.called.should.equal true + + describe "when the doc does not exist", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null) + @MongoManager.insertDoc = sinon.stub().callsArg(3) + @DocManager.deleteDoc @project_id, @doc_id, @callback + + it "should not try to insert a deleted doc", -> + @MongoManager.insertDoc.called.should.equal false + + it "should return a NotFoundError", -> + @callback + .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) + .should.equal true + describe "updateDoc", -> beforeEach -> @oldDocLines = ["old", "doc", "lines"] diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 61c0b45de6..63386d757c 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -50,3 +50,22 @@ describe "MongoManager", -> it "should call the callback with the project", -> @callback.called.should.equal true + + describe "insertDoc", -> + beforeEach -> + @doc_id = ObjectId().toString() + @lines = ["mock-lines"] + @db.projects.insert = sinon.stub().callsArg(1) + @MongoManager.insertDoc @project_id, @doc_id, lines: @lines, @callback + + it "should insert the attributes with the given doc and project id", -> + @db.projects.insert + .calledWith({ + _id: ObjectId(@doc_id) + project_id: ObjectId(@project_id) + lines: @lines + }) + .should.equal true + + it "should call the callback", -> + @callback.called.should.equal true \ No newline at end of file From 984999ec615e5a9989f59fb26f1719de7d4e1b92 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 29 Apr 2014 16:36:10 +0100 Subject: [PATCH 010/349] Add in HTTP end point for deleting docs --- services/docstore/app.coffee | 1 + .../docstore/app/coffee/HttpController.coffee | 10 ++++- .../docstore/app/coffee/MongoManager.coffee | 2 +- services/docstore/app/coffee/mongojs.coffee | 2 +- .../coffee/DeletingDocsTests.coffee | 39 +++++++++++++++++++ .../coffee/helpers/DocstoreClient.coffee | 5 +++ .../unit/coffee/HttpControllerTests.coffee | 18 +++++++++ .../test/unit/coffee/MongoManagerTests.coffee | 6 +-- 8 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index e3acb4529f..8b89bb97ec 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -11,6 +11,7 @@ app = express() app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(), HttpController.updateDoc +app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.get '/status', (req, res)-> res.send('docstore is alive') diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index fc30f1adb9..314d1490b1 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -30,4 +30,12 @@ module.exports = HttpController = return next(error) if error? res.json { modified: modified - } \ No newline at end of file + } + + deleteDoc: (req, res, next = (error) ->) -> + project_id = req.params.project_id + doc_id = req.params.doc_id + logger.log project_id: project_id, doc_id: doc_id, "deleting doc" + DocManager.deleteDoc project_id, doc_id, (error) -> + return next(error) if error? + res.send 204 \ No newline at end of file diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index a988c9bd01..23e98e69c3 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -17,4 +17,4 @@ module.exports = MongoManager = insertDoc: (project_id, doc_id, attributes, callback = (error) ->) -> attributes._id = ObjectId(doc_id) attributes.project_id = ObjectId(project_id) - db.projects.insert attributes, callback \ No newline at end of file + db.docs.insert attributes, callback \ No newline at end of file diff --git a/services/docstore/app/coffee/mongojs.coffee b/services/docstore/app/coffee/mongojs.coffee index 86ce73809a..aae672b8f3 100644 --- a/services/docstore/app/coffee/mongojs.coffee +++ b/services/docstore/app/coffee/mongojs.coffee @@ -1,6 +1,6 @@ Settings = require "settings-sharelatex" mongojs = require "mongojs" -db = mongojs.connect(Settings.mongo.url, ["projects"]) +db = mongojs.connect(Settings.mongo.url, ["projects", "docs"]) module.exports = db: db ObjectId: mongojs.ObjectId diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee new file mode 100644 index 0000000000..a82906be89 --- /dev/null +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -0,0 +1,39 @@ +sinon = require "sinon" +chai = require("chai") +chai.should() +{db, ObjectId} = require "../../../app/js/mongojs" + +DocstoreClient = require "./helpers/DocstoreClient" + +describe "Applying updates to a doc", -> + beforeEach (done) -> + @project_id = ObjectId() + @lines = ["original", "lines"] + DocstoreClient.createDoc @project_id, @lines, (error, @doc_id) => + done() + + afterEach (done) -> + DocstoreClient.deleteProject @project_id, done + + describe "when the doc exists", -> + beforeEach (done) -> + DocstoreClient.deleteDoc @project_id, @doc_id, (error, @res, doc) => + done() + + afterEach (done) -> + db.docs.remove({_id: @doc_id}, done) + + it "should insert a deleted doc into the docs collection", (done) -> + db.docs.find _id: @doc_id, (error, docs) => + docs[0]._id.should.deep.equal @doc_id + docs[0].lines.should.deep.equal @lines + docs[0].deleted.should.equal true + done() + + describe "when the doc does not exist", -> + it "should return a 404", (done) -> + missing_doc_id = ObjectId() + DocstoreClient.deleteDoc @project_id, missing_doc_id, (error, res, doc) -> + res.statusCode.should.equal 404 + done() + diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index f80afcd1af..6aec513246 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -31,6 +31,11 @@ module.exports = DocstoreClient = json: lines: lines }, callback + + deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> + request.del { + url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + }, callback diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index f942b4dbf0..576fd66122 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -86,3 +86,21 @@ describe "HttpController", -> @res.send .calledWith(400) .should.equal true + + describe "deleteDoc", -> + beforeEach -> + @req.params = + project_id: @project_id + doc_id: @doc_id + @DocManager.deleteDoc = sinon.stub().callsArg(2) + @HttpController.deleteDoc @req, @res, @next + + it "should delete the document", -> + @DocManager.deleteDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should return a 204 (No Content)", -> + @res.send + .calledWith(204) + .should.equal true diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 63386d757c..d8c7411eec 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -8,7 +8,7 @@ describe "MongoManager", -> beforeEach -> @MongoManager = SandboxedModule.require modulePath, requires: "./mongojs": - db: @db = { projects: {} } + db: @db = { projects: {}, docs: {} } ObjectId: ObjectId @project_id = ObjectId().toString() @callback = sinon.stub() @@ -55,11 +55,11 @@ describe "MongoManager", -> beforeEach -> @doc_id = ObjectId().toString() @lines = ["mock-lines"] - @db.projects.insert = sinon.stub().callsArg(1) + @db.docs.insert = sinon.stub().callsArg(1) @MongoManager.insertDoc @project_id, @doc_id, lines: @lines, @callback it "should insert the attributes with the given doc and project id", -> - @db.projects.insert + @db.docs.insert .calledWith({ _id: ObjectId(@doc_id) project_id: ObjectId(@project_id) From fa049ff4ebb64671e95fefe7971934ffb83943df Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 30 Apr 2014 13:06:12 +0100 Subject: [PATCH 011/349] Add endpoint for getting all docs --- services/docstore/app.coffee | 1 + .../docstore/app/coffee/DocManager.coffee | 20 +++++- .../docstore/app/coffee/HttpController.coffee | 21 +++++-- services/docstore/package.json | 3 +- .../coffee/DeletingDocsTests.coffee | 10 ++- .../coffee/GettingAllDocsTests.coffee | 45 ++++++++++++++ .../acceptance/coffee/GettingDocsTests.coffee | 10 ++- .../coffee/UpdatingDocsTests.coffee | 8 ++- .../coffee/helpers/DocstoreClient.coffee | 32 ++++++---- .../test/unit/coffee/DocManagerTests.coffee | 61 ++++++++++++++++++- .../unit/coffee/HttpControllerTests.coffee | 48 ++++++++++++++- 11 files changed, 232 insertions(+), 27 deletions(-) create mode 100644 services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 8b89bb97ec..f8024ec188 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -9,6 +9,7 @@ logger.initialize("docstore") app = express() +app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 0d730ad7de..1f8bf64514 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -13,6 +13,14 @@ module.exports = DocManager = return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? return callback null, doc, mongoPath + getAllDocs: (project_id, callback = (error, docs) ->) -> + MongoManager.findProject project_id, (error, project) -> + return callback(error) if error? + return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? + DocManager.findAllDocsInProject project, (error, docs) -> + return callback(error) if error? + return callback null, docs + updateDoc: (project_id, doc_id, lines, callback = (error, modified) ->) -> DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> return callback(error) if error? @@ -39,6 +47,9 @@ module.exports = DocManager = return callback(error) if error? callback() + findAllDocsInProject: (project, callback = (error, docs) ->) -> + callback null, @_findAllDocsInFolder project.rootFolder[0] + findDocInProject: (project, doc_id, callback = (error, doc, mongoPath) ->) -> result = @_findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" if result? @@ -58,4 +69,11 @@ module.exports = DocManager = result = @_findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}" return result if result? - return null \ No newline at end of file + return null + + _findAllDocsInFolder: (folder) -> + docs = folder.docs or [] + for childFolder in folder.folders or [] + docs = docs.concat @_findAllDocsInFolder childFolder + return docs + diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 314d1490b1..781376b5a5 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -11,9 +11,14 @@ module.exports = HttpController = if !doc? res.send 404 else - res.json { - lines: doc.lines - } + res.json HttpController._buildDocView(doc) + + getAllDocs: (req, res, next = (error) ->) -> + project_id = req.params.project_id + logger.log project_id: project_id, "getting all docs" + DocManager.getAllDocs project_id, (error, docs = []) -> + return next(error) if error? + res.json docs.map(HttpController._buildDocView) updateDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id @@ -38,4 +43,12 @@ module.exports = HttpController = logger.log project_id: project_id, doc_id: doc_id, "deleting doc" DocManager.deleteDoc project_id, doc_id, (error) -> return next(error) if error? - res.send 204 \ No newline at end of file + res.send 204 + + _buildDocView: (doc) -> + return { + _id: doc._id.toString() + lines: doc.lines + rev: doc.rev + version: doc.version + } \ No newline at end of file diff --git a/services/docstore/package.json b/services/docstore/package.json index d3d13b2278..029f13cebc 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -9,7 +9,8 @@ "mongojs": "0.9.11", "express": "~4.1.1", "underscore": "~1.6.0", - "body-parser": "~1.0.2" + "body-parser": "~1.0.2", + "async": "~0.8.0" }, "devDependencies": { "grunt-execute": "~0.2.1", diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee index a82906be89..a1dbe937da 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -5,12 +5,16 @@ chai.should() DocstoreClient = require "./helpers/DocstoreClient" -describe "Applying updates to a doc", -> +describe "Deleting a doc", -> beforeEach (done) -> @project_id = ObjectId() + @doc_id = ObjectId() @lines = ["original", "lines"] - DocstoreClient.createDoc @project_id, @lines, (error, @doc_id) => - done() + DocstoreClient.createProject @project_id, (error) => + throw error if error? + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + throw error if error? + done() afterEach (done) -> DocstoreClient.deleteProject @project_id, done diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee new file mode 100644 index 0000000000..568e8f9554 --- /dev/null +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -0,0 +1,45 @@ +sinon = require "sinon" +chai = require("chai") +chai.should() +{ObjectId} = require "mongojs" +async = require "async" + +DocstoreClient = require "./helpers/DocstoreClient" + +describe "Getting all docs", -> + beforeEach (done) -> + @project_id = ObjectId() + @docs = [{ + _id: ObjectId() + lines: ["one"] + version: 1 + rev: 2 + }, { + _id: ObjectId() + lines: ["two"] + version: 3 + rev: 4 + }, { + _id: ObjectId() + lines: ["three"] + version: 5 + rev: 6 + }] + DocstoreClient.createProject @project_id, (error) => + throw error if error? + jobs = for doc in @docs + do (doc) => + (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, callback + async.series jobs, done + + afterEach (done) -> + DocstoreClient.deleteProject @project_id, done + + it "should return all the docs", (done) -> + DocstoreClient.getAllDocs @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.lines.should.deep.equal @docs[i].lines + done() + diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index 398f8b3690..248286b8e4 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -5,12 +5,16 @@ chai.should() DocstoreClient = require "./helpers/DocstoreClient" -describe "Applying updates to a doc", -> +describe "Getting a doc", -> beforeEach (done) -> @project_id = ObjectId() + @doc_id = ObjectId() @lines = ["original", "lines"] - DocstoreClient.createDoc @project_id, @lines, (error, @doc_id) => - done() + DocstoreClient.createProject @project_id, (error) => + throw error if error? + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + throw error if error? + done() afterEach (done) -> DocstoreClient.deleteProject @project_id, done diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 107967ebd3..740aadb446 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -8,10 +8,14 @@ DocstoreClient = require "./helpers/DocstoreClient" describe "Applying updates to a doc", -> beforeEach (done) -> @project_id = ObjectId() + @doc_id = ObjectId() @originalLines = ["original", "lines"] @newLines = ["new", "lines"] - DocstoreClient.createDoc @project_id, @originalLines, (error, @doc_id) => - done() + DocstoreClient.createProject @project_id, (error) => + throw error if error? + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + throw error if error? + done() afterEach (done) -> DocstoreClient.deleteProject @project_id, done diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 6aec513246..7640501537 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -2,29 +2,39 @@ request = require("request").defaults(jar: false) {db, ObjectId} = require("../../../../app/js/mongojs") module.exports = DocstoreClient = - createDoc: (project_id, lines, callback = (error, doc_id) ->) -> - doc_id = ObjectId() + createProject: (project_id, callback = (error) ->) -> db.projects.insert { _id: project_id - rootFolder: [{ - docs: [{ - _id: doc_id, + rootFolder: [{ docs: [] }] + }, callback + + createDoc: (project_id, doc_id, lines, callback = (error) ->) -> + db.projects.update { + _id: project_id + }, { + $push: { + "rootFolder.0.docs": { + _id: doc_id lines: lines - }] - }] - }, (error) -> - return callback(error) if error? - callback null, doc_id + } + } + }, callback deleteProject: (project_id, callback = (error, res, body) ->) -> db.projects.remove _id: project_id, callback - getDoc: (project_id, doc_id, callback = (error, doc) ->) -> + getDoc: (project_id, doc_id, callback = (error, res, body) ->) -> request.get { url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" json: true }, callback + getAllDocs: (project_id, callback = (error, res, body) ->) -> + request.get { + url: "http://localhost:3016/project/#{project_id}/doc" + json: true + }, callback + updateDoc: (project_id, doc_id, lines, callback = (error, res, body) ->) -> request.post { url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 0ab746e2d2..0b2b70c38f 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -41,7 +41,7 @@ describe "DocManager", -> describe "when the project does not exist", -> beforeEach -> - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @null) + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, null) @DocManager.findDocInProject = sinon.stub() @DocManager.getDoc @project_id, @doc_id, @callback @@ -70,6 +70,43 @@ describe "DocManager", -> .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) .should.equal true + describe "getAllDocs", -> + describe "when the project exists", -> + beforeEach -> + @project = { name: "mock-project" } + @docs = [{ _id: @doc_id, lines: ["mock-lines"] }] + @mongoPath = "mock.mongo.path" + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) + @DocManager.findAllDocsInProject = sinon.stub().callsArgWith(1, null, @docs) + @DocManager.getAllDocs @project_id, @callback + + it "should get the project from the database", -> + @MongoManager.findProject + .calledWith(@project_id) + .should.equal true + + it "should find all the docs in the project", -> + @DocManager.findAllDocsInProject + .calledWith(@project) + .should.equal true + + it "should return the docs", -> + @callback.calledWith(null, @docs).should.equal true + + describe "when the project does not exist", -> + beforeEach -> + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, null) + @DocManager.findAllDocsInProject = sinon.stub() + @DocManager.getDoc @project_id, @doc_id, @callback + + it "should not try to find the doc in the project", -> + @DocManager.findAllDocsInProject.called.should.equal false + + it "should return a NotFoundError", -> + @callback + .calledWith(new Errors.NotFoundError("No such project: #{@project_id}")) + .should.equal true + describe "deleteDoc", -> describe "when the doc exists", -> beforeEach -> @@ -232,3 +269,25 @@ describe "DocManager", -> expect(doc).to.be.null expect(mongoPath).to.be.null done() + + describe "findAllDocsInProject", -> + it "should return all the docs", (done) -> + @DocManager.findAllDocsInProject { + rootFolder: [{ + docs: [ + @doc1 = { _id: ObjectId() } + ], + folders: [{ + docs: [ + @doc2 = { _id: ObjectId() } + ] + }, { + docs: [ + @doc3 = { _id: ObjectId() } + @doc4 = { _id: ObjectId() } + ] + }] + }] + }, (error, docs) => + expect(docs).to.deep.equal [@doc1, @doc2, @doc3, @doc4] + done() diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 576fd66122..ba8a6e7535 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -4,6 +4,7 @@ chai = require('chai') chai.should() expect = chai.expect modulePath = require('path').join __dirname, '../../../app/js/HttpController' +ObjectId = require("mongojs").ObjectId describe "HttpController", -> beforeEach -> @@ -18,6 +19,8 @@ describe "HttpController", -> @doc = { _id: @doc_id lines: ["mock", "lines"] + version: 42 + rev: 5 } describe "getDoc", -> @@ -35,7 +38,50 @@ describe "HttpController", -> it "should return the doc as JSON", -> @res.json - .calledWith(lines: @doc.lines) + .calledWith({ + _id: @doc_id + lines: @doc.lines + rev: @doc.rev + version: @doc.version + }) + .should.equal true + + describe "getAllDocs", -> + beforeEach -> + @req.params = + project_id: @project_id + @docs = [{ + _id: ObjectId() + lines: ["mock", "lines", "one"] + version: 1 + rev: 2 + }, { + _id: ObjectId() + lines: ["mock", "lines", "two"] + version: 3 + rev: 4 + }] + @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) + @HttpController.getAllDocs @req, @res, @next + + it "should get all the docs", -> + @DocManager.getAllDocs + .calledWith(@project_id) + .should.equal true + + it "should return the doc as JSON", -> + @res.json + .calledWith([{ + _id: @docs[0]._id.toString() + lines: @docs[0].lines + rev: @docs[0].rev + version: @docs[0].version + }, { + _id: @docs[1]._id.toString() + lines: @docs[1].lines + rev: @docs[1].rev + version: @docs[1].version + }]) .should.equal true describe "updateDoc", -> From aed4a7ce18e4281b6dba75202e3f404c65cb16e8 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 6 May 2014 16:52:58 +0100 Subject: [PATCH 012/349] Add in metrics --- services/docstore/app.coffee | 4 ++++ services/docstore/package.json | 1 + 2 files changed, 5 insertions(+) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index f8024ec188..d9185c4fdc 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -4,8 +4,12 @@ express = require "express" bodyParser = require "body-parser" Errors = require "./app/js/Errors" HttpController = require "./app/js/HttpController" +Metrics = require "metrics-sharelatex" +Path = require "path" +Metrics.initialize("docstore") logger.initialize("docstore") +Metrics.mongodb.monitor(Path.resolve(__dirname + "/node_modules/mongojs/node_modules/mongodb"), logger) app = express() diff --git a/services/docstore/package.json b/services/docstore/package.json index 029f13cebc..c77840e80e 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -6,6 +6,7 @@ "dependencies": { "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#master", "mongojs": "0.9.11", "express": "~4.1.1", "underscore": "~1.6.0", From ccbe33a82e99c7dbb73ae41b3f2f088146619071 Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 7 May 2014 10:59:16 +0100 Subject: [PATCH 013/349] Add in http monitoring --- services/docstore/app.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index d9185c4fdc..58625ea45f 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -13,6 +13,8 @@ Metrics.mongodb.monitor(Path.resolve(__dirname + "/node_modules/mongojs/node_mod app = express() +app.use Metrics.http.monitor(logger) + app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(), HttpController.updateDoc From 43ed71e82c0b03f60dbe5e264a9f378190e2e46c Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 7 May 2014 16:24:47 +0100 Subject: [PATCH 014/349] Do a check for null docs --- services/docstore/app/coffee/HttpController.coffee | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 781376b5a5..5a4115699e 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -18,7 +18,11 @@ module.exports = HttpController = logger.log project_id: project_id, "getting all docs" DocManager.getAllDocs project_id, (error, docs = []) -> return next(error) if error? - res.json docs.map(HttpController._buildDocView) + docViews = [] + for doc in docs + if doc? # There can end up being null docs for some reason :( (probably a race condition) + docViews.push HttpController._buildDocView(doc) + res.json docViews updateDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id From 0adcf3c140493d60b574dbddbd877ce5b85d3a1d Mon Sep 17 00:00:00 2001 From: James Allen Date: Wed, 7 May 2014 16:38:10 +0100 Subject: [PATCH 015/349] Log out errors when null docs are encountered --- .../docstore/app/coffee/HttpController.coffee | 2 + .../unit/coffee/HttpControllerTests.coffee | 115 ++++++++++++------ 2 files changed, 82 insertions(+), 35 deletions(-) diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 5a4115699e..4a99b3a0cc 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -22,6 +22,8 @@ module.exports = HttpController = for doc in docs if doc? # There can end up being null docs for some reason :( (probably a race condition) docViews.push HttpController._buildDocView(doc) + else + logger.error err: new Error("null doc"), project_id: project_id, "encountered null doc" res.json docViews updateDoc: (req, res, next = (error) ->) -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index ba8a6e7535..6d40a20612 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -47,42 +47,87 @@ describe "HttpController", -> .should.equal true describe "getAllDocs", -> - beforeEach -> - @req.params = - project_id: @project_id - @docs = [{ - _id: ObjectId() - lines: ["mock", "lines", "one"] - version: 1 - rev: 2 - }, { - _id: ObjectId() - lines: ["mock", "lines", "two"] - version: 3 - rev: 4 - }] - @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) - @HttpController.getAllDocs @req, @res, @next - - it "should get all the docs", -> - @DocManager.getAllDocs - .calledWith(@project_id) - .should.equal true - - it "should return the doc as JSON", -> - @res.json - .calledWith([{ - _id: @docs[0]._id.toString() - lines: @docs[0].lines - rev: @docs[0].rev - version: @docs[0].version + describe "normally", -> + beforeEach -> + @req.params = + project_id: @project_id + @docs = [{ + _id: ObjectId() + lines: ["mock", "lines", "one"] + version: 1 + rev: 2 }, { - _id: @docs[1]._id.toString() - lines: @docs[1].lines - rev: @docs[1].rev - version: @docs[1].version - }]) - .should.equal true + _id: ObjectId() + lines: ["mock", "lines", "two"] + version: 3 + rev: 4 + }] + @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) + @HttpController.getAllDocs @req, @res, @next + + it "should get all the docs", -> + @DocManager.getAllDocs + .calledWith(@project_id) + .should.equal true + + it "should return the doc as JSON", -> + @res.json + .calledWith([{ + _id: @docs[0]._id.toString() + lines: @docs[0].lines + rev: @docs[0].rev + version: @docs[0].version + }, { + _id: @docs[1]._id.toString() + lines: @docs[1].lines + rev: @docs[1].rev + version: @docs[1].version + }]) + .should.equal true + + describe "with a null doc", -> + beforeEach -> + @req.params = + project_id: @project_id + @docs = [{ + _id: ObjectId() + lines: ["mock", "lines", "one"] + version: 1 + rev: 2 + }, + null, + { + _id: ObjectId() + lines: ["mock", "lines", "two"] + version: 3 + rev: 4 + }] + @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) + @HttpController.getAllDocs @req, @res, @next + + it "should return the non null docs as JSON", -> + @res.json + .calledWith([{ + _id: @docs[0]._id.toString() + lines: @docs[0].lines + rev: @docs[0].rev + version: @docs[0].version + }, { + _id: @docs[2]._id.toString() + lines: @docs[2].lines + rev: @docs[2].rev + version: @docs[2].version + }]) + .should.equal true + + it "should log out an error", -> + @logger.error + .calledWith( + err: new Error("null doc") + project_id: @project_id + "encountered null doc" + ) + .should.equal true describe "updateDoc", -> beforeEach -> From 0dda75c2d55a5e2925fab398daeece6942bfc852 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 8 May 2014 15:43:08 +0100 Subject: [PATCH 016/349] Pass through version and revision information --- .../docstore/app/coffee/DocManager.coffee | 22 +++++--- .../docstore/app/coffee/HttpController.coffee | 6 +- .../docstore/app/coffee/MongoManager.coffee | 3 +- .../coffee/DeletingDocsTests.coffee | 3 +- .../coffee/GettingAllDocsTests.coffee | 2 +- .../acceptance/coffee/GettingDocsTests.coffee | 6 +- .../coffee/UpdatingDocsTests.coffee | 18 +++--- .../coffee/helpers/DocstoreClient.coffee | 6 +- .../test/unit/coffee/DocManagerTests.coffee | 55 +++++++++++++++---- .../unit/coffee/HttpControllerTests.coffee | 11 ++-- .../test/unit/coffee/MongoManagerTests.coffee | 4 +- 11 files changed, 96 insertions(+), 40 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 1f8bf64514..7802482961 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -21,23 +21,29 @@ module.exports = DocManager = return callback(error) if error? return callback null, docs - updateDoc: (project_id, doc_id, lines, callback = (error, modified) ->) -> + updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) -> DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? - if _.isEqual(doc.lines, lines) + if _.isEqual(doc.lines, lines) and doc.version == version logger.log { - project_id: project_id, doc_id: doc_id, rev: doc.rev - }, "doc lines have not changed" - return callback null, false + project_id: project_id, doc_id: doc_id, rev: doc.rev, version: doc.version + }, "doc lines and version have not changed" + return callback null, false, doc.rev else logger.log { - project_id: project_id, doc_id: doc_id, oldDocLines: doc.lines, newDocLines: lines, rev: doc.rev + project_id: project_id + doc_id: doc_id, + oldDocLines: doc.lines + newDocLines: lines + rev: doc.rev + oldVersion: doc.version + newVersion: version }, "updating doc lines" - MongoManager.updateDoc project_id, mongoPath, lines, (error) -> + MongoManager.updateDoc project_id, mongoPath, lines, version, (error) -> return callback(error) if error? - callback null, true + callback null, true, doc.rev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc deleteDoc: (project_id, doc_id, callback = (error) ->) -> DocManager.getDoc project_id, doc_id, (error, doc) -> diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 4a99b3a0cc..1e281d451e 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -30,17 +30,19 @@ module.exports = HttpController = project_id = req.params.project_id doc_id = req.params.doc_id lines = req.body?.lines + version = req.body?.version if !lines? or lines not instanceof Array logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided" res.send 400 # Bad Request return - logger.log project_id: project_id, doc_id: doc_id, "updating doc" - DocManager.updateDoc project_id, doc_id, lines, (error, modified) -> + logger.log project_id: project_id, doc_id: doc_id, version: version, "updating doc" + DocManager.updateDoc project_id, doc_id, lines, version, (error, modified, rev) -> return next(error) if error? res.json { modified: modified + rev: rev } deleteDoc: (req, res, next = (error) ->) -> diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 23e98e69c3..6cd05902c2 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -5,11 +5,12 @@ module.exports = MongoManager = db.projects.find _id: ObjectId(project_id.toString()), {}, (error, projects = []) -> callback error, projects[0] - updateDoc: (project_id, docPath, lines, callback = (error) ->) -> + updateDoc: (project_id, docPath, lines, version, callback = (error) ->) -> update = $set: {} $inc: {} update.$set["#{docPath}.lines"] = lines + update.$set["#{docPath}.version"] = version if version? update.$inc["#{docPath}.rev"] = 1 db.projects.update _id: ObjectId(project_id), update, callback diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee index a1dbe937da..05a9a1bb2a 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -10,9 +10,10 @@ describe "Deleting a doc", -> @project_id = ObjectId() @doc_id = ObjectId() @lines = ["original", "lines"] + @version = 42 DocstoreClient.createProject @project_id, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, (error) => throw error if error? done() diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index 568e8f9554..c3ec641312 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -29,7 +29,7 @@ describe "Getting all docs", -> throw error if error? jobs = for doc in @docs do (doc) => - (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, callback + (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, doc.version, callback async.series jobs, done afterEach (done) -> diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index 248286b8e4..b93b07255e 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -10,9 +10,10 @@ describe "Getting a doc", -> @project_id = ObjectId() @doc_id = ObjectId() @lines = ["original", "lines"] + @version = 42 DocstoreClient.createProject @project_id, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, (error) => throw error if error? done() @@ -20,9 +21,10 @@ describe "Getting a doc", -> DocstoreClient.deleteProject @project_id, done describe "when the doc exists", -> - it "should get the doc lines", (done) -> + it "should get the doc lines and version", (done) -> DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => doc.lines.should.deep.equal @lines + doc.version.should.equal @version done() describe "when the doc does not exist", -> diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 740aadb446..924acb3373 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -11,9 +11,11 @@ describe "Applying updates to a doc", -> @doc_id = ObjectId() @originalLines = ["original", "lines"] @newLines = ["new", "lines"] + @originalVersion = 42 + @newVersion = 53 DocstoreClient.createProject @project_id, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, (error) => throw error if error? done() @@ -22,7 +24,7 @@ describe "Applying updates to a doc", -> describe "when the content has changed", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @newLines, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @newVersion, (error, res, @body) => done() it "should return modified = true", -> @@ -31,11 +33,12 @@ describe "Applying updates to a doc", -> it "should update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => doc.lines.should.deep.equal @newLines + doc.version.should.deep.equal @newVersion done() describe "when the content has not been updated", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @originalVersion, (error, res, @body) => done() it "should return modified = false", -> @@ -44,12 +47,13 @@ describe "Applying updates to a doc", -> it "should not update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => doc.lines.should.deep.equal @originalLines + doc.version.should.deep.equal @originalVersion done() describe "when the doc does not exist", -> beforeEach (done) -> missing_doc_id = ObjectId() - DocstoreClient.updateDoc @project_id, missing_doc_id, @originalLines, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, missing_doc_id, @originalLines, @newVersion, (error, @res, @body) => done() it "should return a 404", -> @@ -58,7 +62,7 @@ describe "Applying updates to a doc", -> describe "when the project does not exist", -> beforeEach (done) -> missing_project_id = ObjectId() - DocstoreClient.updateDoc missing_project_id, @doc_id, @originalLines, (error, @res, @body) => + DocstoreClient.updateDoc missing_project_id, @doc_id, @originalLines, @newVersion, (error, @res, @body) => done() it "should return a 404", -> @@ -67,7 +71,7 @@ describe "Applying updates to a doc", -> describe "when malformed doc lines are provided", -> describe "when the lines are not an array", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @newVersion, (error, @res, @body) => done() it "should return 400", -> @@ -80,7 +84,7 @@ describe "Applying updates to a doc", -> describe "when the lines are not present", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, null, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, null, @newVersion, (error, @res, @body) => done() it "should return 400", -> diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 7640501537..812fd5c822 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -8,7 +8,7 @@ module.exports = DocstoreClient = rootFolder: [{ docs: [] }] }, callback - createDoc: (project_id, doc_id, lines, callback = (error) ->) -> + createDoc: (project_id, doc_id, lines, version, callback = (error) ->) -> db.projects.update { _id: project_id }, { @@ -16,6 +16,7 @@ module.exports = DocstoreClient = "rootFolder.0.docs": { _id: doc_id lines: lines + version: version } } }, callback @@ -35,11 +36,12 @@ module.exports = DocstoreClient = json: true }, callback - updateDoc: (project_id, doc_id, lines, callback = (error, res, body) ->) -> + updateDoc: (project_id, doc_id, lines, version, callback = (error, res, body) ->) -> request.post { url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" json: lines: lines + version: version }, callback deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 0b2b70c38f..18f0758d18 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -149,15 +149,15 @@ describe "DocManager", -> beforeEach -> @oldDocLines = ["old", "doc", "lines"] @newDocLines = ["new", "doc", "lines"] - @doc = { _id: @doc_id, lines: @oldDocLines, rev: 42 } + @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5, version: @version = 42 } @mongoPath = "mock.mongo.path" - @MongoManager.updateDoc = sinon.stub().callsArg(3) + @MongoManager.updateDoc = sinon.stub().callsArg(4) describe "when the doc lines have changed", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should get the existing doc", -> @DocManager.getDoc @@ -166,7 +166,7 @@ describe "DocManager", -> it "should update the doc with the new doc lines", -> @MongoManager.updateDoc - .calledWith(@project_id, @mongoPath, @newDocLines) + .calledWith(@project_id, @mongoPath, @newDocLines, @version) .should.equal true it "should log out the old and new doc lines", -> @@ -177,28 +177,63 @@ describe "DocManager", -> oldDocLines: @oldDocLines newDocLines: @newDocLines rev: @doc.rev + oldVersion: @version + newVersion: @version "updating doc lines" ) .should.equal true - it "should return the callback", -> - @callback.calledWith(null, true).should.equal true + it "should return the callback with the new rev", -> + @callback.calledWith(null, true, @rev + 1).should.equal true + + describe "when the version has changed", -> + beforeEach -> + @newVersion = 1003 + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @newVersion, @callback + + it "should get the existing doc", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should update the doc with the new version", -> + @MongoManager.updateDoc + .calledWith(@project_id, @mongoPath, @oldDocLines, @newVersion) + .should.equal true + + it "should log out the old and new doc lines", -> + @logger.log + .calledWith( + project_id: @project_id + doc_id: @doc_id + oldDocLines: @oldDocLines + newDocLines: @oldDocLines + rev: @doc.rev + oldVersion: @version + newVersion: @newVersion + "updating doc lines" + ) + .should.equal true + + it "should return the callback with the new rev", -> + @callback.calledWith(null, true, @rev + 1).should.equal true describe "when the doc lines have not changed", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @callback it "should not update the doc", -> @MongoManager.updateDoc.called.should.equal false - it "should return the callback", -> - @callback.calledWith(null, false).should.equal true + it "should return the callback with the existing rev", -> + @callback.calledWith(null, false, @rev).should.equal true describe "when the doc does not exist", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should not try to update the doc", -> @MongoManager.updateDoc.called.should.equal false diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 6d40a20612..b1d700608b 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -139,29 +139,30 @@ describe "HttpController", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] - @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, true) + version: @version = 42 + @DocManager.updateDoc = sinon.stub().callsArgWith(4, null, true, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should update the document", -> @DocManager.updateDoc - .calledWith(@project_id, @doc_id, @lines) + .calledWith(@project_id, @doc_id, @lines, @version) .should.equal true it "should return a modified status", -> @res.json - .calledWith(modified: true) + .calledWith(modified: true, rev: @rev) .should.equal true describe "when the doc lines exist and were not updated", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] - @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, false) + @DocManager.updateDoc = sinon.stub().callsArgWith(4, null, false, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should return a modified status", -> @res.json - .calledWith(modified: false) + .calledWith(modified: false, rev: @rev) .should.equal true describe "when the doc lines are not provided", -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index d8c7411eec..e2ca10d531 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -31,10 +31,11 @@ describe "MongoManager", -> describe "updateDoc", -> beforeEach -> + @version = 42 @lines = ["mock-lines"] @docPath = "rootFolder.0.folders.1.docs.0" @db.projects.update = sinon.stub().callsArg(2) - @MongoManager.updateDoc @project_id, @docPath, @lines, @callback + @MongoManager.updateDoc @project_id, @docPath, @lines, @version, @callback it "should update the doc lines and increment the TPDS rev", -> @db.projects.update @@ -43,6 +44,7 @@ describe "MongoManager", -> }, { $set: "rootFolder.0.folders.1.docs.0.lines": @lines + "rootFolder.0.folders.1.docs.0.version": @version $inc: "rootFolder.0.folders.1.docs.0.rev": 1 }) From 79457227e19995bdaaf8a0885c931b4e4874a2ac Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 13 May 2014 12:54:58 +0100 Subject: [PATCH 017/349] Support up to 2mb requests --- services/docstore/app.coffee | 2 +- .../acceptance/coffee/UpdatingDocsTests.coffee | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 58625ea45f..ce4fdc1b93 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -17,7 +17,7 @@ app.use Metrics.http.monitor(logger) app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc -app.post '/project/:project_id/doc/:doc_id', bodyParser.json(), HttpController.updateDoc +app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.get '/status', (req, res)-> diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 924acb3373..cd0c6b0752 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -95,3 +95,19 @@ describe "Applying updates to a doc", -> doc.lines.should.deep.equal @originalLines done() + describe "when the content is large", -> + beforeEach (done) -> + line = new Array(1025).join("x") # 1kb + @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @newVersion, (error, res, @body) => + done() + + it "should return modified = true", -> + @body.modified.should.equal true + + it "should update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + doc.lines.should.deep.equal @largeLines + doc.version.should.deep.equal @newVersion + done() + From 7cca4f0368bdef12ede26aa410b67e23583c16d3 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 16 May 2014 13:06:35 +0100 Subject: [PATCH 018/349] Don't store and send version data --- .../docstore/app/coffee/DocManager.coffee | 12 ++--- .../docstore/app/coffee/HttpController.coffee | 6 +-- .../docstore/app/coffee/MongoManager.coffee | 3 +- .../coffee/DeletingDocsTests.coffee | 2 +- .../coffee/GettingAllDocsTests.coffee | 5 +- .../acceptance/coffee/GettingDocsTests.coffee | 4 +- .../coffee/UpdatingDocsTests.coffee | 21 ++++----- .../coffee/helpers/DocstoreClient.coffee | 6 +-- .../test/unit/coffee/DocManagerTests.coffee | 47 +++---------------- .../unit/coffee/HttpControllerTests.coffee | 16 ++----- .../test/unit/coffee/MongoManagerTests.coffee | 4 +- 11 files changed, 31 insertions(+), 95 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 7802482961..18c2d52f13 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -21,15 +21,15 @@ module.exports = DocManager = return callback(error) if error? return callback null, docs - updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) -> + updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? - if _.isEqual(doc.lines, lines) and doc.version == version + if _.isEqual(doc.lines, lines) logger.log { - project_id: project_id, doc_id: doc_id, rev: doc.rev, version: doc.version - }, "doc lines and version have not changed" + project_id: project_id, doc_id: doc_id, rev: doc.rev + }, "doc lines have not changed" return callback null, false, doc.rev else logger.log { @@ -38,10 +38,8 @@ module.exports = DocManager = oldDocLines: doc.lines newDocLines: lines rev: doc.rev - oldVersion: doc.version - newVersion: version }, "updating doc lines" - MongoManager.updateDoc project_id, mongoPath, lines, version, (error) -> + MongoManager.updateDoc project_id, mongoPath, lines, (error) -> return callback(error) if error? callback null, true, doc.rev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 1e281d451e..65453976f5 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -30,15 +30,14 @@ module.exports = HttpController = project_id = req.params.project_id doc_id = req.params.doc_id lines = req.body?.lines - version = req.body?.version if !lines? or lines not instanceof Array logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided" res.send 400 # Bad Request return - logger.log project_id: project_id, doc_id: doc_id, version: version, "updating doc" - DocManager.updateDoc project_id, doc_id, lines, version, (error, modified, rev) -> + logger.log project_id: project_id, doc_id: doc_id, "updating doc" + DocManager.updateDoc project_id, doc_id, lines, (error, modified, rev) -> return next(error) if error? res.json { modified: modified @@ -58,5 +57,4 @@ module.exports = HttpController = _id: doc._id.toString() lines: doc.lines rev: doc.rev - version: doc.version } \ No newline at end of file diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 6cd05902c2..23e98e69c3 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -5,12 +5,11 @@ module.exports = MongoManager = db.projects.find _id: ObjectId(project_id.toString()), {}, (error, projects = []) -> callback error, projects[0] - updateDoc: (project_id, docPath, lines, version, callback = (error) ->) -> + updateDoc: (project_id, docPath, lines, callback = (error) ->) -> update = $set: {} $inc: {} update.$set["#{docPath}.lines"] = lines - update.$set["#{docPath}.version"] = version if version? update.$inc["#{docPath}.rev"] = 1 db.projects.update _id: ObjectId(project_id), update, callback diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee index 05a9a1bb2a..fa7e15f61c 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -13,7 +13,7 @@ describe "Deleting a doc", -> @version = 42 DocstoreClient.createProject @project_id, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => throw error if error? done() diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index c3ec641312..f033f483c0 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -12,24 +12,21 @@ describe "Getting all docs", -> @docs = [{ _id: ObjectId() lines: ["one"] - version: 1 rev: 2 }, { _id: ObjectId() lines: ["two"] - version: 3 rev: 4 }, { _id: ObjectId() lines: ["three"] - version: 5 rev: 6 }] DocstoreClient.createProject @project_id, (error) => throw error if error? jobs = for doc in @docs do (doc) => - (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, doc.version, callback + (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, callback async.series jobs, done afterEach (done) -> diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index b93b07255e..9688628d32 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -10,10 +10,9 @@ describe "Getting a doc", -> @project_id = ObjectId() @doc_id = ObjectId() @lines = ["original", "lines"] - @version = 42 DocstoreClient.createProject @project_id, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => throw error if error? done() @@ -24,7 +23,6 @@ describe "Getting a doc", -> it "should get the doc lines and version", (done) -> DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => doc.lines.should.deep.equal @lines - doc.version.should.equal @version done() describe "when the doc does not exist", -> diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index cd0c6b0752..10d84c7cf1 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -11,11 +11,9 @@ describe "Applying updates to a doc", -> @doc_id = ObjectId() @originalLines = ["original", "lines"] @newLines = ["new", "lines"] - @originalVersion = 42 - @newVersion = 53 DocstoreClient.createProject @project_id, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => throw error if error? done() @@ -24,7 +22,7 @@ describe "Applying updates to a doc", -> describe "when the content has changed", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @newVersion, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @newLines, (error, res, @body) => done() it "should return modified = true", -> @@ -33,12 +31,11 @@ describe "Applying updates to a doc", -> it "should update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => doc.lines.should.deep.equal @newLines - doc.version.should.deep.equal @newVersion done() describe "when the content has not been updated", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @originalVersion, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, (error, res, @body) => done() it "should return modified = false", -> @@ -47,13 +44,12 @@ describe "Applying updates to a doc", -> it "should not update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => doc.lines.should.deep.equal @originalLines - doc.version.should.deep.equal @originalVersion done() describe "when the doc does not exist", -> beforeEach (done) -> missing_doc_id = ObjectId() - DocstoreClient.updateDoc @project_id, missing_doc_id, @originalLines, @newVersion, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, missing_doc_id, @originalLines, (error, @res, @body) => done() it "should return a 404", -> @@ -62,7 +58,7 @@ describe "Applying updates to a doc", -> describe "when the project does not exist", -> beforeEach (done) -> missing_project_id = ObjectId() - DocstoreClient.updateDoc missing_project_id, @doc_id, @originalLines, @newVersion, (error, @res, @body) => + DocstoreClient.updateDoc missing_project_id, @doc_id, @originalLines, (error, @res, @body) => done() it "should return a 404", -> @@ -71,7 +67,7 @@ describe "Applying updates to a doc", -> describe "when malformed doc lines are provided", -> describe "when the lines are not an array", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @newVersion, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, (error, @res, @body) => done() it "should return 400", -> @@ -84,7 +80,7 @@ describe "Applying updates to a doc", -> describe "when the lines are not present", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, null, @newVersion, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, null, (error, @res, @body) => done() it "should return 400", -> @@ -99,7 +95,7 @@ describe "Applying updates to a doc", -> beforeEach (done) -> line = new Array(1025).join("x") # 1kb @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @newVersion, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, (error, res, @body) => done() it "should return modified = true", -> @@ -108,6 +104,5 @@ describe "Applying updates to a doc", -> it "should update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => doc.lines.should.deep.equal @largeLines - doc.version.should.deep.equal @newVersion done() diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 812fd5c822..7640501537 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -8,7 +8,7 @@ module.exports = DocstoreClient = rootFolder: [{ docs: [] }] }, callback - createDoc: (project_id, doc_id, lines, version, callback = (error) ->) -> + createDoc: (project_id, doc_id, lines, callback = (error) ->) -> db.projects.update { _id: project_id }, { @@ -16,7 +16,6 @@ module.exports = DocstoreClient = "rootFolder.0.docs": { _id: doc_id lines: lines - version: version } } }, callback @@ -36,12 +35,11 @@ module.exports = DocstoreClient = json: true }, callback - updateDoc: (project_id, doc_id, lines, version, callback = (error, res, body) ->) -> + updateDoc: (project_id, doc_id, lines, callback = (error, res, body) ->) -> request.post { url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" json: lines: lines - version: version }, callback deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 18f0758d18..e9d914f711 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -149,15 +149,15 @@ describe "DocManager", -> beforeEach -> @oldDocLines = ["old", "doc", "lines"] @newDocLines = ["new", "doc", "lines"] - @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5, version: @version = 42 } + @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5 } @mongoPath = "mock.mongo.path" - @MongoManager.updateDoc = sinon.stub().callsArg(4) + @MongoManager.updateDoc = sinon.stub().callsArg(3) describe "when the doc lines have changed", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should get the existing doc", -> @DocManager.getDoc @@ -166,7 +166,7 @@ describe "DocManager", -> it "should update the doc with the new doc lines", -> @MongoManager.updateDoc - .calledWith(@project_id, @mongoPath, @newDocLines, @version) + .calledWith(@project_id, @mongoPath, @newDocLines) .should.equal true it "should log out the old and new doc lines", -> @@ -177,41 +177,6 @@ describe "DocManager", -> oldDocLines: @oldDocLines newDocLines: @newDocLines rev: @doc.rev - oldVersion: @version - newVersion: @version - "updating doc lines" - ) - .should.equal true - - it "should return the callback with the new rev", -> - @callback.calledWith(null, true, @rev + 1).should.equal true - - describe "when the version has changed", -> - beforeEach -> - @newVersion = 1003 - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @newVersion, @callback - - it "should get the existing doc", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id) - .should.equal true - - it "should update the doc with the new version", -> - @MongoManager.updateDoc - .calledWith(@project_id, @mongoPath, @oldDocLines, @newVersion) - .should.equal true - - it "should log out the old and new doc lines", -> - @logger.log - .calledWith( - project_id: @project_id - doc_id: @doc_id - oldDocLines: @oldDocLines - newDocLines: @oldDocLines - rev: @doc.rev - oldVersion: @version - newVersion: @newVersion "updating doc lines" ) .should.equal true @@ -222,7 +187,7 @@ describe "DocManager", -> describe "when the doc lines have not changed", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @callback + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback it "should not update the doc", -> @MongoManager.updateDoc.called.should.equal false @@ -233,7 +198,7 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should not try to update the doc", -> @MongoManager.updateDoc.called.should.equal false diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index b1d700608b..2944e3a6a1 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -42,7 +42,6 @@ describe "HttpController", -> _id: @doc_id lines: @doc.lines rev: @doc.rev - version: @doc.version }) .should.equal true @@ -54,12 +53,10 @@ describe "HttpController", -> @docs = [{ _id: ObjectId() lines: ["mock", "lines", "one"] - version: 1 rev: 2 }, { _id: ObjectId() lines: ["mock", "lines", "two"] - version: 3 rev: 4 }] @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) @@ -76,12 +73,10 @@ describe "HttpController", -> _id: @docs[0]._id.toString() lines: @docs[0].lines rev: @docs[0].rev - version: @docs[0].version }, { _id: @docs[1]._id.toString() lines: @docs[1].lines rev: @docs[1].rev - version: @docs[1].version }]) .should.equal true @@ -92,14 +87,12 @@ describe "HttpController", -> @docs = [{ _id: ObjectId() lines: ["mock", "lines", "one"] - version: 1 rev: 2 }, null, { _id: ObjectId() lines: ["mock", "lines", "two"] - version: 3 rev: 4 }] @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) @@ -111,12 +104,10 @@ describe "HttpController", -> _id: @docs[0]._id.toString() lines: @docs[0].lines rev: @docs[0].rev - version: @docs[0].version }, { _id: @docs[2]._id.toString() lines: @docs[2].lines rev: @docs[2].rev - version: @docs[2].version }]) .should.equal true @@ -139,13 +130,12 @@ describe "HttpController", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] - version: @version = 42 - @DocManager.updateDoc = sinon.stub().callsArgWith(4, null, true, @rev = 5) + @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, true, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should update the document", -> @DocManager.updateDoc - .calledWith(@project_id, @doc_id, @lines, @version) + .calledWith(@project_id, @doc_id, @lines) .should.equal true it "should return a modified status", -> @@ -157,7 +147,7 @@ describe "HttpController", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] - @DocManager.updateDoc = sinon.stub().callsArgWith(4, null, false, @rev = 5) + @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, false, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should return a modified status", -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index e2ca10d531..d8c7411eec 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -31,11 +31,10 @@ describe "MongoManager", -> describe "updateDoc", -> beforeEach -> - @version = 42 @lines = ["mock-lines"] @docPath = "rootFolder.0.folders.1.docs.0" @db.projects.update = sinon.stub().callsArg(2) - @MongoManager.updateDoc @project_id, @docPath, @lines, @version, @callback + @MongoManager.updateDoc @project_id, @docPath, @lines, @callback it "should update the doc lines and increment the TPDS rev", -> @db.projects.update @@ -44,7 +43,6 @@ describe "MongoManager", -> }, { $set: "rootFolder.0.folders.1.docs.0.lines": @lines - "rootFolder.0.folders.1.docs.0.version": @version $inc: "rootFolder.0.folders.1.docs.0.rev": 1 }) From 973d9b8643204737a72d5dc77d3283684da76da8 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 20 May 2014 13:04:33 +0100 Subject: [PATCH 019/349] added raw endpoint to docstore --- services/docstore/app.coffee | 1 + .../docstore/app/coffee/HttpController.coffee | 17 ++++++++++++- .../unit/coffee/HttpControllerTests.coffee | 24 +++++++++++++++++-- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index ce4fdc1b93..c97a02799a 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -17,6 +17,7 @@ app.use Metrics.http.monitor(logger) app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc +app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 65453976f5..0dec71141e 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -13,6 +13,18 @@ module.exports = HttpController = else res.json HttpController._buildDocView(doc) + getRawDoc: (req, res, next = (error)->)-> + project_id = req.params.project_id + doc_id = req.params.doc_id + logger.log project_id: project_id, doc_id: doc_id, "getting raw doc" + DocManager.getDoc project_id, doc_id, (error, doc) -> + return next(error) if error? + if !doc? + res.send 404 + else + res.setHeader('content-type', 'text/plain') + res.send HttpController._buildRawDocView(doc) + getAllDocs: (req, res, next = (error) ->) -> project_id = req.params.project_id logger.log project_id: project_id, "getting all docs" @@ -57,4 +69,7 @@ module.exports = HttpController = _id: doc._id.toString() lines: doc.lines rev: doc.rev - } \ No newline at end of file + } + + _buildRawDocView: (doc)-> + return doc.lines.join("\n") diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 2944e3a6a1..7c7ff8c103 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -1,4 +1,5 @@ SandboxedModule = require('sandboxed-module') +assert = require("chai").assert sinon = require('sinon') chai = require('chai') chai.should() @@ -11,14 +12,14 @@ describe "HttpController", -> @HttpController = SandboxedModule.require modulePath, requires: "./DocManager": @DocManager = {} "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } - @res = { send: sinon.stub(), json: sinon.stub() } + @res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() } @req = {} @next = sinon.stub() @project_id = "mock-project-id" @doc_id = "mock-doc-id" @doc = { _id: @doc_id - lines: ["mock", "lines"] + lines: ["mock", "lines", " here", "", "", " spaces "] version: 42 rev: 5 } @@ -45,6 +46,25 @@ describe "HttpController", -> }) .should.equal true + describe "getRawDoc", -> + beforeEach -> + @req.params = + project_id: @project_id + doc_id: @doc_id + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @HttpController.getRawDoc @req, @res, @next + + it "should get the document", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should set the content type header", -> + @res.setHeader.calledWith('content-type', 'text/plain').should.equal true + + it "should send the raw version of the doc", -> + assert.deepEqual @res.send.args[0][0], "#{@doc.lines[0]}\n#{@doc.lines[1]}\n#{@doc.lines[2]}\n#{@doc.lines[3]}\n#{@doc.lines[4]}\n#{@doc.lines[5]}" + describe "getAllDocs", -> describe "normally", -> beforeEach -> From 9f969bba4dde9ed103a3f929795ea57eeabc0df9 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 29 May 2014 11:18:31 +0100 Subject: [PATCH 020/349] Handle null doc lines --- services/docstore/app/coffee/HttpController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 0dec71141e..2b8d49d93c 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -72,4 +72,4 @@ module.exports = HttpController = } _buildRawDocView: (doc)-> - return doc.lines.join("\n") + return (doc?.lines or []).join("\n") From e4e14602f1ad1af487bc1ab27bcd0036ac752fad Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 29 May 2014 12:04:18 +0100 Subject: [PATCH 021/349] null check on id --- services/docstore/app/coffee/HttpController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 2b8d49d93c..a14c9047a5 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -66,7 +66,7 @@ module.exports = HttpController = _buildDocView: (doc) -> return { - _id: doc._id.toString() + _id: doc._id?.toString() lines: doc.lines rev: doc.rev } From dc9fff94f311a90c3c4d46e8b5061fe06613a336 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 29 May 2014 14:21:46 +0100 Subject: [PATCH 022/349] Add null checks for null folders --- services/docstore/app/coffee/DocManager.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 18c2d52f13..74591cebfa 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -61,7 +61,7 @@ module.exports = DocManager = else callback null, null, null - _findDocInFolder: (folder, doc_id, currentPath) -> + _findDocInFolder: (folder = {}, doc_id, currentPath) -> for doc, i in folder.docs or [] if doc._id.toString() == doc_id.toString() return { @@ -75,7 +75,7 @@ module.exports = DocManager = return null - _findAllDocsInFolder: (folder) -> + _findAllDocsInFolder: (folder = {}) -> docs = folder.docs or [] for childFolder in folder.folders or [] docs = docs.concat @_findAllDocsInFolder childFolder From 32f1a327a645c860f1734a06bb73f63dd69db5b2 Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 3 Jun 2014 11:42:41 +0100 Subject: [PATCH 023/349] Add in null check --- services/docstore/app/coffee/DocManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 74591cebfa..3de6f906ae 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -63,7 +63,7 @@ module.exports = DocManager = _findDocInFolder: (folder = {}, doc_id, currentPath) -> for doc, i in folder.docs or [] - if doc._id.toString() == doc_id.toString() + if doc._id? and doc._id.toString() == doc_id.toString() return { doc: doc mongoPath: "#{currentPath}.docs.#{i}" From 828aefe2c87f6b79909c90d68a0ee0336c0552bd Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 5 Jun 2014 10:20:56 +0100 Subject: [PATCH 024/349] Add in extra null check --- services/docstore/app/coffee/DocManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 3de6f906ae..dfbad5f6a2 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -63,7 +63,7 @@ module.exports = DocManager = _findDocInFolder: (folder = {}, doc_id, currentPath) -> for doc, i in folder.docs or [] - if doc._id? and doc._id.toString() == doc_id.toString() + if doc?._id? and doc._id.toString() == doc_id.toString() return { doc: doc mongoPath: "#{currentPath}.docs.#{i}" From 7870b4fb55225800065104d1fb35277f681ab3d9 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 5 Jun 2014 13:29:50 +0100 Subject: [PATCH 025/349] Return deleted docs --- .../docstore/app/coffee/DocManager.coffee | 12 +++++-- .../docstore/app/coffee/HttpController.coffee | 2 ++ .../docstore/app/coffee/MongoManager.coffee | 4 +++ .../test/unit/coffee/DocManagerTests.coffee | 31 +++++++++++++++++-- .../unit/coffee/HttpControllerTests.coffee | 5 +++ .../test/unit/coffee/MongoManagerTests.coffee | 20 ++++++++++-- 6 files changed, 67 insertions(+), 7 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index dfbad5f6a2..14ab13bf02 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -10,8 +10,14 @@ module.exports = DocManager = return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? DocManager.findDocInProject project, doc_id, (error, doc, mongoPath) -> return callback(error) if error? - return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? - return callback null, doc, mongoPath + if doc? + return callback null, doc, mongoPath + else + # Perhaps it's a deleted doc + MongoManager.findDoc doc_id, (error, doc) -> + return callback(error) if error? + return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? + return callback null, doc getAllDocs: (project_id, callback = (error, docs) ->) -> MongoManager.findProject project_id, (error, project) -> @@ -24,7 +30,7 @@ module.exports = DocManager = updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> return callback(error) if error? - return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? + return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? or !mongoPath? if _.isEqual(doc.lines, lines) logger.log { diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index a14c9047a5..7a4976a1f3 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -8,6 +8,7 @@ module.exports = HttpController = logger.log project_id: project_id, doc_id: doc_id, "getting doc" DocManager.getDoc project_id, doc_id, (error, doc) -> return next(error) if error? + logger.log doc: doc, "got doc" if !doc? res.send 404 else @@ -69,6 +70,7 @@ module.exports = HttpController = _id: doc._id?.toString() lines: doc.lines rev: doc.rev + deleted: !!doc.deleted } _buildRawDocView: (doc)-> diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 23e98e69c3..82db106d96 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -5,6 +5,10 @@ module.exports = MongoManager = db.projects.find _id: ObjectId(project_id.toString()), {}, (error, projects = []) -> callback error, projects[0] + findDoc: (doc_id, callback = (error, doc) ->) -> + db.docs.find _id: ObjectId(doc_id.toString()), {}, (error, docs = []) -> + callback error, docs[0] + updateDoc: (project_id, docPath, lines, callback = (error) ->) -> update = $set: {} diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index e9d914f711..339d082c8a 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -53,11 +53,11 @@ describe "DocManager", -> .calledWith(new Errors.NotFoundError("No such project: #{@project_id}")) .should.equal true - describe "when the doc does not exist", -> + describe "when the doc does not exist in the project tree", -> beforeEach -> - @project = { name: "mock-project" } @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null) + @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) @DocManager.getDoc @project_id, @doc_id, @callback it "should try to find the doc in the project", -> @@ -65,6 +65,33 @@ describe "DocManager", -> .calledWith(@project, @doc_id) .should.equal true + it "should try to find the doc in the docs collection", -> + @MongoManager.findDoc + .calledWith(@doc_id) + .should.equal true + + it "should return the doc", -> + @callback + .calledWith(null, @doc) + .should.equal true + + describe "when the doc does not exist anywhere", -> + beforeEach -> + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) + @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null) + @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null) + @DocManager.getDoc @project_id, @doc_id, @callback + + it "should try to find the doc in the project", -> + @DocManager.findDocInProject + .calledWith(@project, @doc_id) + .should.equal true + + it "should try to find the doc in the docs collection", -> + @MongoManager.findDoc + .calledWith(@doc_id) + .should.equal true + it "should return a NotFoundError", -> @callback .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 7c7ff8c103..4343d8120a 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -43,6 +43,7 @@ describe "HttpController", -> _id: @doc_id lines: @doc.lines rev: @doc.rev + deleted: false }) .should.equal true @@ -93,10 +94,12 @@ describe "HttpController", -> _id: @docs[0]._id.toString() lines: @docs[0].lines rev: @docs[0].rev + deleted: false }, { _id: @docs[1]._id.toString() lines: @docs[1].lines rev: @docs[1].rev + deleted: false }]) .should.equal true @@ -124,10 +127,12 @@ describe "HttpController", -> _id: @docs[0]._id.toString() lines: @docs[0].lines rev: @docs[0].rev + deleted: false }, { _id: @docs[2]._id.toString() lines: @docs[2].lines rev: @docs[2].rev + deleted: false }]) .should.equal true diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index d8c7411eec..c8e8478f58 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -11,6 +11,7 @@ describe "MongoManager", -> db: @db = { projects: {}, docs: {} } ObjectId: ObjectId @project_id = ObjectId().toString() + @doc_id = ObjectId().toString() @callback = sinon.stub() describe "findProject", -> @@ -19,7 +20,7 @@ describe "MongoManager", -> @db.projects.find = sinon.stub().callsArgWith(2, null, [@project]) @MongoManager.findProject @project_id, @callback - it "should find the project without the doc lines", -> + it "should find the project", -> @db.projects.find .calledWith({ _id: ObjectId(@project_id) @@ -29,6 +30,22 @@ describe "MongoManager", -> it "should call the callback with the project", -> @callback.calledWith(null, @project).should.equal true + describe "findDoc", -> + beforeEach -> + @doc = { name: "mock-doc" } + @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc]) + @MongoManager.findDoc @doc_id, @callback + + it "should find the doc", -> + @db.docs.find + .calledWith({ + _id: ObjectId(@doc_id) + }, {}) + .should.equal true + + it "should call the callback with the doc", -> + @callback.calledWith(null, @doc).should.equal true + describe "updateDoc", -> beforeEach -> @lines = ["mock-lines"] @@ -53,7 +70,6 @@ describe "MongoManager", -> describe "insertDoc", -> beforeEach -> - @doc_id = ObjectId().toString() @lines = ["mock-lines"] @db.docs.insert = sinon.stub().callsArg(1) @MongoManager.insertDoc @project_id, @doc_id, lines: @lines, @callback From 4818ae813188ade11ec610e05b9c8aa1b778e588 Mon Sep 17 00:00:00 2001 From: James Allen Date: Thu, 5 Jun 2014 14:10:44 +0100 Subject: [PATCH 026/349] Use flag to only get deleted doc when appropriate --- .../docstore/app/coffee/DocManager.coffee | 18 ++++--- .../docstore/app/coffee/HttpController.coffee | 2 +- .../test/unit/coffee/DocManagerTests.coffee | 50 +++++++++---------- .../unit/coffee/HttpControllerTests.coffee | 6 +-- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 14ab13bf02..d789554d1b 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -4,7 +4,11 @@ logger = require "logger-sharelatex" _ = require "underscore" module.exports = DocManager = - getDoc: (project_id, doc_id, callback = (error, doc, mongoPath) ->) -> + getDoc: (project_id, doc_id, options, callback = (error, doc, mongoPath) ->) -> + if typeof(options) == "function" + callback = options + options.include_deleted = false + MongoManager.findProject project_id, (error, project) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? @@ -13,11 +17,13 @@ module.exports = DocManager = if doc? return callback null, doc, mongoPath else - # Perhaps it's a deleted doc - MongoManager.findDoc doc_id, (error, doc) -> - return callback(error) if error? - return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? - return callback null, doc + if options.include_deleted + MongoManager.findDoc doc_id, (error, doc) -> + return callback(error) if error? + return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? + return callback null, doc + else + return callback new Errors.NotFoundError("No such doc: #{project_id}") getAllDocs: (project_id, callback = (error, docs) ->) -> MongoManager.findProject project_id, (error, project) -> diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 7a4976a1f3..f5b2d4896a 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -6,7 +6,7 @@ module.exports = HttpController = project_id = req.params.project_id doc_id = req.params.doc_id logger.log project_id: project_id, doc_id: doc_id, "getting doc" - DocManager.getDoc project_id, doc_id, (error, doc) -> + DocManager.getDoc project_id, doc_id, include_deleted: true, (error, doc) -> return next(error) if error? logger.log doc: doc, "got doc" if !doc? diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 339d082c8a..0a296c4617 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -17,7 +17,7 @@ describe "DocManager", -> @callback = sinon.stub() describe "getDoc", -> - describe "when the project exists", -> + describe "when the project exists and the doc is in it", -> beforeEach -> @project = { name: "mock-project" } @doc = { _id: @doc_id, lines: ["mock-lines"] } @@ -53,27 +53,37 @@ describe "DocManager", -> .calledWith(new Errors.NotFoundError("No such project: #{@project_id}")) .should.equal true - describe "when the doc does not exist in the project tree", -> + describe "when the doc is deleted", -> beforeEach -> @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) - @DocManager.getDoc @project_id, @doc_id, @callback - it "should try to find the doc in the project", -> - @DocManager.findDocInProject - .calledWith(@project, @doc_id) - .should.equal true + describe "when include_deleted = true", -> + beforeEach -> + @DocManager.getDoc @project_id, @doc_id, include_deleted: true, @callback - it "should try to find the doc in the docs collection", -> - @MongoManager.findDoc - .calledWith(@doc_id) - .should.equal true + it "should try to find the doc in the docs collection", -> + @MongoManager.findDoc + .calledWith(@doc_id) + .should.equal true - it "should return the doc", -> - @callback - .calledWith(null, @doc) - .should.equal true + it "should return the doc", -> + @callback + .calledWith(null, @doc) + .should.equal true + + describe "when include_deleted is not set", -> + beforeEach -> + @DocManager.getDoc @project_id, @doc_id, @callback + + it "should not try to find the doc in the docs collection", -> + @MongoManager.findDoc.called.should.equal false + + it "should return a NotFoundError", -> + @callback + .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) + .should.equal true describe "when the doc does not exist anywhere", -> beforeEach -> @@ -82,16 +92,6 @@ describe "DocManager", -> @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null) @DocManager.getDoc @project_id, @doc_id, @callback - it "should try to find the doc in the project", -> - @DocManager.findDocInProject - .calledWith(@project, @doc_id) - .should.equal true - - it "should try to find the doc in the docs collection", -> - @MongoManager.findDoc - .calledWith(@doc_id) - .should.equal true - it "should return a NotFoundError", -> @callback .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 4343d8120a..e34802c9de 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -29,12 +29,12 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @HttpController.getDoc @req, @res, @next - it "should get the document", -> + it "should get the document (including deleted)", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id) + .calledWith(@project_id, @doc_id, include_deleted: true) .should.equal true it "should return the doc as JSON", -> From 6d24c69e9608a404c6a97a91fc38ee071a5d5e70 Mon Sep 17 00:00:00 2001 From: James Allen Date: Fri, 6 Jun 2014 12:37:42 +0100 Subject: [PATCH 027/349] Don't return deleted docs by default, make it a flag --- .../docstore/app/coffee/HttpController.coffee | 3 +- .../acceptance/coffee/GettingDocsTests.coffee | 18 ++++++++ .../coffee/helpers/DocstoreClient.coffee | 18 ++++++-- .../unit/coffee/HttpControllerTests.coffee | 42 ++++++++++++------- 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index f5b2d4896a..c2be655aff 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -5,8 +5,9 @@ module.exports = HttpController = getDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id doc_id = req.params.doc_id + include_deleted = req.query?.include_deleted == "true" logger.log project_id: project_id, doc_id: doc_id, "getting doc" - DocManager.getDoc project_id, doc_id, include_deleted: true, (error, doc) -> + DocManager.getDoc project_id, doc_id, include_deleted: include_deleted, (error, doc) -> return next(error) if error? logger.log doc: doc, "got doc" if !doc? diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index 9688628d32..406f300f4f 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -32,3 +32,21 @@ describe "Getting a doc", -> res.statusCode.should.equal 404 done() + describe "when the doc is a deleted doc", -> + beforeEach (done) -> + @deleted_doc_id = ObjectId() + DocstoreClient.createDeletedDoc @project_id, @deleted_doc_id, @lines, done + + describe "with include_deleted=true", -> + it "should return the doc", (done) -> + DocstoreClient.getDoc @project_id, @deleted_doc_id, include_deleted: true, (error, res, doc) => + doc.lines.should.deep.equal @lines + doc.deleted.should.equal true + done() + + describe "without include_deleted=true", -> + it "should return 404", (done) -> + DocstoreClient.getDoc @project_id, @deleted_doc_id, (error, res, doc) => + res.statusCode.should.equal 404 + done() + diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 7640501537..1ca3cc2aff 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -20,12 +20,23 @@ module.exports = DocstoreClient = } }, callback + createDeletedDoc: (project_id, doc_id, lines, callback = (error) ->) -> + db.docs.insert { + _id: doc_id + project_id: project_id + lines: lines + deleted: true + }, callback + deleteProject: (project_id, callback = (error, res, body) ->) -> db.projects.remove _id: project_id, callback - getDoc: (project_id, doc_id, callback = (error, res, body) ->) -> + getDoc: (project_id, doc_id, options, callback = (error, res, body) ->) -> + if typeof(options) == "function" + callback = options + options = { include_deleted: false } request.get { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}?include_deleted=#{options.include_deleted}" json: true }, callback @@ -45,8 +56,7 @@ module.exports = DocstoreClient = deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> request.del { url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" - }, callback - + }, callback diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index e34802c9de..a41e6ced82 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -30,22 +30,36 @@ describe "HttpController", -> project_id: @project_id doc_id: @doc_id @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) - @HttpController.getDoc @req, @res, @next - it "should get the document (including deleted)", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id, include_deleted: true) - .should.equal true + describe "without deleted docs", -> + beforeEach -> + @HttpController.getDoc @req, @res, @next - it "should return the doc as JSON", -> - @res.json - .calledWith({ - _id: @doc_id - lines: @doc.lines - rev: @doc.rev - deleted: false - }) - .should.equal true + it "should get the document (including deleted)", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id, include_deleted: false) + .should.equal true + + it "should return the doc as JSON", -> + @res.json + .calledWith({ + _id: @doc_id + lines: @doc.lines + rev: @doc.rev + deleted: false + }) + .should.equal true + + describe "with deleted docs", -> + beforeEach -> + @req.query = + include_deleted: 'true' + @HttpController.getDoc @req, @res, @next + + it "should get the document (without deleted)", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id, include_deleted: true) + .should.equal true describe "getRawDoc", -> beforeEach -> From a66f7079207d8d944cd0fa70cca9d95dd5e8abca Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 19 Aug 2014 13:37:06 +0100 Subject: [PATCH 028/349] Release version 0.1.0 --- services/docstore/package.json | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index c77840e80e..8923088f41 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -1,12 +1,16 @@ { "name": "docstore-sharelatex", - "version": "0.0.0", + "version": "0.1.0", "description": "A CRUD API for handling text documents in projects", "author": "ShareLaTeX ", + "repository": { + "type": "git", + "url": "https://github.com/sharelatex/docstore-sharelatex.git" + }, "dependencies": { - "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#master", - "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#master", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#master", + "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", + "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.0.0", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.0.0", "mongojs": "0.9.11", "express": "~4.1.1", "underscore": "~1.6.0", From 28990d5a3971e3823eedf8b13495be2452e03949 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 20 Jan 2015 13:46:57 +0000 Subject: [PATCH 029/349] changed logging to easier to see when the http request starts --- services/docstore/app/coffee/HttpController.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index c2be655aff..39a14620f7 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -50,7 +50,7 @@ module.exports = HttpController = res.send 400 # Bad Request return - logger.log project_id: project_id, doc_id: doc_id, "updating doc" + logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc" DocManager.updateDoc project_id, doc_id, lines, (error, modified, rev) -> return next(error) if error? res.json { From b3d653f930a98d3ec0270cc2bdecea8f62b271de Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 20 Jan 2015 15:25:35 +0000 Subject: [PATCH 030/349] added grep for tests --- services/docstore/Gruntfile.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/services/docstore/Gruntfile.coffee b/services/docstore/Gruntfile.coffee index a9ac6e5180..05e00c5a42 100644 --- a/services/docstore/Gruntfile.coffee +++ b/services/docstore/Gruntfile.coffee @@ -54,6 +54,7 @@ module.exports = (grunt) -> unit: options: reporter: grunt.option('reporter') or 'spec' + grep: grunt.option("grep") src: ["test/unit/js/**/*.js"] acceptance: options: From 704bf53fe533c7e82cd80fd401b3b75d68e07393 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 20 Jan 2015 17:09:51 +0000 Subject: [PATCH 031/349] Write docs to do collection and project collection - docs are written to project collection then doc collection - deletes used to insert into doc collection, now its the same upsert with deleted = true - does not set delted = false for new docs as it is not needed, save space - changed delete to be seperate update on mongo --- .../docstore/app/coffee/DocManager.coffee | 16 ++++-- .../docstore/app/coffee/MongoManager.coffee | 19 +++++-- .../test/unit/coffee/DocManagerTests.coffee | 32 ++++++++---- .../test/unit/coffee/MongoManagerTests.coffee | 51 ++++++++++++++----- 4 files changed, 86 insertions(+), 32 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index d789554d1b..a104129525 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -2,6 +2,7 @@ MongoManager = require "./MongoManager" Errors = require "./Errors" logger = require "logger-sharelatex" _ = require "underscore" +async = require "async" module.exports = DocManager = getDoc: (project_id, doc_id, options, callback = (error, doc, mongoPath) ->) -> @@ -51,7 +52,13 @@ module.exports = DocManager = newDocLines: lines rev: doc.rev }, "updating doc lines" - MongoManager.updateDoc project_id, mongoPath, lines, (error) -> + async.series [ + (cb)-> + # project collection is still primary so that needs to be successful first + MongoManager.updateDoc project_id, mongoPath, lines, cb + (cb)-> + MongoManager.upsertIntoDocCollection project_id, doc_id, lines, doc.rev, cb + ], (error)-> return callback(error) if error? callback null, true, doc.rev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc @@ -59,9 +66,10 @@ module.exports = DocManager = DocManager.getDoc project_id, doc_id, (error, doc) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? - MongoManager.insertDoc project_id, doc_id, { lines: doc.lines, deleted: true }, (error) -> - return callback(error) if error? - callback() + MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, doc.rev, (error) -> + MongoManager.markDocAsDeleted doc_id, (error) -> + return callback(error) if error? + callback() findAllDocsInProject: (project, callback = (error, docs) ->) -> callback null, @_findAllDocsInFolder project.rootFolder[0] diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 82db106d96..05a61e4ccf 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -18,7 +18,18 @@ module.exports = MongoManager = db.projects.update _id: ObjectId(project_id), update, callback - insertDoc: (project_id, doc_id, attributes, callback = (error) ->) -> - attributes._id = ObjectId(doc_id) - attributes.project_id = ObjectId(project_id) - db.docs.insert attributes, callback \ No newline at end of file + upsertIntoDocCollection: (project_id, doc_id, lines, oldRev, callback)-> + update = + $set:{} + update.$set["lines"] = lines + update.$set["project_id"] = ObjectId(project_id) + update.$set["rev"] = oldRev + 1 + db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback + + + markDocAsDeleted: (doc_id, callback)-> + update = + $set: {} + update.$set["deleted"] = true + db.docs.update _id: ObjectId(doc_id), update, (err)-> + callback(err) diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 0a296c4617..14b342fb99 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -138,8 +138,10 @@ describe "DocManager", -> describe "when the doc exists", -> beforeEach -> @lines = ["mock", "doc", "lines"] - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, lines: @lines) - @MongoManager.insertDoc = sinon.stub().callsArg(3) + @rev = 77 + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, {lines: @lines, rev:@rev}) + @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) + @MongoManager.markDocAsDeleted = sinon.stub().callsArg(1) @DocManager.deleteDoc @project_id, @doc_id, @callback it "should get the doc", -> @@ -147,12 +149,14 @@ describe "DocManager", -> .calledWith(@project_id, @doc_id) .should.equal true - it "insert the doc as a deleted doc", -> - @MongoManager.insertDoc - .calledWith(@project_id, @doc_id, { - lines: @lines - deleted: true - }) + it "should update the doc lines", -> + @MongoManager.upsertIntoDocCollection + .calledWith(@project_id, @doc_id, @lines, @rev) + .should.equal true + + it "should mark doc as deleted", -> + @MongoManager.markDocAsDeleted + .calledWith(@doc_id) .should.equal true it "should return the callback", -> @@ -161,11 +165,11 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null) - @MongoManager.insertDoc = sinon.stub().callsArg(3) + @MongoManager.upsertIntoDocCollection = sinon.stub() @DocManager.deleteDoc @project_id, @doc_id, @callback it "should not try to insert a deleted doc", -> - @MongoManager.insertDoc.called.should.equal false + @MongoManager.upsertIntoDocCollection.called.should.equal false it "should return a NotFoundError", -> @callback @@ -180,6 +184,7 @@ describe "DocManager", -> @mongoPath = "mock.mongo.path" @MongoManager.updateDoc = sinon.stub().callsArg(3) + @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) describe "when the doc lines have changed", -> beforeEach -> @@ -196,6 +201,11 @@ describe "DocManager", -> .calledWith(@project_id, @mongoPath, @newDocLines) .should.equal true + it "should upsert the document to the doc collection", -> + @MongoManager.upsertIntoDocCollection + .calledWith(@project_id, @doc_id, @newDocLines, @rev) + .should.equal true + it "should log out the old and new doc lines", -> @logger.log .calledWith( @@ -218,6 +228,7 @@ describe "DocManager", -> it "should not update the doc", -> @MongoManager.updateDoc.called.should.equal false + @MongoManager.upsertIntoDocCollection.called.should.equal false it "should return the callback with the existing rev", -> @callback.calledWith(null, false, @rev).should.equal true @@ -229,6 +240,7 @@ describe "DocManager", -> it "should not try to update the doc", -> @MongoManager.updateDoc.called.should.equal false + @MongoManager.upsertIntoDocCollection.called.should.equal false it "should return a NotFoundError", -> @callback diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index c8e8478f58..aac8447a4c 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -3,6 +3,7 @@ sinon = require('sinon') require('chai').should() modulePath = require('path').join __dirname, '../../../app/js/MongoManager' ObjectId = require("mongojs").ObjectId +assert = require("chai").assert describe "MongoManager", -> beforeEach -> @@ -13,6 +14,7 @@ describe "MongoManager", -> @project_id = ObjectId().toString() @doc_id = ObjectId().toString() @callback = sinon.stub() + @stubbedErr = new Error("hello world") describe "findProject", -> beforeEach -> @@ -68,20 +70,41 @@ describe "MongoManager", -> it "should call the callback with the project", -> @callback.called.should.equal true - describe "insertDoc", -> + + describe "upsertIntoDocCollection", -> beforeEach -> - @lines = ["mock-lines"] - @db.docs.insert = sinon.stub().callsArg(1) - @MongoManager.insertDoc @project_id, @doc_id, lines: @lines, @callback + @db.docs.update = sinon.stub().callsArgWith(3, @stubbedErr) + @oldRev = 77 - it "should insert the attributes with the given doc and project id", -> - @db.docs.insert - .calledWith({ - _id: ObjectId(@doc_id) - project_id: ObjectId(@project_id) - lines: @lines - }) - .should.equal true + it "should upsert the document", (done)-> + @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, @oldRev, (err)=> + args = @db.docs.update.args[0] + assert.deepEqual args[0], {_id: ObjectId(@doc_id)} + assert.equal args[1]["$set"]["lines"], @lines + assert.equal args[1]["$set"]["rev"], 78 + assert.deepEqual args[1]["$set"]["project_id"], ObjectId(@project_id) + done() - it "should call the callback", -> - @callback.called.should.equal true \ No newline at end of file + it "should return the error", (done)-> + @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, @oldRev, (err)=> + err.should.equal @stubbedErr + done() + + describe "markDocAsDeleted", -> + beforeEach -> + @db.docs.update = sinon.stub().callsArgWith(2, @stubbedErr) + @oldRev = 77 + + it "should process the update", (done)-> + @MongoManager.markDocAsDeleted @doc_id, (err)=> + args = @db.docs.update.args[0] + assert.deepEqual args[0], {_id: ObjectId(@doc_id)} + assert.equal args[1]["$set"]["deleted"], true + done() + + it "should return the error", (done)-> + @MongoManager.markDocAsDeleted @doc_id, (err)=> + err.should.equal @stubbedErr + done() + + \ No newline at end of file From 535d4435bfcc3b3e3159d75e9f30d4986b7b2e1d Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 21 Jan 2015 12:31:06 +0000 Subject: [PATCH 032/349] added missing err check --- services/docstore/app/coffee/DocManager.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index a104129525..dedf3998f5 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -67,6 +67,7 @@ module.exports = DocManager = return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, doc.rev, (error) -> + return callback(error) if error? MongoManager.markDocAsDeleted doc_id, (error) -> return callback(error) if error? callback() From 5d2c09bf758b27b73cfe43d0036ee01a041b96cb Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 22 Jan 2015 15:05:48 +0000 Subject: [PATCH 033/349] read docs from doc collection first - removes include deleted flag as it is irrelivant now --- .../docstore/app/coffee/DocManager.coffee | 31 +++++------- .../docstore/app/coffee/HttpController.coffee | 3 +- .../acceptance/coffee/GettingDocsTests.coffee | 20 +++----- .../coffee/helpers/DocstoreClient.coffee | 7 +-- .../test/unit/coffee/DocManagerTests.coffee | 47 ++++++++++++------- .../unit/coffee/HttpControllerTests.coffee | 8 ++-- 6 files changed, 56 insertions(+), 60 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index dedf3998f5..f1c856eb9b 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -5,24 +5,19 @@ _ = require "underscore" async = require "async" module.exports = DocManager = - getDoc: (project_id, doc_id, options, callback = (error, doc, mongoPath) ->) -> - if typeof(options) == "function" - callback = options - options.include_deleted = false + getDoc: (project_id, doc_id, callback = (error, doc, mongoPath) ->) -> - MongoManager.findProject project_id, (error, project) -> - return callback(error) if error? - return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? - DocManager.findDocInProject project, doc_id, (error, doc, mongoPath) -> + MongoManager.findDoc doc_id, (err, docFromDocCollection)-> + return callback(err) if err? + MongoManager.findProject project_id, (error, project) -> return callback(error) if error? - if doc? - return callback null, doc, mongoPath - else - if options.include_deleted - MongoManager.findDoc doc_id, (error, doc) -> - return callback(error) if error? - return callback new Errors.NotFoundError("No such doc: #{project_id}") if !doc? - return callback null, doc + return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? + DocManager.findDocInProject project, doc_id, (error, doc, mongoPath) -> + return callback(error) if error? + if docFromDocCollection? + return callback null, docFromDocCollection, mongoPath + else if doc? + return callback null, doc, mongoPath else return callback new Errors.NotFoundError("No such doc: #{project_id}") @@ -37,7 +32,7 @@ module.exports = DocManager = updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> return callback(error) if error? - return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? or !mongoPath? + return callback new Errors.NotFoundError("No such project/doc to update: #{project_id}/#{doc_id}") if !doc? or !mongoPath? if _.isEqual(doc.lines, lines) logger.log { @@ -65,7 +60,7 @@ module.exports = DocManager = deleteDoc: (project_id, doc_id, callback = (error) ->) -> DocManager.getDoc project_id, doc_id, (error, doc) -> return callback(error) if error? - return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc? + return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, doc.rev, (error) -> return callback(error) if error? MongoManager.markDocAsDeleted doc_id, (error) -> diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 39a14620f7..2d54e69e3a 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -5,9 +5,8 @@ module.exports = HttpController = getDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id doc_id = req.params.doc_id - include_deleted = req.query?.include_deleted == "true" logger.log project_id: project_id, doc_id: doc_id, "getting doc" - DocManager.getDoc project_id, doc_id, include_deleted: include_deleted, (error, doc) -> + DocManager.getDoc project_id, doc_id, (error, doc) -> return next(error) if error? logger.log doc: doc, "got doc" if !doc? diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index 406f300f4f..fe92f44d72 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -34,19 +34,13 @@ describe "Getting a doc", -> describe "when the doc is a deleted doc", -> beforeEach (done) -> - @deleted_doc_id = ObjectId() + @deleted_doc_id = ObjectId() DocstoreClient.createDeletedDoc @project_id, @deleted_doc_id, @lines, done - describe "with include_deleted=true", -> - it "should return the doc", (done) -> - DocstoreClient.getDoc @project_id, @deleted_doc_id, include_deleted: true, (error, res, doc) => - doc.lines.should.deep.equal @lines - doc.deleted.should.equal true - done() - - describe "without include_deleted=true", -> - it "should return 404", (done) -> - DocstoreClient.getDoc @project_id, @deleted_doc_id, (error, res, doc) => - res.statusCode.should.equal 404 - done() + it "should return the doc", (done) -> + DocstoreClient.getDoc @project_id, @deleted_doc_id, (error, res, doc) => + doc.lines.should.deep.equal @lines + doc.deleted.should.equal true + done() + \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 1ca3cc2aff..9bf763bbf0 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -31,12 +31,9 @@ module.exports = DocstoreClient = deleteProject: (project_id, callback = (error, res, body) ->) -> db.projects.remove _id: project_id, callback - getDoc: (project_id, doc_id, options, callback = (error, res, body) ->) -> - if typeof(options) == "function" - callback = options - options = { include_deleted: false } + getDoc: (project_id, doc_id, callback = (error, res, body) ->) -> request.get { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}?include_deleted=#{options.include_deleted}" + url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" json: true }, callback diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 14b342fb99..3172e8ea5b 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -15,14 +15,38 @@ describe "DocManager", -> @doc_id = ObjectId().toString() @project_id = ObjectId().toString() @callback = sinon.stub() + @stubbedError = new Error("blew up") describe "getDoc", -> + beforeEach -> + @project = { name: "mock-project" } + @doc = { _id: @doc_id, lines: ["mock-lines"] } + @docCollectionDoc = { _id: @doc_id, lines: ["mock-lines"] } + + describe "when the doc is in the doc collection not projects collection", -> + + beforeEach -> + @MongoManager.findDoc = sinon.stub() + @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) + @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) + + it "should get the doc from the doc collection when it is present there", (done)-> + @MongoManager.findDoc.callsArgWith(1, null, @docCollectionDoc) + @DocManager.getDoc @project_id, @doc_id, (err, doc)=> + doc.should.equal @docCollectionDoc + done() + + it "should return the error from find doc", (done)-> + @MongoManager.findDoc.callsArgWith(1, @stubbedError) + @DocManager.getDoc @project_id, @doc_id, (err, doc)=> + err.should.equal @stubbedError + done() + describe "when the project exists and the doc is in it", -> beforeEach -> - @project = { name: "mock-project" } - @doc = { _id: @doc_id, lines: ["mock-lines"] } @mongoPath = "mock.mongo.path" @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) + @MongoManager.findDoc = sinon.stub().callsArg(1) @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) @DocManager.getDoc @project_id, @doc_id, @callback @@ -42,6 +66,7 @@ describe "DocManager", -> describe "when the project does not exist", -> beforeEach -> @MongoManager.findProject = sinon.stub().callsArgWith(1, null, null) + @MongoManager.findDoc = sinon.stub().callsArg(1) @DocManager.findDocInProject = sinon.stub() @DocManager.getDoc @project_id, @doc_id, @callback @@ -59,9 +84,7 @@ describe "DocManager", -> @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) - describe "when include_deleted = true", -> - beforeEach -> - @DocManager.getDoc @project_id, @doc_id, include_deleted: true, @callback + @DocManager.getDoc @project_id, @doc_id, @callback it "should try to find the doc in the docs collection", -> @MongoManager.findDoc @@ -73,17 +96,7 @@ describe "DocManager", -> .calledWith(null, @doc) .should.equal true - describe "when include_deleted is not set", -> - beforeEach -> - @DocManager.getDoc @project_id, @doc_id, @callback - - it "should not try to find the doc in the docs collection", -> - @MongoManager.findDoc.called.should.equal false - - it "should return a NotFoundError", -> - @callback - .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) - .should.equal true + describe "when the doc does not exist anywhere", -> beforeEach -> @@ -124,7 +137,7 @@ describe "DocManager", -> beforeEach -> @MongoManager.findProject = sinon.stub().callsArgWith(1, null, null) @DocManager.findAllDocsInProject = sinon.stub() - @DocManager.getDoc @project_id, @doc_id, @callback + @DocManager.getAllDocs @project_id, @callback it "should not try to find the doc in the project", -> @DocManager.findAllDocsInProject.called.should.equal false diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index a41e6ced82..7ec4d046ce 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -29,7 +29,7 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) describe "without deleted docs", -> beforeEach -> @@ -37,7 +37,7 @@ describe "HttpController", -> it "should get the document (including deleted)", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id, include_deleted: false) + .calledWith(@project_id, @doc_id) .should.equal true it "should return the doc as JSON", -> @@ -52,13 +52,11 @@ describe "HttpController", -> describe "with deleted docs", -> beforeEach -> - @req.query = - include_deleted: 'true' @HttpController.getDoc @req, @res, @next it "should get the document (without deleted)", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id, include_deleted: true) + .calledWith(@project_id, @doc_id) .should.equal true describe "getRawDoc", -> From 7b0b72494f7cea094dbd275a5d623ffdc1a5ef9e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 27 Jan 2015 15:05:35 +0000 Subject: [PATCH 034/349] write to doc collection first --- services/docstore/app/coffee/DocManager.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index f1c856eb9b..a491159d94 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -48,11 +48,10 @@ module.exports = DocManager = rev: doc.rev }, "updating doc lines" async.series [ - (cb)-> - # project collection is still primary so that needs to be successful first - MongoManager.updateDoc project_id, mongoPath, lines, cb (cb)-> MongoManager.upsertIntoDocCollection project_id, doc_id, lines, doc.rev, cb + (cb)-> + MongoManager.updateDoc project_id, mongoPath, lines, cb ], (error)-> return callback(error) if error? callback null, true, doc.rev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc From 7fe25fe28f0959b0983f9258123f03f927da84ea Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 27 Jan 2015 17:05:07 +0000 Subject: [PATCH 035/349] improved docstore acceptence tests to deal with changing docs on get all docs --- .../acceptance/coffee/GettingAllDocsTests.coffee | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index f033f483c0..53b26d453b 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -11,22 +11,25 @@ describe "Getting all docs", -> @project_id = ObjectId() @docs = [{ _id: ObjectId() - lines: ["one"] + lines: ["one", "two", "three"] rev: 2 }, { _id: ObjectId() - lines: ["two"] + lines: ["aaa", "bbb", "ccc"] rev: 4 }, { _id: ObjectId() - lines: ["three"] + lines: ["111", "222", "333"] rev: 6 }] DocstoreClient.createProject @project_id, (error) => throw error if error? jobs = for doc in @docs do (doc) => - (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, callback + (callback) => + DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + doc.lines[0] = doc.lines[0]+" added" + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback async.series jobs, done afterEach (done) -> @@ -40,3 +43,4 @@ describe "Getting all docs", -> doc.lines.should.deep.equal @docs[i].lines done() + From a0832c79e6519d1e551ea3256c0df0c05cf624c3 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 3 Feb 2015 14:05:08 +0000 Subject: [PATCH 036/349] return 404 if doc is deleted and include_deleted is not set to true --- .../docstore/app/coffee/DocManager.coffee | 1 - .../docstore/app/coffee/HttpController.coffee | 3 ++ .../acceptance/coffee/GettingDocsTests.coffee | 10 ++-- .../coffee/UpdatingDocsTests.coffee | 10 ++-- .../coffee/helpers/DocstoreClient.coffee | 3 +- .../unit/coffee/HttpControllerTests.coffee | 46 ++++++++++++++----- 6 files changed, 52 insertions(+), 21 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index a491159d94..9ebf324841 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -6,7 +6,6 @@ async = require "async" module.exports = DocManager = getDoc: (project_id, doc_id, callback = (error, doc, mongoPath) ->) -> - MongoManager.findDoc doc_id, (err, docFromDocCollection)-> return callback(err) if err? MongoManager.findProject project_id, (error, project) -> diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 2d54e69e3a..2a974794b2 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -5,12 +5,15 @@ module.exports = HttpController = getDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id doc_id = req.params.doc_id + include_deleted = req.query?.include_deleted == "true" logger.log project_id: project_id, doc_id: doc_id, "getting doc" DocManager.getDoc project_id, doc_id, (error, doc) -> return next(error) if error? logger.log doc: doc, "got doc" if !doc? res.send 404 + else if doc.deleted && !include_deleted + res.send 404 else res.json HttpController._buildDocView(doc) diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index fe92f44d72..35b51537fa 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -21,14 +21,14 @@ describe "Getting a doc", -> describe "when the doc exists", -> it "should get the doc lines and version", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @lines done() describe "when the doc does not exist", -> it "should return a 404", (done) -> missing_doc_id = ObjectId() - DocstoreClient.getDoc @project_id, missing_doc_id, (error, res, doc) -> + DocstoreClient.getDoc @project_id, missing_doc_id, {}, (error, res, doc) -> res.statusCode.should.equal 404 done() @@ -38,9 +38,13 @@ describe "Getting a doc", -> DocstoreClient.createDeletedDoc @project_id, @deleted_doc_id, @lines, done it "should return the doc", (done) -> - DocstoreClient.getDoc @project_id, @deleted_doc_id, (error, res, doc) => + DocstoreClient.getDoc @project_id, @deleted_doc_id, {include_deleted:true},(error, res, doc) => doc.lines.should.deep.equal @lines doc.deleted.should.equal true done() + it "should return a 404 when the query string is not set", (done)-> + DocstoreClient.getDoc @project_id, @deleted_doc_id, {},(error, res, doc) => + res.statusCode.should.equal 404 + done() \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 10d84c7cf1..7d168922af 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -29,7 +29,7 @@ describe "Applying updates to a doc", -> @body.modified.should.equal true it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @newLines done() @@ -42,7 +42,7 @@ describe "Applying updates to a doc", -> @body.modified.should.equal false it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @originalLines done() @@ -74,7 +74,7 @@ describe "Applying updates to a doc", -> @res.statusCode.should.equal 400 it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @originalLines done() @@ -87,7 +87,7 @@ describe "Applying updates to a doc", -> @res.statusCode.should.equal 400 it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @originalLines done() @@ -102,7 +102,7 @@ describe "Applying updates to a doc", -> @body.modified.should.equal true it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, (error, res, doc) => + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @largeLines done() diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 9bf763bbf0..d3a65790b8 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -31,10 +31,11 @@ module.exports = DocstoreClient = deleteProject: (project_id, callback = (error, res, body) ->) -> db.projects.remove _id: project_id, callback - getDoc: (project_id, doc_id, callback = (error, res, body) ->) -> + getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) -> request.get { url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" json: true + qs:qs }, callback getAllDocs: (project_id, callback = (error, res, body) ->) -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 7ec4d046ce..66f82f5b7b 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -13,7 +13,7 @@ describe "HttpController", -> "./DocManager": @DocManager = {} "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } @res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() } - @req = {} + @req = { query:{}} @next = sinon.stub() @project_id = "mock-project-id" @doc_id = "mock-doc-id" @@ -23,16 +23,22 @@ describe "HttpController", -> version: 42 rev: 5 } + @deletedDoc = { + deleted:true + _id: @doc_id + lines: ["mock", "lines", " here", "", "", " spaces "] + version: 42 + rev: 5 + } describe "getDoc", -> - beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) describe "without deleted docs", -> beforeEach -> + @req.params = + project_id: @project_id + doc_id: @doc_id + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) @HttpController.getDoc @req, @res, @next it "should get the document (including deleted)", -> @@ -50,13 +56,31 @@ describe "HttpController", -> }) .should.equal true - describe "with deleted docs", -> + describe "which is deleted", -> beforeEach -> - @HttpController.getDoc @req, @res, @next + @req.params = + project_id: @project_id + doc_id: @doc_id + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @deletedDoc) - it "should get the document (without deleted)", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id) + it "should get the doc from the doc manager", -> + @HttpController.getDoc @req, @res, @next + @DocManager.getDoc.calledWith(@project_id, @doc_id).should.equal true + + it "should return 404 if the query string delete is not set ", -> + @HttpController.getDoc @req, @res, @next + @res.send.calledWith(404).should.equal true + + it "should return the doc as JSON if include_deleted is set to true", -> + @req.query.include_deleted = "true" + @HttpController.getDoc @req, @res, @next + @res.json + .calledWith({ + _id: @doc_id + lines: @doc.lines + rev: @doc.rev + deleted: true + }) .should.equal true describe "getRawDoc", -> From 18a05d881341e9aa448bb80eaa564c313557fd1a Mon Sep 17 00:00:00 2001 From: James Allen Date: Tue, 10 Feb 2015 13:22:28 +0000 Subject: [PATCH 037/349] Release version 0.1.2 --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 8923088f41..16da100cfd 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -1,6 +1,6 @@ { "name": "docstore-sharelatex", - "version": "0.1.0", + "version": "0.1.2", "description": "A CRUD API for handling text documents in projects", "author": "ShareLaTeX ", "repository": { From daf7c4f68e6171265958c21490bdf7acf294643b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Sun, 22 Feb 2015 18:45:21 +0000 Subject: [PATCH 038/349] log out when a doc from the project collection is used --- services/docstore/app/coffee/DocManager.coffee | 1 + services/docstore/test/unit/coffee/DocManagerTests.coffee | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 9ebf324841..49d34a7399 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -16,6 +16,7 @@ module.exports = DocManager = if docFromDocCollection? return callback null, docFromDocCollection, mongoPath else if doc? + logger.warn project_id:project_id, doc_id:doc_id, "doc just used from project collection, why?" return callback null, doc, mongoPath else return callback new Errors.NotFoundError("No such doc: #{project_id}") diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 3172e8ea5b..cf4f76f0f8 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -11,7 +11,7 @@ describe "DocManager", -> beforeEach -> @DocManager = SandboxedModule.require modulePath, requires: "./MongoManager": @MongoManager = {} - "logger-sharelatex": @logger = {log: sinon.stub()} + "logger-sharelatex": @logger = {log: sinon.stub(), warn:->} @doc_id = ObjectId().toString() @project_id = ObjectId().toString() @callback = sinon.stub() From 3cd3c118d1aefef65e5da280a7902f1a044dbd91 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 Feb 2015 13:17:55 +0000 Subject: [PATCH 039/349] don't log out when doc lines are [] as this is a new empty doc --- services/docstore/app/coffee/DocManager.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 49d34a7399..b0f540fecb 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -16,7 +16,8 @@ module.exports = DocManager = if docFromDocCollection? return callback null, docFromDocCollection, mongoPath else if doc? - logger.warn project_id:project_id, doc_id:doc_id, "doc just used from project collection, why?" + if doc?.lines?.length > 0 + logger.warn project_id:project_id, doc_id:doc_id, "doc just used from project collection, why?" return callback null, doc, mongoPath else return callback new Errors.NotFoundError("No such doc: #{project_id}") From 5861231548ac993c558f02f9c0770a763c72df1b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 20 Feb 2015 14:28:16 +0000 Subject: [PATCH 040/349] docstore now only touches doc collection - need to run migration 1 before using this for this to work - added acceptence test so new documents updated should be upserted, not return 404 --- .../docstore/app/coffee/DocManager.coffee | 115 ++++------ .../docstore/app/coffee/MongoManager.coffee | 13 +- services/docstore/app/coffee/mongojs.coffee | 2 +- .../coffee/DeletingDocsTests.coffee | 9 +- .../coffee/GettingAllDocsTests.coffee | 19 +- .../acceptance/coffee/GettingDocsTests.coffee | 9 +- .../coffee/UpdatingDocsTests.coffee | 30 ++- .../coffee/helpers/DocstoreClient.coffee | 19 +- .../test/unit/coffee/DocManagerTests.coffee | 196 +++--------------- .../test/unit/coffee/MongoManagerTests.coffee | 48 ++--- 10 files changed, 114 insertions(+), 346 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index b0f540fecb..2cbd0b65c7 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -5,57 +5,50 @@ _ = require "underscore" async = require "async" module.exports = DocManager = - getDoc: (project_id, doc_id, callback = (error, doc, mongoPath) ->) -> - MongoManager.findDoc doc_id, (err, docFromDocCollection)-> - return callback(err) if err? - MongoManager.findProject project_id, (error, project) -> - return callback(error) if error? - return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? - DocManager.findDocInProject project, doc_id, (error, doc, mongoPath) -> - return callback(error) if error? - if docFromDocCollection? - return callback null, docFromDocCollection, mongoPath - else if doc? - if doc?.lines?.length > 0 - logger.warn project_id:project_id, doc_id:doc_id, "doc just used from project collection, why?" - return callback null, doc, mongoPath - else - return callback new Errors.NotFoundError("No such doc: #{project_id}") + + getDoc: (project_id, doc_id, callback = (error, doc) ->) -> + MongoManager.findDoc doc_id, (err, doc)-> + if err? + return callback(err) + else if !doc? + return callback new Errors.NotFoundError("No such doc: #{doc_id} in project #{project_id}") + callback null, doc getAllDocs: (project_id, callback = (error, docs) ->) -> - MongoManager.findProject project_id, (error, project) -> - return callback(error) if error? - return callback new Errors.NotFoundError("No such project: #{project_id}") if !project? - DocManager.findAllDocsInProject project, (error, docs) -> - return callback(error) if error? - return callback null, docs + MongoManager.getProjectsDocs project_id, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + else + return callback(null, docs) updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> - DocManager.getDoc project_id, doc_id, (error, doc, mongoPath) -> - return callback(error) if error? - return callback new Errors.NotFoundError("No such project/doc to update: #{project_id}/#{doc_id}") if !doc? or !mongoPath? + DocManager.getDoc project_id, doc_id, (error, doc) -> - if _.isEqual(doc.lines, lines) - logger.log { - project_id: project_id, doc_id: doc_id, rev: doc.rev - }, "doc lines have not changed" - return callback null, false, doc.rev - else - logger.log { - project_id: project_id - doc_id: doc_id, - oldDocLines: doc.lines - newDocLines: lines - rev: doc.rev - }, "updating doc lines" - async.series [ - (cb)-> - MongoManager.upsertIntoDocCollection project_id, doc_id, lines, doc.rev, cb - (cb)-> - MongoManager.updateDoc project_id, mongoPath, lines, cb - ], (error)-> - return callback(error) if error? - callback null, true, doc.rev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc + isNewDoc = error?.name == new Errors.NotFoundError().name + + if !isNewDoc and error? + logger.err project_id: project_id, doc_id: doc_id, err:error, "error getting document for update" + return callback(error) + else if !isNewDoc and !doc? + logger.err project_id: project_id, doc_id: doc_id, "existing document to update could not be found" + return callback new Errors.NotFoundError("No such project/doc to update: #{project_id}/#{doc_id}") + else if _.isEqual(doc?.lines, lines) + logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating" + return callback null, false, doc?.rev + + oldRev = doc?.rev || 0 + logger.log { + project_id: project_id + doc_id: doc_id, + oldDocLines: doc?.lines + newDocLines: lines + rev: oldRev + }, "updating doc lines" + MongoManager.upsertIntoDocCollection project_id, doc_id, lines, oldRev, (error)-> + return callback(callback) if error? + callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc deleteDoc: (project_id, doc_id, callback = (error) ->) -> DocManager.getDoc project_id, doc_id, (error, doc) -> @@ -67,33 +60,3 @@ module.exports = DocManager = return callback(error) if error? callback() - findAllDocsInProject: (project, callback = (error, docs) ->) -> - callback null, @_findAllDocsInFolder project.rootFolder[0] - - findDocInProject: (project, doc_id, callback = (error, doc, mongoPath) ->) -> - result = @_findDocInFolder project.rootFolder[0], doc_id, "rootFolder.0" - if result? - callback null, result.doc, result.mongoPath - else - callback null, null, null - - _findDocInFolder: (folder = {}, doc_id, currentPath) -> - for doc, i in folder.docs or [] - if doc?._id? and doc._id.toString() == doc_id.toString() - return { - doc: doc - mongoPath: "#{currentPath}.docs.#{i}" - } - - for childFolder, i in folder.folders or [] - result = @_findDocInFolder childFolder, doc_id, "#{currentPath}.folders.#{i}" - return result if result? - - return null - - _findAllDocsInFolder: (folder = {}) -> - docs = folder.docs or [] - for childFolder in folder.folders or [] - docs = docs.concat @_findAllDocsInFolder childFolder - return docs - diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 05a61e4ccf..be13b6a084 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -1,22 +1,13 @@ {db, ObjectId} = require "./mongojs" module.exports = MongoManager = - findProject: (project_id, callback = (error, project) ->) -> - db.projects.find _id: ObjectId(project_id.toString()), {}, (error, projects = []) -> - callback error, projects[0] findDoc: (doc_id, callback = (error, doc) ->) -> db.docs.find _id: ObjectId(doc_id.toString()), {}, (error, docs = []) -> callback error, docs[0] - updateDoc: (project_id, docPath, lines, callback = (error) ->) -> - update = - $set: {} - $inc: {} - update.$set["#{docPath}.lines"] = lines - update.$inc["#{docPath}.rev"] = 1 - - db.projects.update _id: ObjectId(project_id), update, callback + getProjectsDocs: (project_id, callback)-> + db.docs.find project_id: ObjectId(project_id.toString()), {}, callback upsertIntoDocCollection: (project_id, doc_id, lines, oldRev, callback)-> update = diff --git a/services/docstore/app/coffee/mongojs.coffee b/services/docstore/app/coffee/mongojs.coffee index aae672b8f3..9a8d6c38e5 100644 --- a/services/docstore/app/coffee/mongojs.coffee +++ b/services/docstore/app/coffee/mongojs.coffee @@ -1,6 +1,6 @@ Settings = require "settings-sharelatex" mongojs = require "mongojs" -db = mongojs.connect(Settings.mongo.url, ["projects", "docs"]) +db = mongojs.connect(Settings.mongo.url, ["docs"]) module.exports = db: db ObjectId: mongojs.ObjectId diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee index fa7e15f61c..d2d5a05727 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -11,14 +11,9 @@ describe "Deleting a doc", -> @doc_id = ObjectId() @lines = ["original", "lines"] @version = 42 - DocstoreClient.createProject @project_id, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => - throw error if error? - done() - - afterEach (done) -> - DocstoreClient.deleteProject @project_id, done + done() describe "when the doc exists", -> beforeEach (done) -> diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index 53b26d453b..4463abcdad 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -22,18 +22,13 @@ describe "Getting all docs", -> lines: ["111", "222", "333"] rev: 6 }] - DocstoreClient.createProject @project_id, (error) => - throw error if error? - jobs = for doc in @docs - do (doc) => - (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> - doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback - async.series jobs, done - - afterEach (done) -> - DocstoreClient.deleteProject @project_id, done + jobs = for doc in @docs + do (doc) => + (callback) => + DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + doc.lines[0] = doc.lines[0]+" added" + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback + async.series jobs, done it "should return all the docs", (done) -> DocstoreClient.getAllDocs @project_id, (error, res, docs) => diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index 35b51537fa..345f29f89f 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -10,14 +10,9 @@ describe "Getting a doc", -> @project_id = ObjectId() @doc_id = ObjectId() @lines = ["original", "lines"] - DocstoreClient.createProject @project_id, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => - throw error if error? - done() - - afterEach (done) -> - DocstoreClient.deleteProject @project_id, done + done() describe "when the doc exists", -> it "should get the doc lines and version", (done) -> diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 7d168922af..b18be15c25 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -11,14 +11,9 @@ describe "Applying updates to a doc", -> @doc_id = ObjectId() @originalLines = ["original", "lines"] @newLines = ["new", "lines"] - DocstoreClient.createProject @project_id, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => throw error if error? - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => - throw error if error? - done() - - afterEach (done) -> - DocstoreClient.deleteProject @project_id, done + done() describe "when the content has changed", -> beforeEach (done) -> @@ -28,6 +23,9 @@ describe "Applying updates to a doc", -> it "should return modified = true", -> @body.modified.should.equal true + it "should return the rev", -> + @body.rev.should.equal 2 + it "should update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @newLines @@ -48,22 +46,18 @@ describe "Applying updates to a doc", -> describe "when the doc does not exist", -> beforeEach (done) -> - missing_doc_id = ObjectId() - DocstoreClient.updateDoc @project_id, missing_doc_id, @originalLines, (error, @res, @body) => + @missing_doc_id = ObjectId() + DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, (error, @res, @body) => done() - it "should return a 404", -> - @res.statusCode.should.equal 404 + it "should create the doc", -> + @body.rev.should.equal 1 - describe "when the project does not exist", -> - beforeEach (done) -> - missing_project_id = ObjectId() - DocstoreClient.updateDoc missing_project_id, @doc_id, @originalLines, (error, @res, @body) => + it "should be retreivable", (done)-> + DocstoreClient.getDoc @project_id, @missing_doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @originalLines done() - it "should return a 404", -> - @res.statusCode.should.equal 404 - describe "when malformed doc lines are provided", -> describe "when the lines are not an array", -> beforeEach (done) -> diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index d3a65790b8..1d2bcadc75 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -2,23 +2,9 @@ request = require("request").defaults(jar: false) {db, ObjectId} = require("../../../../app/js/mongojs") module.exports = DocstoreClient = - createProject: (project_id, callback = (error) ->) -> - db.projects.insert { - _id: project_id - rootFolder: [{ docs: [] }] - }, callback createDoc: (project_id, doc_id, lines, callback = (error) ->) -> - db.projects.update { - _id: project_id - }, { - $push: { - "rootFolder.0.docs": { - _id: doc_id - lines: lines - } - } - }, callback + db.docs.save({_id: doc_id, project_id:project_id, lines: lines, rev:1}, callback) createDeletedDoc: (project_id, doc_id, lines, callback = (error) ->) -> db.docs.insert { @@ -28,9 +14,6 @@ module.exports = DocstoreClient = deleted: true }, callback - deleteProject: (project_id, callback = (error, res, body) ->) -> - db.projects.remove _id: project_id, callback - getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) -> request.get { url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index cf4f76f0f8..712047f914 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -11,7 +11,10 @@ describe "DocManager", -> beforeEach -> @DocManager = SandboxedModule.require modulePath, requires: "./MongoManager": @MongoManager = {} - "logger-sharelatex": @logger = {log: sinon.stub(), warn:->} + "logger-sharelatex": @logger = + log: sinon.stub() + warn:-> + err:-> @doc_id = ObjectId().toString() @project_id = ObjectId().toString() @callback = sinon.stub() @@ -27,8 +30,6 @@ describe "DocManager", -> beforeEach -> @MongoManager.findDoc = sinon.stub() - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) - @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) it "should get the doc from the doc collection when it is present there", (done)-> @MongoManager.findDoc.callsArgWith(1, null, @docCollectionDoc) @@ -42,46 +43,8 @@ describe "DocManager", -> err.should.equal @stubbedError done() - describe "when the project exists and the doc is in it", -> - beforeEach -> - @mongoPath = "mock.mongo.path" - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) - @MongoManager.findDoc = sinon.stub().callsArg(1) - @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) - @DocManager.getDoc @project_id, @doc_id, @callback - - it "should get the project from the database", -> - @MongoManager.findProject - .calledWith(@project_id) - .should.equal true - - it "should find the doc in the project", -> - @DocManager.findDocInProject - .calledWith(@project, @doc_id) - .should.equal true - - it "should return the doc", -> - @callback.calledWith(null, @doc, @mongoPath).should.equal true - - describe "when the project does not exist", -> - beforeEach -> - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, null) - @MongoManager.findDoc = sinon.stub().callsArg(1) - @DocManager.findDocInProject = sinon.stub() - @DocManager.getDoc @project_id, @doc_id, @callback - - it "should not try to find the doc in the project", -> - @DocManager.findDocInProject.called.should.equal false - - it "should return a NotFoundError", -> - @callback - .calledWith(new Errors.NotFoundError("No such project: #{@project_id}")) - .should.equal true - describe "when the doc is deleted", -> beforeEach -> - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) - @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) @DocManager.getDoc @project_id, @doc_id, @callback @@ -96,55 +59,39 @@ describe "DocManager", -> .calledWith(null, @doc) .should.equal true - - describe "when the doc does not exist anywhere", -> beforeEach -> - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) - @DocManager.findDocInProject = sinon.stub().callsArgWith(2, null, null, null) @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null) @DocManager.getDoc @project_id, @doc_id, @callback it "should return a NotFoundError", -> @callback - .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) + .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id} in project #{@project_id}")) .should.equal true describe "getAllDocs", -> describe "when the project exists", -> beforeEach -> - @project = { name: "mock-project" } @docs = [{ _id: @doc_id, lines: ["mock-lines"] }] - @mongoPath = "mock.mongo.path" - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, @project) - @DocManager.findAllDocsInProject = sinon.stub().callsArgWith(1, null, @docs) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @docs) @DocManager.getAllDocs @project_id, @callback it "should get the project from the database", -> - @MongoManager.findProject + @MongoManager.getProjectsDocs .calledWith(@project_id) .should.equal true - it "should find all the docs in the project", -> - @DocManager.findAllDocsInProject - .calledWith(@project) - .should.equal true - it "should return the docs", -> @callback.calledWith(null, @docs).should.equal true - describe "when the project does not exist", -> + describe "when there are no docs for the project", -> beforeEach -> - @MongoManager.findProject = sinon.stub().callsArgWith(1, null, null) - @DocManager.findAllDocsInProject = sinon.stub() + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null) @DocManager.getAllDocs @project_id, @callback - it "should not try to find the doc in the project", -> - @DocManager.findAllDocsInProject.called.should.equal false - it "should return a NotFoundError", -> @callback - .calledWith(new Errors.NotFoundError("No such project: #{@project_id}")) + .calledWith(new Errors.NotFoundError("No such docs for project #{@project_id}")) .should.equal true describe "deleteDoc", -> @@ -194,14 +141,13 @@ describe "DocManager", -> @oldDocLines = ["old", "doc", "lines"] @newDocLines = ["new", "doc", "lines"] @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5 } - @mongoPath = "mock.mongo.path" @MongoManager.updateDoc = sinon.stub().callsArg(3) @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) describe "when the doc lines have changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should get the existing doc", -> @@ -209,11 +155,6 @@ describe "DocManager", -> .calledWith(@project_id, @doc_id) .should.equal true - it "should update the doc with the new doc lines", -> - @MongoManager.updateDoc - .calledWith(@project_id, @mongoPath, @newDocLines) - .should.equal true - it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection .calledWith(@project_id, @doc_id, @newDocLines, @rev) @@ -234,13 +175,25 @@ describe "DocManager", -> it "should return the callback with the new rev", -> @callback.calledWith(null, true, @rev + 1).should.equal true + describe "when there is a generic error getting the doc", -> + + beforeEach -> + @error = new Error("doc could not be found") + @DocManager.getDoc = sinon.stub().callsArgWith(2, @error, null, null) + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + + it "should not upsert the document to the doc collection", -> + @MongoManager.upsertIntoDocCollection.called.should.equal false + + it "should return the callback with the error", -> + @callback.calledWith(@error).should.equal true + describe "when the doc lines have not changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback it "should not update the doc", -> - @MongoManager.updateDoc.called.should.equal false @MongoManager.upsertIntoDocCollection.called.should.equal false it "should return the callback with the existing rev", -> @@ -248,98 +201,17 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) + NotFoundError = Errors.NotFoundError("doc could not be found") + @DocManager.getDoc = sinon.stub().callsArgWith(2, NotFoundError, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + + it "should upsert the document to the doc collection", -> + @MongoManager.upsertIntoDocCollection + .calledWith(@project_id, @doc_id, @newDocLines) + .should.equal true - it "should not try to update the doc", -> - @MongoManager.updateDoc.called.should.equal false - @MongoManager.upsertIntoDocCollection.called.should.equal false + it "should return the callback with the new rev", -> + @callback.calledWith(null, true, 1).should.equal true - it "should return a NotFoundError", -> - @callback - .calledWith(new Errors.NotFoundError("No such project/doc: #{@project_id}/#{@doc_id}")) - .should.equal true - describe "findDocInProject", -> - it "should find the doc when it is in the root folder", (done) -> - @DocManager.findDocInProject { - rootFolder: [{ - docs: [{ - _id: ObjectId(@doc_id) - }] - }] - }, @doc_id, (error, doc, mongoPath) => - expect(doc).to.deep.equal { _id: ObjectId(@doc_id) } - mongoPath.should.equal "rootFolder.0.docs.0" - done() - it "should find the doc when it is in a sub folder", (done) -> - @DocManager.findDocInProject { - rootFolder: [{ - folders: [{ - docs: [{ - _id: ObjectId(@doc_id) - }] - }] - }] - }, @doc_id, (error, doc, mongoPath) => - expect(doc).to.deep.equal { _id: ObjectId(@doc_id) } - mongoPath.should.equal "rootFolder.0.folders.0.docs.0" - done() - - it "should find the doc when it there are other docs", (done) -> - @DocManager.findDocInProject { - rootFolder: [{ - folders: [{ - docs: [{ - _id: ObjectId() - }] - }, { - docs: [{ - _id: ObjectId() - }, { - _id: ObjectId(@doc_id) - }] - }], - docs: [{ - _id: ObjectId() - }] - }] - }, @doc_id, (error, doc, mongoPath) => - expect(doc).to.deep.equal { _id: ObjectId(@doc_id) } - mongoPath.should.equal "rootFolder.0.folders.1.docs.1" - done() - - it "should return null when the doc doesn't exist", (done) -> - @DocManager.findDocInProject { - rootFolder: [{ - folders: [{ - docs: [] - }] - }] - }, @doc_id, (error, doc, mongoPath) => - expect(doc).to.be.null - expect(mongoPath).to.be.null - done() - - describe "findAllDocsInProject", -> - it "should return all the docs", (done) -> - @DocManager.findAllDocsInProject { - rootFolder: [{ - docs: [ - @doc1 = { _id: ObjectId() } - ], - folders: [{ - docs: [ - @doc2 = { _id: ObjectId() } - ] - }, { - docs: [ - @doc3 = { _id: ObjectId() } - @doc4 = { _id: ObjectId() } - ] - }] - }] - }, (error, docs) => - expect(docs).to.deep.equal [@doc1, @doc2, @doc3, @doc4] - done() diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index aac8447a4c..add0b33c37 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -9,29 +9,13 @@ describe "MongoManager", -> beforeEach -> @MongoManager = SandboxedModule.require modulePath, requires: "./mongojs": - db: @db = { projects: {}, docs: {} } + db: @db = { docs: {} } ObjectId: ObjectId @project_id = ObjectId().toString() @doc_id = ObjectId().toString() @callback = sinon.stub() @stubbedErr = new Error("hello world") - describe "findProject", -> - beforeEach -> - @project = { name: "mock-project" } - @db.projects.find = sinon.stub().callsArgWith(2, null, [@project]) - @MongoManager.findProject @project_id, @callback - - it "should find the project", -> - @db.projects.find - .calledWith({ - _id: ObjectId(@project_id) - }, {}) - .should.equal true - - it "should call the callback with the project", -> - @callback.calledWith(null, @project).should.equal true - describe "findDoc", -> beforeEach -> @doc = { name: "mock-doc" } @@ -48,28 +32,24 @@ describe "MongoManager", -> it "should call the callback with the doc", -> @callback.calledWith(null, @doc).should.equal true - describe "updateDoc", -> + describe "getProjectsDocs", -> beforeEach -> - @lines = ["mock-lines"] - @docPath = "rootFolder.0.folders.1.docs.0" - @db.projects.update = sinon.stub().callsArg(2) - @MongoManager.updateDoc @project_id, @docPath, @lines, @callback + @doc1 = { name: "mock-doc1" } + @doc2 = { name: "mock-doc2" } + @doc3 = { name: "mock-doc3" } + @doc4 = { name: "mock-doc4" } + @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc, @doc3, @doc4]) + @MongoManager.getProjectsDocs @project_id, @callback - it "should update the doc lines and increment the TPDS rev", -> - @db.projects.update + it "should find the docs via the project_id", -> + @db.docs.find .calledWith({ - _id: ObjectId(@project_id) - }, { - $set: - "rootFolder.0.folders.1.docs.0.lines": @lines - $inc: - "rootFolder.0.folders.1.docs.0.rev": 1 - }) + project_id: ObjectId(@project_id) + }, {}) .should.equal true - it "should call the callback with the project", -> - @callback.called.should.equal true - + it "should call the callback with the docs", -> + @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true describe "upsertIntoDocCollection", -> beforeEach -> From 724211953273bd654c29747bcd966f5d5a0d6c5d Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 26 Feb 2015 16:00:28 +0000 Subject: [PATCH 041/349] simplified DocManager.updateDoc so it calls mongomanager.findDoc makes the logic for dealing new documents that are not in mongo yet much simpler --- .../docstore/app/coffee/DocManager.coffee | 41 ++++++++----------- .../test/unit/coffee/DocManagerTests.coffee | 15 ++++--- 2 files changed, 25 insertions(+), 31 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 2cbd0b65c7..fbf201bcd5 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -24,31 +24,26 @@ module.exports = DocManager = return callback(null, docs) updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> - DocManager.getDoc project_id, doc_id, (error, doc) -> - - isNewDoc = error?.name == new Errors.NotFoundError().name - - if !isNewDoc and error? - logger.err project_id: project_id, doc_id: doc_id, err:error, "error getting document for update" - return callback(error) - else if !isNewDoc and !doc? - logger.err project_id: project_id, doc_id: doc_id, "existing document to update could not be found" - return callback new Errors.NotFoundError("No such project/doc to update: #{project_id}/#{doc_id}") - else if _.isEqual(doc?.lines, lines) + MongoManager.findDoc doc_id, (err, doc)-> + if err? + logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" + return callback(err) + + if _.isEqual(doc?.lines, lines) logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating" return callback null, false, doc?.rev - - oldRev = doc?.rev || 0 - logger.log { - project_id: project_id - doc_id: doc_id, - oldDocLines: doc?.lines - newDocLines: lines - rev: oldRev - }, "updating doc lines" - MongoManager.upsertIntoDocCollection project_id, doc_id, lines, oldRev, (error)-> - return callback(callback) if error? - callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc + else + oldRev = doc?.rev || 0 + logger.log { + project_id: project_id + doc_id: doc_id, + oldDocLines: doc?.lines + newDocLines: lines + rev: oldRev + }, "updating doc lines" + MongoManager.upsertIntoDocCollection project_id, doc_id, lines, oldRev, (error)-> + return callback(callback) if error? + callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc deleteDoc: (project_id, doc_id, callback = (error) ->) -> DocManager.getDoc project_id, doc_id, (error, doc) -> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 712047f914..81bd9a3a6d 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -142,17 +142,17 @@ describe "DocManager", -> @newDocLines = ["new", "doc", "lines"] @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5 } - @MongoManager.updateDoc = sinon.stub().callsArg(3) @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) + @MongoManager.findDoc = sinon.stub() describe "when the doc lines have changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should get the existing doc", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id) + @MongoManager.findDoc + .calledWith(@doc_id) .should.equal true it "should upsert the document to the doc collection", -> @@ -179,7 +179,7 @@ describe "DocManager", -> beforeEach -> @error = new Error("doc could not be found") - @DocManager.getDoc = sinon.stub().callsArgWith(2, @error, null, null) + @MongoManager.findDoc = sinon.stub().callsArgWith(1, @error, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should not upsert the document to the doc collection", -> @@ -190,7 +190,7 @@ describe "DocManager", -> describe "when the doc lines have not changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback it "should not update the doc", -> @@ -201,8 +201,7 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> - NotFoundError = Errors.NotFoundError("doc could not be found") - @DocManager.getDoc = sinon.stub().callsArgWith(2, NotFoundError, null, null) + @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should upsert the document to the doc collection", -> From a73dc90b00930d3808dd2bfa7e2075e9cb7c7a29 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 26 Feb 2015 16:01:10 +0000 Subject: [PATCH 042/349] change mongomangers upsert to use an inc this is tested and does work with new documents --- services/docstore/app/coffee/MongoManager.coffee | 3 ++- services/docstore/test/unit/coffee/MongoManagerTests.coffee | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index be13b6a084..8db8d57dc3 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -12,9 +12,10 @@ module.exports = MongoManager = upsertIntoDocCollection: (project_id, doc_id, lines, oldRev, callback)-> update = $set:{} + $inc:{} update.$set["lines"] = lines update.$set["project_id"] = ObjectId(project_id) - update.$set["rev"] = oldRev + 1 + update.$inc["rev"] = 1 #on new docs being created this will set the rev to 1 db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index add0b33c37..97f09035e8 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -61,7 +61,7 @@ describe "MongoManager", -> args = @db.docs.update.args[0] assert.deepEqual args[0], {_id: ObjectId(@doc_id)} assert.equal args[1]["$set"]["lines"], @lines - assert.equal args[1]["$set"]["rev"], 78 + assert.equal args[1]["$inc"]["rev"], 1 assert.deepEqual args[1]["$set"]["project_id"], ObjectId(@project_id) done() From 32829f0e6ea7b4a7550bb2fec89683b2b7043db0 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 27 Feb 2015 14:06:06 +0000 Subject: [PATCH 043/349] remove old rev, not needed any more --- services/docstore/app/coffee/DocManager.coffee | 4 ++-- services/docstore/app/coffee/MongoManager.coffee | 2 +- services/docstore/test/unit/coffee/DocManagerTests.coffee | 8 ++++---- .../docstore/test/unit/coffee/MongoManagerTests.coffee | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index fbf201bcd5..4cef291854 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -41,7 +41,7 @@ module.exports = DocManager = newDocLines: lines rev: oldRev }, "updating doc lines" - MongoManager.upsertIntoDocCollection project_id, doc_id, lines, oldRev, (error)-> + MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)-> return callback(callback) if error? callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc @@ -49,7 +49,7 @@ module.exports = DocManager = DocManager.getDoc project_id, doc_id, (error, doc) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? - MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, doc.rev, (error) -> + MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, (error) -> return callback(error) if error? MongoManager.markDocAsDeleted doc_id, (error) -> return callback(error) if error? diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 8db8d57dc3..352483fbfc 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -9,7 +9,7 @@ module.exports = MongoManager = getProjectsDocs: (project_id, callback)-> db.docs.find project_id: ObjectId(project_id.toString()), {}, callback - upsertIntoDocCollection: (project_id, doc_id, lines, oldRev, callback)-> + upsertIntoDocCollection: (project_id, doc_id, lines, callback)-> update = $set:{} $inc:{} diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 81bd9a3a6d..b09ed900c8 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -100,7 +100,7 @@ describe "DocManager", -> @lines = ["mock", "doc", "lines"] @rev = 77 @DocManager.getDoc = sinon.stub().callsArgWith(2, null, {lines: @lines, rev:@rev}) - @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) + @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @MongoManager.markDocAsDeleted = sinon.stub().callsArg(1) @DocManager.deleteDoc @project_id, @doc_id, @callback @@ -111,7 +111,7 @@ describe "DocManager", -> it "should update the doc lines", -> @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @lines, @rev) + .calledWith(@project_id, @doc_id, @lines) .should.equal true it "should mark doc as deleted", -> @@ -142,7 +142,7 @@ describe "DocManager", -> @newDocLines = ["new", "doc", "lines"] @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5 } - @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(4) + @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @MongoManager.findDoc = sinon.stub() describe "when the doc lines have changed", -> @@ -157,7 +157,7 @@ describe "DocManager", -> it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @newDocLines, @rev) + .calledWith(@project_id, @doc_id, @newDocLines) .should.equal true it "should log out the old and new doc lines", -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 97f09035e8..b0e7c07e97 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -57,7 +57,7 @@ describe "MongoManager", -> @oldRev = 77 it "should upsert the document", (done)-> - @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, @oldRev, (err)=> + @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, (err)=> args = @db.docs.update.args[0] assert.deepEqual args[0], {_id: ObjectId(@doc_id)} assert.equal args[1]["$set"]["lines"], @lines @@ -66,7 +66,7 @@ describe "MongoManager", -> done() it "should return the error", (done)-> - @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, @oldRev, (err)=> + @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, (err)=> err.should.equal @stubbedErr done() From 53480153e385107c42165189bec5fbe3b6d8fe47 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Fri, 27 Feb 2015 14:50:08 +0000 Subject: [PATCH 044/349] if the doc has no lines then it is new and needs to be written --- .../docstore/app/coffee/DocManager.coffee | 4 +++- .../test/unit/coffee/DocManagerTests.coffee | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 49d34a7399..a8a5c0c01f 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -34,7 +34,9 @@ module.exports = DocManager = return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc to update: #{project_id}/#{doc_id}") if !doc? or !mongoPath? - if _.isEqual(doc.lines, lines) + isNewDoc = lines.length == 0 + linesAreSame = _.isEqual(doc.lines, lines) + if linesAreSame and !isNewDoc logger.log { project_id: project_id, doc_id: doc_id, rev: doc.rev }, "doc lines have not changed" diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index cf4f76f0f8..1e4050ed3d 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -246,6 +246,25 @@ describe "DocManager", -> it "should return the callback with the existing rev", -> @callback.calledWith(null, false, @rev).should.equal true + + describe "when the doc lines are an empty array", -> + beforeEach -> + + @doc.lines = [] + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc, @mongoPath) + @DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback + + it "should still upsert the doc even though the lines are the same", -> + @MongoManager.updateDoc + .calledWith(@project_id, @mongoPath, []) + .should.equal true + + it "should upsert the document to the doc collection", -> + @MongoManager.upsertIntoDocCollection + .calledWith(@project_id, @doc_id, [], @rev) + .should.equal true + + describe "when the doc does not exist", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) From 6c568d9cbb884449788759e65c3219925286273a Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Mon, 23 Feb 2015 13:17:55 +0000 Subject: [PATCH 045/349] don't log out when doc lines are [] as this is a new empty doc --- services/docstore/app/coffee/DocManager.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index a8a5c0c01f..a65da55004 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -16,7 +16,8 @@ module.exports = DocManager = if docFromDocCollection? return callback null, docFromDocCollection, mongoPath else if doc? - logger.warn project_id:project_id, doc_id:doc_id, "doc just used from project collection, why?" + if doc?.lines?.length > 0 + logger.warn project_id:project_id, doc_id:doc_id, "doc just used from project collection, why?" return callback null, doc, mongoPath else return callback new Errors.NotFoundError("No such doc: #{project_id}") From 73a73adf627fabc3e2f1423c06d3fd6d50b9f7ab Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 30 Apr 2015 15:04:26 +0100 Subject: [PATCH 046/349] make startup message consistent --- services/docstore/app.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index c97a02799a..ec9b250851 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -35,4 +35,4 @@ port = Settings.internal.docstore.port host = Settings.internal.docstore.host app.listen port, host, (error) -> throw error if error? - logger.log("docstore listening on #{host}:#{port}") + logger.info "Docstore starting up, listening on #{host}:#{port}" From 314c7350042848a8a721199899fa5f5a2119e382 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 1 Jun 2015 18:22:02 -0300 Subject: [PATCH 047/349] initial version for archive docs in S3 --- services/docstore/app.coffee | 1 + .../docstore/app/coffee/DocManager.coffee | 35 ++++++++++++++++++ .../docstore/app/coffee/HttpController.coffee | 7 ++++ .../docstore/config/settings.defaults.coffee | 8 +++++ .../acceptance/coffee/ArchiveDocsTests.coffee | 36 +++++++++++++++++++ .../coffee/helpers/DocstoreClient.coffee | 14 +++++--- 6 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index ec9b250851..8609d79e8f 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -20,6 +20,7 @@ app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc +app.get '/project/:project_id/archive', HttpController.archiveAllDocs app.get '/status', (req, res)-> res.send('docstore is alive') diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index ef03969a30..57184d8844 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -3,6 +3,10 @@ Errors = require "./Errors" logger = require "logger-sharelatex" _ = require "underscore" async = require "async" +settings = require("settings-sharelatex") +request = require("request") +crypto = require("crypto") +thirtySeconds = 30 * 1000 module.exports = DocManager = @@ -58,3 +62,34 @@ module.exports = DocManager = return callback(error) if error? callback() + archiveAllDocs: (project_id, callback = (error, docs) ->) -> + MongoManager.getProjectsDocs project_id, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + + jobs = for doc in docs + do (doc) => + (cb) => + logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" + options = buildS3Options(doc.lines, project_id+"/"+doc._id) + request.put options, (err, res)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong archiving file in aws" + cb(err) + + async.series jobs, callback + +buildS3Options = (content, key)-> + return { + aws: + key: settings.filestore.s3.key + secret: settings.filestore.s3.secret + bucket: settings.filestore.stores.user_files + timeout: thirtySeconds + json: content + #headers: + # 'content-md5': crypto.createHash("md5").update(content).digest("hex") + uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" + } diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 2a974794b2..1c790ac9ba 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -78,3 +78,10 @@ module.exports = HttpController = _buildRawDocView: (doc)-> return (doc?.lines or []).join("\n") + + archiveAllDocs: (req, res, next = (error) ->) -> + project_id = req.params.project_id + logger.log project_id: project_id, "archiving all docs" + DocManager.archiveAllDocs project_id, (error) -> + return next(error) if error? + res.send 204 diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 8a3fc9197f..d708b56ce2 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -9,3 +9,11 @@ module.exports = mongo: url: 'mongodb://127.0.0.1/sharelatex' + + #filestore: + # backend: "s3" + # stores: + # user_files: "" + # s3: + # key: "" + # secret: "" \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee new file mode 100644 index 0000000000..f55e39099c --- /dev/null +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -0,0 +1,36 @@ +sinon = require "sinon" +chai = require("chai") +chai.should() +{ObjectId} = require "mongojs" +async = require "async" + +DocstoreClient = require "./helpers/DocstoreClient" + +describe "Archiving all docs", -> + beforeEach (done) -> + @project_id = ObjectId() + @docs = [{ + _id: ObjectId() + lines: ["one", "two", "three"] + rev: 2 + }, { + _id: ObjectId() + lines: ["aaa", "bbb", "ccc"] + rev: 4 + }, { + _id: ObjectId() + lines: ["111", "222", "333"] + rev: 6 + }] + jobs = for doc in @docs + do (doc) => + (callback) => + DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + doc.lines[0] = doc.lines[0]+" added" + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback + async.series jobs, done + + it "should archive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + res.statusCode.should.equal 204 + done() \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 1d2bcadc75..989a2ce0e7 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -1,5 +1,6 @@ request = require("request").defaults(jar: false) {db, ObjectId} = require("../../../../app/js/mongojs") +settings = require("settings-sharelatex") module.exports = DocstoreClient = @@ -16,28 +17,31 @@ module.exports = DocstoreClient = getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) -> request.get { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" json: true qs:qs }, callback getAllDocs: (project_id, callback = (error, res, body) ->) -> request.get { - url: "http://localhost:3016/project/#{project_id}/doc" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc" json: true }, callback updateDoc: (project_id, doc_id, lines, callback = (error, res, body) ->) -> request.post { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" json: lines: lines }, callback deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> request.del { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" }, callback - + archiveAllDoc: (project_id, callback = (error, res, body) ->) -> + request.get { + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/archive" + }, callback From 7f5204f0f79110852e856e2bd7458b62a05a4175 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 1 Jun 2015 18:24:40 -0300 Subject: [PATCH 048/349] initial version for archive docs in S3 --- services/docstore/app.coffee | 1 + .../docstore/app/coffee/DocManager.coffee | 35 ++++++++++++++++++ .../docstore/app/coffee/HttpController.coffee | 7 ++++ .../docstore/config/settings.defaults.coffee | 8 +++++ .../acceptance/coffee/ArchiveDocsTests.coffee | 36 +++++++++++++++++++ .../coffee/helpers/DocstoreClient.coffee | 14 +++++--- 6 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index ec9b250851..8609d79e8f 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -20,6 +20,7 @@ app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc +app.get '/project/:project_id/archive', HttpController.archiveAllDocs app.get '/status', (req, res)-> res.send('docstore is alive') diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index ef03969a30..57184d8844 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -3,6 +3,10 @@ Errors = require "./Errors" logger = require "logger-sharelatex" _ = require "underscore" async = require "async" +settings = require("settings-sharelatex") +request = require("request") +crypto = require("crypto") +thirtySeconds = 30 * 1000 module.exports = DocManager = @@ -58,3 +62,34 @@ module.exports = DocManager = return callback(error) if error? callback() + archiveAllDocs: (project_id, callback = (error, docs) ->) -> + MongoManager.getProjectsDocs project_id, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + + jobs = for doc in docs + do (doc) => + (cb) => + logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" + options = buildS3Options(doc.lines, project_id+"/"+doc._id) + request.put options, (err, res)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong archiving file in aws" + cb(err) + + async.series jobs, callback + +buildS3Options = (content, key)-> + return { + aws: + key: settings.filestore.s3.key + secret: settings.filestore.s3.secret + bucket: settings.filestore.stores.user_files + timeout: thirtySeconds + json: content + #headers: + # 'content-md5': crypto.createHash("md5").update(content).digest("hex") + uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" + } diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 2a974794b2..1c790ac9ba 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -78,3 +78,10 @@ module.exports = HttpController = _buildRawDocView: (doc)-> return (doc?.lines or []).join("\n") + + archiveAllDocs: (req, res, next = (error) ->) -> + project_id = req.params.project_id + logger.log project_id: project_id, "archiving all docs" + DocManager.archiveAllDocs project_id, (error) -> + return next(error) if error? + res.send 204 diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 8a3fc9197f..d708b56ce2 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -9,3 +9,11 @@ module.exports = mongo: url: 'mongodb://127.0.0.1/sharelatex' + + #filestore: + # backend: "s3" + # stores: + # user_files: "" + # s3: + # key: "" + # secret: "" \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee new file mode 100644 index 0000000000..f55e39099c --- /dev/null +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -0,0 +1,36 @@ +sinon = require "sinon" +chai = require("chai") +chai.should() +{ObjectId} = require "mongojs" +async = require "async" + +DocstoreClient = require "./helpers/DocstoreClient" + +describe "Archiving all docs", -> + beforeEach (done) -> + @project_id = ObjectId() + @docs = [{ + _id: ObjectId() + lines: ["one", "two", "three"] + rev: 2 + }, { + _id: ObjectId() + lines: ["aaa", "bbb", "ccc"] + rev: 4 + }, { + _id: ObjectId() + lines: ["111", "222", "333"] + rev: 6 + }] + jobs = for doc in @docs + do (doc) => + (callback) => + DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + doc.lines[0] = doc.lines[0]+" added" + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback + async.series jobs, done + + it "should archive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + res.statusCode.should.equal 204 + done() \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 1d2bcadc75..989a2ce0e7 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -1,5 +1,6 @@ request = require("request").defaults(jar: false) {db, ObjectId} = require("../../../../app/js/mongojs") +settings = require("settings-sharelatex") module.exports = DocstoreClient = @@ -16,28 +17,31 @@ module.exports = DocstoreClient = getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) -> request.get { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" json: true qs:qs }, callback getAllDocs: (project_id, callback = (error, res, body) ->) -> request.get { - url: "http://localhost:3016/project/#{project_id}/doc" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc" json: true }, callback updateDoc: (project_id, doc_id, lines, callback = (error, res, body) ->) -> request.post { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" json: lines: lines }, callback deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> request.del { - url: "http://localhost:3016/project/#{project_id}/doc/#{doc_id}" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" }, callback - + archiveAllDoc: (project_id, callback = (error, res, body) ->) -> + request.get { + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/archive" + }, callback From 7c7ff649043d5e26284afed108c8f5396b207c4a Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Mon, 1 Jun 2015 19:36:26 -0300 Subject: [PATCH 049/349] retrieving all docs from s3 --- .../docstore/app/coffee/DocManager.coffee | 48 +++++++++++++++---- .../docstore/app/coffee/MongoManager.coffee | 11 +++++ .../docstore/config/settings.defaults.coffee | 3 +- .../acceptance/coffee/ArchiveDocsTests.coffee | 12 ++++- 4 files changed, 63 insertions(+), 11 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 57184d8844..205128a72f 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -19,13 +19,14 @@ module.exports = DocManager = callback null, doc getAllDocs: (project_id, callback = (error, docs) ->) -> - MongoManager.getProjectsDocs project_id, (error, docs) -> - if err? - return callback(error) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - else - return callback(null, docs) + DocManager.unArchiveAllDocs project_id, (error) -> + MongoManager.getProjectsDocs project_id, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + else + return callback(null, docs) updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> MongoManager.findDoc doc_id, (err, doc)-> @@ -76,11 +77,40 @@ module.exports = DocManager = options = buildS3Options(doc.lines, project_id+"/"+doc._id) request.put options, (err, res)-> if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong archiving file in aws" - cb(err) + logger.err err:err, res:res, "something went wrong archiving doc in aws" + cb(err) + MongoManager.markDocAsArchived doc._id, (error) -> + return cb(error) if error? + cb() async.series jobs, callback + unArchiveAllDocs: (project_id, callback = (error) ->) -> + MongoManager.getProjectsDocs project_id, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + + jobs = for doc in docs + do (doc) => + if !doc.inS3? + (cb) => cb() + else + (cb) => + logger.log project_id: project_id, doc_id: doc._id, "getting doc from s3" + options = buildS3Options(true, project_id+"/"+doc._id) + request.get options, (err, res, lines)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong unarchiving doc from aws" + cb(err) + MongoManager.upsertIntoDocCollection project_id, doc._id.toString(), lines, (error) -> + return cb(error) if error? + cb() + + async.series jobs, callback + + buildS3Options = (content, key)-> return { aws: diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 352483fbfc..ef73297b90 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -13,9 +13,11 @@ module.exports = MongoManager = update = $set:{} $inc:{} + $unset:{} update.$set["lines"] = lines update.$set["project_id"] = ObjectId(project_id) update.$inc["rev"] = 1 #on new docs being created this will set the rev to 1 + update.$unset["inS3"] = true db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback @@ -25,3 +27,12 @@ module.exports = MongoManager = update.$set["deleted"] = true db.docs.update _id: ObjectId(doc_id), update, (err)-> callback(err) + + markDocAsArchived: (doc_id, callback)-> + update = + $set: {} + $unset: {} + update.$set["inS3"] = true + update.$unset["lines"] = true + db.docs.update _id: doc_id, update, (err)-> + callback(err) \ No newline at end of file diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index d708b56ce2..4a16b05c2a 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -16,4 +16,5 @@ module.exports = # user_files: "" # s3: # key: "" - # secret: "" \ No newline at end of file + # secret: "" + \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index f55e39099c..9569f97cda 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -33,4 +33,14 @@ describe "Archiving all docs", -> it "should archive all the docs", (done) -> DocstoreClient.archiveAllDoc @project_id, (error, res) => res.statusCode.should.equal 204 - done() \ No newline at end of file + done() + + it "should unarchive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + DocstoreClient.getAllDocs @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.lines.should.deep.equal @docs[i].lines + done() + From 19f1a9ad82457eea53936f3e49aee3dd1980f3af Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 2 Jun 2015 10:59:35 +0100 Subject: [PATCH 050/349] changed style of async jobs to map to use underscore which is like we use in the rest of the stack. Also removed a few => binds which are not needed --- .../docstore/app/coffee/DocManager.coffee | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 205128a72f..aae71bc2d3 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -70,18 +70,17 @@ module.exports = DocManager = else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") - jobs = for doc in docs - do (doc) => - (cb) => - logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" - options = buildS3Options(doc.lines, project_id+"/"+doc._id) - request.put options, (err, res)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong archiving doc in aws" - cb(err) - MongoManager.markDocAsArchived doc._id, (error) -> - return cb(error) if error? - cb() + jobs = _.map docs, (doc) -> + (cb)-> + logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" + options = buildS3Options(doc.lines, project_id+"/"+doc._id) + request.put options, (err, res)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong archiving doc in aws" + cb(err) + MongoManager.markDocAsArchived doc._id, (error) -> + return cb(error) if error? + cb() async.series jobs, callback @@ -92,21 +91,20 @@ module.exports = DocManager = else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") - jobs = for doc in docs - do (doc) => + jobs = _.map docs, (doc) -> + (cb)-> if !doc.inS3? - (cb) => cb() + return cb() else - (cb) => - logger.log project_id: project_id, doc_id: doc._id, "getting doc from s3" - options = buildS3Options(true, project_id+"/"+doc._id) - request.get options, (err, res, lines)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong unarchiving doc from aws" - cb(err) - MongoManager.upsertIntoDocCollection project_id, doc._id.toString(), lines, (error) -> - return cb(error) if error? - cb() + logger.log project_id: project_id, doc_id: doc._id, "getting doc from s3" + options = buildS3Options(true, project_id+"/"+doc._id) + request.get options, (err, res, lines)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong unarchiving doc from aws" + cb(err) + MongoManager.upsertIntoDocCollection project_id, doc._id.toString(), lines, (error) -> + return cb(error) if error? + cb() async.series jobs, callback From 60bc7bf4e1ca77329faf5c9a5bbab4ca6e6c47b2 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 2 Jun 2015 12:36:38 +0100 Subject: [PATCH 051/349] pulled logic for arching docs arpart a bit, can be moved into its own file hacked out (needs tests) the unarchiving of individual docs & doc updates --- .../docstore/app/coffee/DocManager.coffee | 61 +++++++++++-------- .../docstore/app/coffee/MongoManager.coffee | 3 + 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index aae71bc2d3..a89d83e11c 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -16,7 +16,13 @@ module.exports = DocManager = return callback(err) else if !doc? return callback new Errors.NotFoundError("No such doc: #{doc_id} in project #{project_id}") - callback null, doc + else if doc?.inS3 + DocManager.unarchiveDoc project_id, doc_id, (err)-> + if err? + return callback(err) + MongoManager.findDoc doc_id, callback + else + callback err, doc getAllDocs: (project_id, callback = (error, docs) ->) -> DocManager.unArchiveAllDocs project_id, (error) -> @@ -29,8 +35,8 @@ module.exports = DocManager = return callback(null, docs) updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> - MongoManager.findDoc doc_id, (err, doc)-> - if err? + DocManager.getDoc doc_id, (err, doc)-> + if err? and !(error instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" return callback(err) @@ -63,51 +69,54 @@ module.exports = DocManager = return callback(error) if error? callback() + + #DOC ARCHIVER archiveAllDocs: (project_id, callback = (error, docs) ->) -> MongoManager.getProjectsDocs project_id, (error, docs) -> if err? return callback(error) else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") - jobs = _.map docs, (doc) -> - (cb)-> - logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" - options = buildS3Options(doc.lines, project_id+"/"+doc._id) - request.put options, (err, res)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong archiving doc in aws" - cb(err) - MongoManager.markDocAsArchived doc._id, (error) -> - return cb(error) if error? - cb() - + (cb)-> DocManager.archiveDoc project_id, doc, cb async.series jobs, callback + + archiveDoc: (project_id, doc, callback)-> + logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" + options = buildS3Options(doc.lines, project_id+"/"+doc._id) + request.put options, (err, res)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong archiving doc in aws" + callback(err) + MongoManager.markDocAsArchived doc._id, (error) -> + return callback(error) if error? + callback() + unArchiveAllDocs: (project_id, callback = (error) ->) -> MongoManager.getProjectsDocs project_id, (error, docs) -> if err? return callback(error) else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") - jobs = _.map docs, (doc) -> (cb)-> if !doc.inS3? return cb() else - logger.log project_id: project_id, doc_id: doc._id, "getting doc from s3" - options = buildS3Options(true, project_id+"/"+doc._id) - request.get options, (err, res, lines)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong unarchiving doc from aws" - cb(err) - MongoManager.upsertIntoDocCollection project_id, doc._id.toString(), lines, (error) -> - return cb(error) if error? - cb() - + unarchiveDoc project_id, doc_id, cb async.series jobs, callback + unarchiveDoc: (project_id, doc_id, callback)-> + logger.log project_id: project_id, doc_id: doc._id, "getting doc from s3" + options = buildS3Options(true, project_id+"/"+doc._id) + request.get options, (err, res, lines)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong unarchiving doc from aws" + callback(err) + MongoManager.upsertIntoDocCollection project_id, doc._id.toString(), lines, (error) -> + return callback(error) if error? + callback() buildS3Options = (content, key)-> return { diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index ef73297b90..1f8b9ca6d8 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -34,5 +34,8 @@ module.exports = MongoManager = $unset: {} update.$set["inS3"] = true update.$unset["lines"] = true + # to ensure that the lines have not changed during the archive process + # what if we passed the lines through into the query {_id: doc_id, lines:lines} + # or more performant would be todo the rev {_id:doc_id, rev:rev} db.docs.update _id: doc_id, update, (err)-> callback(err) \ No newline at end of file From ea92f57acc7a9c80636f44b550b4a6ff452ea694 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 2 Jun 2015 12:39:49 +0100 Subject: [PATCH 052/349] point where we unset doc lines also search on doc rev to make sure the document has not been updated --- services/docstore/app/coffee/DocManager.coffee | 2 +- services/docstore/app/coffee/MongoManager.coffee | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index a89d83e11c..61cd4a1be4 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -89,7 +89,7 @@ module.exports = DocManager = if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong archiving doc in aws" callback(err) - MongoManager.markDocAsArchived doc._id, (error) -> + MongoManager.markDocAsArchived doc._id, doc.rev, (error) -> return callback(error) if error? callback() diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 1f8b9ca6d8..f33e5995ef 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -28,14 +28,12 @@ module.exports = MongoManager = db.docs.update _id: ObjectId(doc_id), update, (err)-> callback(err) - markDocAsArchived: (doc_id, callback)-> + markDocAsArchived: (doc_id, rev, callback)-> update = $set: {} $unset: {} update.$set["inS3"] = true update.$unset["lines"] = true - # to ensure that the lines have not changed during the archive process - # what if we passed the lines through into the query {_id: doc_id, lines:lines} - # or more performant would be todo the rev {_id:doc_id, rev:rev} + # to ensure that the lines have not changed during the archive process we search via the rev db.docs.update _id: doc_id, update, (err)-> callback(err) \ No newline at end of file From 86f16caeefee4abf64214a9d4493149b58556f13 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 2 Jun 2015 15:13:28 -0300 Subject: [PATCH 053/349] fix some issues --- services/docstore/app/coffee/DocManager.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 61cd4a1be4..df52a2a16b 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -35,8 +35,8 @@ module.exports = DocManager = return callback(null, docs) updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> - DocManager.getDoc doc_id, (err, doc)-> - if err? and !(error instanceof Errors.NotFoundError) + DocManager.getDoc project_id, doc_id, (err, doc)-> + if err? and !(err instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" return callback(err) @@ -104,17 +104,17 @@ module.exports = DocManager = if !doc.inS3? return cb() else - unarchiveDoc project_id, doc_id, cb + DocManager.unarchiveDoc project_id, doc._id, cb async.series jobs, callback unarchiveDoc: (project_id, doc_id, callback)-> - logger.log project_id: project_id, doc_id: doc._id, "getting doc from s3" - options = buildS3Options(true, project_id+"/"+doc._id) + logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" + options = buildS3Options(true, project_id+"/"+doc_id) request.get options, (err, res, lines)-> if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong unarchiving doc from aws" callback(err) - MongoManager.upsertIntoDocCollection project_id, doc._id.toString(), lines, (error) -> + MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (error) -> return callback(error) if error? callback() From ddd26798f18616970c0475b829eef121da9f55aa Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 2 Jun 2015 15:55:22 -0300 Subject: [PATCH 054/349] refactoring s3 filter in router --- services/docstore/app.coffee | 4 +- .../docstore/app/coffee/DocArchive.coffee | 71 +++++++++++++++++++ .../docstore/app/coffee/DocManager.coffee | 67 +---------------- .../docstore/app/coffee/HttpController.coffee | 3 +- .../docstore/app/coffee/MongoManager.coffee | 12 +++- 5 files changed, 89 insertions(+), 68 deletions(-) create mode 100644 services/docstore/app/coffee/DocArchive.coffee diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 8609d79e8f..5f45f5a8c3 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -20,7 +20,9 @@ app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc -app.get '/project/:project_id/archive', HttpController.archiveAllDocs + +if Settings.filestore.backend == "s3" + app.get '/project/:project_id/archive', HttpController.archiveAllDocs app.get '/status', (req, res)-> res.send('docstore is alive') diff --git a/services/docstore/app/coffee/DocArchive.coffee b/services/docstore/app/coffee/DocArchive.coffee new file mode 100644 index 0000000000..25f4d02506 --- /dev/null +++ b/services/docstore/app/coffee/DocArchive.coffee @@ -0,0 +1,71 @@ +MongoManager = require "./MongoManager" +Errors = require "./Errors" +logger = require "logger-sharelatex" +_ = require "underscore" +async = require "async" +settings = require("settings-sharelatex") +request = require("request") +crypto = require("crypto") +thirtySeconds = 30 * 1000 + +module.exports = DocArchive = + + archiveAllDocs: (project_id, callback = (error, docs) ->) -> + MongoManager.getProjectsDocs project_id, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + jobs = _.map docs, (doc) -> + (cb)-> DocArchive.archiveDoc project_id, doc, cb + async.series jobs, callback + + + archiveDoc: (project_id, doc, callback)-> + logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" + options = buildS3Options(doc.lines, project_id+"/"+doc._id) + request.put options, (err, res)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong archiving doc in aws" + callback(err) + MongoManager.markDocAsArchived doc._id, doc.rev, (error) -> + return callback(error) if error? + callback() + + unArchiveAllDocs: (project_id, callback = (error) ->) -> + MongoManager.getArchivedProjectDocs project_id, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + jobs = _.map docs, (doc) -> + (cb)-> + if !doc.inS3? + return cb() + else + DocArchive.unarchiveDoc project_id, doc._id, cb + async.series jobs, callback + + unarchiveDoc: (project_id, doc_id, callback)-> + logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" + options = buildS3Options(true, project_id+"/"+doc_id) + request.get options, (err, res, lines)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, "something went wrong unarchiving doc from aws" + callback(err) + MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (error) -> + return callback(error) if error? + callback() + +buildS3Options = (content, key)-> + return { + aws: + key: settings.filestore.s3.key + secret: settings.filestore.s3.secret + bucket: settings.filestore.stores.user_files + timeout: thirtySeconds + json: content + #headers: + # 'content-md5': crypto.createHash("md5").update(content).digest("hex") + uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" + } \ No newline at end of file diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index df52a2a16b..5ffad57b9d 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -7,6 +7,7 @@ settings = require("settings-sharelatex") request = require("request") crypto = require("crypto") thirtySeconds = 30 * 1000 +DocArchive = require "./DocArchive" module.exports = DocManager = @@ -17,7 +18,7 @@ module.exports = DocManager = else if !doc? return callback new Errors.NotFoundError("No such doc: #{doc_id} in project #{project_id}") else if doc?.inS3 - DocManager.unarchiveDoc project_id, doc_id, (err)-> + DocArchive.unarchiveDoc project_id, doc_id, (err)-> if err? return callback(err) MongoManager.findDoc doc_id, callback @@ -25,7 +26,7 @@ module.exports = DocManager = callback err, doc getAllDocs: (project_id, callback = (error, docs) ->) -> - DocManager.unArchiveAllDocs project_id, (error) -> + DocArchive.unArchiveAllDocs project_id, (error) -> MongoManager.getProjectsDocs project_id, (error, docs) -> if err? return callback(error) @@ -68,65 +69,3 @@ module.exports = DocManager = MongoManager.markDocAsDeleted doc_id, (error) -> return callback(error) if error? callback() - - - #DOC ARCHIVER - archiveAllDocs: (project_id, callback = (error, docs) ->) -> - MongoManager.getProjectsDocs project_id, (error, docs) -> - if err? - return callback(error) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - jobs = _.map docs, (doc) -> - (cb)-> DocManager.archiveDoc project_id, doc, cb - async.series jobs, callback - - - archiveDoc: (project_id, doc, callback)-> - logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" - options = buildS3Options(doc.lines, project_id+"/"+doc._id) - request.put options, (err, res)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong archiving doc in aws" - callback(err) - MongoManager.markDocAsArchived doc._id, doc.rev, (error) -> - return callback(error) if error? - callback() - - unArchiveAllDocs: (project_id, callback = (error) ->) -> - MongoManager.getProjectsDocs project_id, (error, docs) -> - if err? - return callback(error) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - jobs = _.map docs, (doc) -> - (cb)-> - if !doc.inS3? - return cb() - else - DocManager.unarchiveDoc project_id, doc._id, cb - async.series jobs, callback - - unarchiveDoc: (project_id, doc_id, callback)-> - logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" - options = buildS3Options(true, project_id+"/"+doc_id) - request.get options, (err, res, lines)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong unarchiving doc from aws" - callback(err) - MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (error) -> - return callback(error) if error? - callback() - -buildS3Options = (content, key)-> - return { - aws: - key: settings.filestore.s3.key - secret: settings.filestore.s3.secret - bucket: settings.filestore.stores.user_files - timeout: thirtySeconds - json: content - #headers: - # 'content-md5': crypto.createHash("md5").update(content).digest("hex") - uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" - } diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 1c790ac9ba..86d2dec470 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -1,5 +1,6 @@ DocManager = require "./DocManager" logger = require "logger-sharelatex" +DocArchive = require "./DocArchive" module.exports = HttpController = getDoc: (req, res, next = (error) ->) -> @@ -82,6 +83,6 @@ module.exports = HttpController = archiveAllDocs: (req, res, next = (error) ->) -> project_id = req.params.project_id logger.log project_id: project_id, "archiving all docs" - DocManager.archiveAllDocs project_id, (error) -> + DocArchive.archiveAllDocs project_id, (error) -> return next(error) if error? res.send 204 diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index f33e5995ef..b454214ff1 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -9,6 +9,12 @@ module.exports = MongoManager = getProjectsDocs: (project_id, callback)-> db.docs.find project_id: ObjectId(project_id.toString()), {}, callback + getArchivedProjectDocs: (project_id, callback)-> + query = + project_id: ObjectId(project_id.toString()) + inS3: true + db.docs.find query, {}, callback + upsertIntoDocCollection: (project_id, doc_id, lines, callback)-> update = $set:{} @@ -34,6 +40,8 @@ module.exports = MongoManager = $unset: {} update.$set["inS3"] = true update.$unset["lines"] = true - # to ensure that the lines have not changed during the archive process we search via the rev - db.docs.update _id: doc_id, update, (err)-> + query = + _id: doc_id + rev: rev + db.docs.update query, update, (err)-> callback(err) \ No newline at end of file From 5c31e8006286a130c37cbec721166fa656299a9b Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 2 Jun 2015 16:29:32 -0300 Subject: [PATCH 055/349] more refactoring --- services/docstore/app.coffee | 2 +- ...rchive.coffee => DocArchiveManager.coffee} | 0 .../docstore/app/coffee/DocManager.coffee | 2 +- .../docstore/app/coffee/HttpController.coffee | 2 +- .../acceptance/coffee/ArchiveDocsTests.coffee | 71 ++++++++++--------- 5 files changed, 40 insertions(+), 37 deletions(-) rename services/docstore/app/coffee/{DocArchive.coffee => DocArchiveManager.coffee} (100%) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 5f45f5a8c3..3c3a35d213 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -21,7 +21,7 @@ app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc -if Settings.filestore.backend == "s3" +if Settings.filestore?.backend == "s3" app.get '/project/:project_id/archive', HttpController.archiveAllDocs app.get '/status', (req, res)-> diff --git a/services/docstore/app/coffee/DocArchive.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee similarity index 100% rename from services/docstore/app/coffee/DocArchive.coffee rename to services/docstore/app/coffee/DocArchiveManager.coffee diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 5ffad57b9d..85beac7031 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -7,7 +7,7 @@ settings = require("settings-sharelatex") request = require("request") crypto = require("crypto") thirtySeconds = 30 * 1000 -DocArchive = require "./DocArchive" +DocArchive = require "./DocArchiveManager" module.exports = DocManager = diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 86d2dec470..77d129811d 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -1,6 +1,6 @@ DocManager = require "./DocManager" logger = require "logger-sharelatex" -DocArchive = require "./DocArchive" +DocArchive = require "./DocArchiveManager" module.exports = HttpController = getDoc: (req, res, next = (error) ->) -> diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 9569f97cda..7b886bec9c 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -3,44 +3,47 @@ chai = require("chai") chai.should() {ObjectId} = require "mongojs" async = require "async" +Settings = require("settings-sharelatex") DocstoreClient = require "./helpers/DocstoreClient" -describe "Archiving all docs", -> - beforeEach (done) -> - @project_id = ObjectId() - @docs = [{ - _id: ObjectId() - lines: ["one", "two", "three"] - rev: 2 - }, { - _id: ObjectId() - lines: ["aaa", "bbb", "ccc"] - rev: 4 - }, { - _id: ObjectId() - lines: ["111", "222", "333"] - rev: 6 - }] - jobs = for doc in @docs - do (doc) => - (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> - doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback - async.series jobs, done +if Settings.filestore?.backend == "s3" - it "should archive all the docs", (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, res) => - res.statusCode.should.equal 204 - done() + describe "Archiving all docs", -> + beforeEach (done) -> + @project_id = ObjectId() + @docs = [{ + _id: ObjectId() + lines: ["one", "two", "three"] + rev: 2 + }, { + _id: ObjectId() + lines: ["aaa", "bbb", "ccc"] + rev: 4 + }, { + _id: ObjectId() + lines: ["111", "222", "333"] + rev: 6 + }] + jobs = for doc in @docs + do (doc) => + (callback) => + DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + doc.lines[0] = doc.lines[0]+" added" + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback + async.series jobs, done - it "should unarchive all the docs", (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, res) => - DocstoreClient.getAllDocs @project_id, (error, res, docs) => - throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs - doc.lines.should.deep.equal @docs[i].lines + it "should archive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + res.statusCode.should.equal 204 done() + it "should unarchive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + DocstoreClient.getAllDocs @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.lines.should.deep.equal @docs[i].lines + done() + From 6add9a0da75706d9c4e9da1deba60d40034be21d Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 2 Jun 2015 17:12:11 -0300 Subject: [PATCH 056/349] init unit tests --- .../test/unit/coffee/DocArchiveManager.coffee | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 services/docstore/test/unit/coffee/DocArchiveManager.coffee diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee new file mode 100644 index 0000000000..f00fb11c69 --- /dev/null +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -0,0 +1,70 @@ +assert = require("chai").assert +sinon = require('sinon') +chai = require('chai') +should = chai.should() +expect = chai.expect +modulePath = "../../../app/js/DocArchiveManager.js" +SandboxedModule = require('sandboxed-module') +ObjectId = require("mongojs").ObjectId +Errors = require "../../../app/js/Errors" + +describe "DocArchiveManager", -> + + beforeEach -> + + @settings = + filestore: + backend: "s3" + s3: + secret: "secret" + key: "this_key" + stores: + user_files:"sl_user_files" + + @request = + put: sinon.stub().callsArgWith(1, null, statusCode:200) + + @MongoManager = + markDocAsArchived: sinon.stub().callsArgWith(2, null) + upsertIntoDocCollection: sinon.stub() + + @DocArchiveManager = SandboxedModule.require modulePath, requires: + "settings-sharelatex": @settings + "./MongoManager": @MongoManager + "request": @request + "logger-sharelatex": + log:-> + err:-> + + @key = "my/key" + @bucketName = "my-bucket" + @error = "my errror" + + @docs = [{ + _id: ObjectId() + lines: ["one", "two", "three"] + rev: 2 + }, { + _id: ObjectId() + lines: ["aaa", "bbb", "ccc"] + rev: 4 + }, { + _id: ObjectId() + lines: ["111", "222", "333"] + rev: 6 + }] + + @project_id = ObjectId().toString() + @callback = sinon.stub() + @stubbedError = new Error("blew up") + + describe "archiveDoc", -> + + it "should use correct options", (done)-> + @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> + opts = @request.put.args[0][0] + assert.deepEqual(opts.aws, {key:@settings.filestore.s3.key, secret:@settings.filestore.s3.secret, bucket:@settings.filestore.stores.user_files}) + opts.json.should.equal @docs[0].lines + opts.timeout.should.equal (30*1000) + opts.uri.should.equal "https://#{@settings.filestore.stores.user_files}.s3.amazonaws.com/#{@project_id}/#{@docs[0]._id}" + done() \ No newline at end of file From 0cd21204300a71fb59c6f00710d4c5ea899eb06f Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 2 Jun 2015 18:13:16 -0300 Subject: [PATCH 057/349] more unit tests for archive feature --- .../app/coffee/DocArchiveManager.coffee | 8 +- .../test/unit/coffee/DocArchiveManager.coffee | 149 +++++++++++++++--- .../test/unit/coffee/DocManagerTests.coffee | 3 + 3 files changed, 133 insertions(+), 27 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 25f4d02506..8c24237983 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -12,7 +12,7 @@ module.exports = DocArchive = archiveAllDocs: (project_id, callback = (error, docs) ->) -> MongoManager.getProjectsDocs project_id, (error, docs) -> - if err? + if error? return callback(error) else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") @@ -27,14 +27,14 @@ module.exports = DocArchive = request.put options, (err, res)-> if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong archiving doc in aws" - callback(err) + return callback(err) MongoManager.markDocAsArchived doc._id, doc.rev, (error) -> return callback(error) if error? callback() unArchiveAllDocs: (project_id, callback = (error) ->) -> MongoManager.getArchivedProjectDocs project_id, (error, docs) -> - if err? + if error? return callback(error) else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") @@ -52,7 +52,7 @@ module.exports = DocArchive = request.get options, (err, res, lines)-> if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong unarchiving doc from aws" - callback(err) + return callback(err) MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (error) -> return callback(error) if error? callback() diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index f00fb11c69..a2c9a1d4f9 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -22,13 +22,33 @@ describe "DocArchiveManager", -> user_files:"sl_user_files" @request = - put: sinon.stub().callsArgWith(1, null, statusCode:200) + put: {} + get: {} + + @docs = [{ + _id: ObjectId() + lines: ["one", "two", "three"] + rev: 2 + inS3: true + }, { + _id: ObjectId() + lines: ["aaa", "bbb", "ccc"] + rev: 4 + inS3: true + }, { + _id: ObjectId() + lines: ["111", "222", "333"] + rev: 6 + inS3: true + }] @MongoManager = markDocAsArchived: sinon.stub().callsArgWith(2, null) - upsertIntoDocCollection: sinon.stub() + upsertIntoDocCollection: sinon.stub().callsArgWith(3, null) + getProjectsDocs: sinon.stub().callsArgWith(1, null, @docs) + getArchivedProjectDocs: sinon.stub().callsArgWith(1, null, @docs) - @DocArchiveManager = SandboxedModule.require modulePath, requires: + @requires = "settings-sharelatex": @settings "./MongoManager": @MongoManager "request": @request @@ -36,35 +56,118 @@ describe "DocArchiveManager", -> log:-> err:-> - @key = "my/key" - @bucketName = "my-bucket" @error = "my errror" - - @docs = [{ - _id: ObjectId() - lines: ["one", "two", "three"] - rev: 2 - }, { - _id: ObjectId() - lines: ["aaa", "bbb", "ccc"] - rev: 4 - }, { - _id: ObjectId() - lines: ["111", "222", "333"] - rev: 6 - }] - @project_id = ObjectId().toString() - @callback = sinon.stub() - @stubbedError = new Error("blew up") + @stubbedError = new Errors.NotFoundError("blew up") describe "archiveDoc", -> it "should use correct options", (done)-> + @request.put = sinon.stub().callsArgWith(1, null, statusCode:200) + @requires["request"] = @request + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> opts = @request.put.args[0][0] assert.deepEqual(opts.aws, {key:@settings.filestore.s3.key, secret:@settings.filestore.s3.secret, bucket:@settings.filestore.stores.user_files}) opts.json.should.equal @docs[0].lines opts.timeout.should.equal (30*1000) opts.uri.should.equal "https://#{@settings.filestore.stores.user_files}.s3.amazonaws.com/#{@project_id}/#{@docs[0]._id}" - done() \ No newline at end of file + done() + + it "should return the error", (done)-> + @request.put = sinon.stub().callsArgWith(1, @error, {}) + @requires["request"] = @request + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> + err.should.equal @error + done() + + describe "unarchiveDoc", -> + + it "should use correct options", (done)-> + @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, @docs[0].lines) + @requires["request"] = @request + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.unarchiveDoc @project_id, @docs[0]._id, (err)=> + opts = @request.get.args[0][0] + assert.deepEqual(opts.aws, {key:@settings.filestore.s3.key, secret:@settings.filestore.s3.secret, bucket:@settings.filestore.stores.user_files}) + opts.json.should.equal true + opts.timeout.should.equal (30*1000) + opts.uri.should.equal "https://#{@settings.filestore.stores.user_files}.s3.amazonaws.com/#{@project_id}/#{@docs[0]._id}" + done() + + it "should return the error", (done)-> + @request.get = sinon.stub().callsArgWith(1, @error, {}, {}) + @requires["request"] = @request + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.unarchiveDoc @project_id, @docs[0], (err)=> + err.should.equal @error + done() + + describe "archiveAllDocs", -> + + it "should archive all project docs", (done)-> + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @docs) + @requires["./MongoManager"] = @MongoManager + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) + + @DocArchiveManager.archiveAllDocs @project_id, (err)=> + for doc in @docs + @DocArchiveManager.archiveDoc.calledWith(@project_id, doc).should.equal true + should.not.exist err + done() + + it "should return error if have no docs", (done)-> + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null) + @requires["./MongoManager"] = @MongoManager + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.archiveAllDocs @project_id, (err)=> + should.exist err + done() + + it "should return the error", (done)-> + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, @error, null) + @requires["./MongoManager"] = @MongoManager + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.archiveAllDocs @project_id, (err)=> + err.should.equal @error + done() + + describe "unArchiveAllDocs", -> + + it "should unarchive all inS3 docs", (done)-> + @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, @docs) + @requires["./MongoManager"] = @MongoManager + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + @DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null) + + @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> + for doc in @docs + @DocArchiveManager.unarchiveDoc.calledWith(@project_id, doc._id).should.equal true + should.not.exist err + done() + + it "should return error if have no docs", (done)-> + @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, null) + @requires["./MongoManager"] = @MongoManager + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> + should.exist err + done() + + it "should return the error", (done)-> + @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, @error, null) + @requires["./MongoManager"] = @MongoManager + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> + err.should.equal @error + done() diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index ab28058791..1aef029ddf 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -11,6 +11,7 @@ describe "DocManager", -> beforeEach -> @DocManager = SandboxedModule.require modulePath, requires: "./MongoManager": @MongoManager = {} + "./DocArchiveManager": @DocArchiveManager = {} "logger-sharelatex": @logger = log: sinon.stub() warn:-> @@ -74,6 +75,7 @@ describe "DocManager", -> beforeEach -> @docs = [{ _id: @doc_id, lines: ["mock-lines"] }] @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @docs) + @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, @docs) @DocManager.getAllDocs @project_id, @callback it "should get the project from the database", -> @@ -87,6 +89,7 @@ describe "DocManager", -> describe "when there are no docs for the project", -> beforeEach -> @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null) + @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, null) @DocManager.getAllDocs @project_id, @callback it "should return a NotFoundError", -> From a26320013deb4f5a0956250d7aad76ea8ab7f6f1 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 2 Jun 2015 19:24:45 -0300 Subject: [PATCH 058/349] more acceptance tests --- .../app/coffee/DocArchiveManager.coffee | 28 ++++----- .../acceptance/coffee/ArchiveDocsTests.coffee | 59 +++++++++++++++---- .../coffee/helpers/DocstoreClient.coffee | 4 ++ .../unit/coffee/HttpControllerTests.coffee | 18 ++++++ 4 files changed, 82 insertions(+), 27 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 8c24237983..77cc78df67 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -23,7 +23,7 @@ module.exports = DocArchive = archiveDoc: (project_id, doc, callback)-> logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" - options = buildS3Options(doc.lines, project_id+"/"+doc._id) + options = DocArchive.buildS3Options(doc.lines, project_id+"/"+doc._id) request.put options, (err, res)-> if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong archiving doc in aws" @@ -48,7 +48,7 @@ module.exports = DocArchive = unarchiveDoc: (project_id, doc_id, callback)-> logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" - options = buildS3Options(true, project_id+"/"+doc_id) + options = DocArchive.buildS3Options(true, project_id+"/"+doc_id) request.get options, (err, res, lines)-> if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong unarchiving doc from aws" @@ -57,15 +57,15 @@ module.exports = DocArchive = return callback(error) if error? callback() -buildS3Options = (content, key)-> - return { - aws: - key: settings.filestore.s3.key - secret: settings.filestore.s3.secret - bucket: settings.filestore.stores.user_files - timeout: thirtySeconds - json: content - #headers: - # 'content-md5': crypto.createHash("md5").update(content).digest("hex") - uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" - } \ No newline at end of file + buildS3Options: (content, key)-> + return { + aws: + key: settings.filestore.s3.key + secret: settings.filestore.s3.secret + bucket: settings.filestore.stores.user_files + timeout: thirtySeconds + json: content + #headers: + # 'content-md5': crypto.createHash("md5").update(content).digest("hex") + uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" + } \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 7b886bec9c..e961ecce95 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -1,7 +1,7 @@ sinon = require "sinon" chai = require("chai") -chai.should() -{ObjectId} = require "mongojs" +should = chai.should() +{db, ObjectId} = require "../../../app/js/mongojs" async = require "async" Settings = require("settings-sharelatex") @@ -11,6 +11,7 @@ if Settings.filestore?.backend == "s3" describe "Archiving all docs", -> beforeEach (done) -> + @callback = sinon.stub() @project_id = ObjectId() @docs = [{ _id: ObjectId() @@ -33,17 +34,49 @@ if Settings.filestore?.backend == "s3" DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback async.series jobs, done - it "should archive all the docs", (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, res) => - res.statusCode.should.equal 204 - done() + afterEach (done) -> + db.docs.remove({project_id: @project_id}, done) - it "should unarchive all the docs", (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, res) => - DocstoreClient.getAllDocs @project_id, (error, res, docs) => - throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs - doc.lines.should.deep.equal @docs[i].lines + describe "Archiving all docs", -> + beforeEach (done) -> + + DocstoreClient.archiveAllDoc @project_id, (error, @res) => done() + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() + + it "should set inS3 and unset lines in each doc", (done) -> + + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done + + it "should be able get the same docs back", (done) -> + + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done + + + describe "Unarchiving all docs", -> + + it "should unarchive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + DocstoreClient.getAllDocs @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.lines.should.deep.equal @docs[i].lines + done() + diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 989a2ce0e7..74acf1134a 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -1,6 +1,7 @@ request = require("request").defaults(jar: false) {db, ObjectId} = require("../../../../app/js/mongojs") settings = require("settings-sharelatex") +DocArchiveManager = require("../../../../app/js/DocArchiveManager.js") module.exports = DocstoreClient = @@ -45,3 +46,6 @@ module.exports = DocstoreClient = url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/archive" }, callback + getS3Doc: (project_id, doc_id, callback = (error, res, body) ->) -> + options = DocArchiveManager.buildS3Options(true, project_id+"/"+doc_id) + request.get options, callback diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 66f82f5b7b..c76ced9696 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -11,6 +11,7 @@ describe "HttpController", -> beforeEach -> @HttpController = SandboxedModule.require modulePath, requires: "./DocManager": @DocManager = {} + "./DocArchiveManager": @DocArchiveManager = {} "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } @res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() } @req = { query:{}} @@ -247,3 +248,20 @@ describe "HttpController", -> @res.send .calledWith(204) .should.equal true + + describe "archiveAllDocs", -> + beforeEach -> + @req.params = + project_id: @project_id + @DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1) + @HttpController.archiveAllDocs @req, @res, @next + + it "should archive the project", -> + @DocArchiveManager.archiveAllDocs + .calledWith(@project_id) + .should.equal true + + it "should return a 204 (No Content)", -> + @res.send + .calledWith(204) + .should.equal true \ No newline at end of file From 5ba14522da36ca0edf07f3a2adf8f2505bec7b6c Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Tue, 2 Jun 2015 20:08:50 -0300 Subject: [PATCH 059/349] handling error --- .../app/coffee/DocArchiveManager.coffee | 4 +- .../docstore/config/settings.defaults.coffee | 2 +- .../acceptance/coffee/ArchiveDocsTests.coffee | 90 +++++++++++-------- 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 77cc78df67..f04e1b125a 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -27,7 +27,7 @@ module.exports = DocArchive = request.put options, (err, res)-> if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong archiving doc in aws" - return callback(err) + return callback new Errors.NotFoundError("Error in S3 request") MongoManager.markDocAsArchived doc._id, doc.rev, (error) -> return callback(error) if error? callback() @@ -52,7 +52,7 @@ module.exports = DocArchive = request.get options, (err, res, lines)-> if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong unarchiving doc from aws" - return callback(err) + return callback new Errors.NotFoundError("Error in S3 request") MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (error) -> return callback(error) if error? callback() diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 4a16b05c2a..1af857e4f7 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -17,4 +17,4 @@ module.exports = # s3: # key: "" # secret: "" - \ No newline at end of file + # fail: false \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index e961ecce95..4e27dc6302 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -37,46 +37,58 @@ if Settings.filestore?.backend == "s3" afterEach (done) -> db.docs.remove({project_id: @project_id}, done) - describe "Archiving all docs", -> - beforeEach (done) -> + if !Settings.filestore?.fail - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - done() + describe "Archiving all docs", -> + beforeEach (done) -> - it "should archive all the docs", (done) -> - @res.statusCode.should.equal 204 - done() - - it "should set inS3 and unset lines in each doc", (done) -> - - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => - should.not.exist doc.lines - doc.inS3.should.equal true - callback() - async.series jobs, done - - it "should be able get the same docs back", (done) -> - - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() - callback() - async.series jobs, done - - - describe "Unarchiving all docs", -> - - it "should unarchive all the docs", (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, res) => - DocstoreClient.getAllDocs @project_id, (error, res, docs) => - throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs - doc.lines.should.deep.equal @docs[i].lines + DocstoreClient.archiveAllDoc @project_id, (error, @res) => done() + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() + + it "should set inS3 and unset lines in each doc", (done) -> + + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done + + it "should be able get the same docs back", (done) -> + + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done + + + describe "Unarchiving all docs", -> + + it "should unarchive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + DocstoreClient.getAllDocs @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.lines.should.deep.equal @docs[i].lines + done() + + # set fail to true and also run the docstore service with a denied config + if Settings.filestore?.fail + + describe "Test S3 fail request", -> + + it "should return a 404", (done) -> + + DocstoreClient.archiveAllDoc @project_id, (error, res) => + res.statusCode.should.equal 404 + done() From aa23c1da56f0c40591671af7a3ea5936c06620f4 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 Jun 2015 11:45:47 -0300 Subject: [PATCH 060/349] md5 check for doc lines --- services/docstore/app/coffee/DocArchiveManager.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index f04e1b125a..206dc929f5 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -25,9 +25,14 @@ module.exports = DocArchive = logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" options = DocArchive.buildS3Options(doc.lines, project_id+"/"+doc._id) request.put options, (err, res)-> + md5lines = crypto.createHash("md5").update(JSON.stringify(doc.lines)).digest("hex") + md5response = res.headers.etag.toString().replace(/\"/g, '') if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong archiving doc in aws" return callback new Errors.NotFoundError("Error in S3 request") + if md5lines != md5response + logger.err responseMD5:md5response, linesMD5:md5lines, "error in response md5 from s3" + return callback new Errors.NotFoundError("Error in S3 md5 response") MongoManager.markDocAsArchived doc._id, doc.rev, (error) -> return callback(error) if error? callback() @@ -66,6 +71,6 @@ module.exports = DocArchive = timeout: thirtySeconds json: content #headers: - # 'content-md5': crypto.createHash("md5").update(content).digest("hex") + # 'content-md5': crypto.createHash("md5").update(JSON.stringify(content)).digest("hex") uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" } \ No newline at end of file From 9a68bfb39328ff52b784fc29f291f8cdfdb3e7a7 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 Jun 2015 12:00:08 -0300 Subject: [PATCH 061/349] fix unit tests --- .../test/unit/coffee/DocArchiveManager.coffee | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index a2c9a1d4f9..dcd425138b 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -7,6 +7,7 @@ modulePath = "../../../app/js/DocArchiveManager.js" SandboxedModule = require('sandboxed-module') ObjectId = require("mongojs").ObjectId Errors = require "../../../app/js/Errors" +crypto = require("crypto") describe "DocArchiveManager", -> @@ -58,12 +59,12 @@ describe "DocArchiveManager", -> @error = "my errror" @project_id = ObjectId().toString() - @stubbedError = new Errors.NotFoundError("blew up") + @stubbedError = new Errors.NotFoundError("Error in S3 request") describe "archiveDoc", -> it "should use correct options", (done)-> - @request.put = sinon.stub().callsArgWith(1, null, statusCode:200) + @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:""}}) @requires["request"] = @request @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires @@ -75,13 +76,23 @@ describe "DocArchiveManager", -> opts.uri.should.equal "https://#{@settings.filestore.stores.user_files}.s3.amazonaws.com/#{@project_id}/#{@docs[0]._id}" done() - it "should return the error", (done)-> - @request.put = sinon.stub().callsArgWith(1, @error, {}) + it "should return no md5 error", (done)-> + @md5 = crypto.createHash("md5").update(JSON.stringify(@docs[0].lines)).digest("hex") + @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:@md5}}) @requires["request"] = @request @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> - err.should.equal @error + should.not.exist err + done() + + it "should return the error", (done)-> + @request.put = sinon.stub().callsArgWith(1, @stubbedError, {statusCode:400,headers:{etag:""}}) + @requires["request"] = @request + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + + @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> + should.exist err done() describe "unarchiveDoc", -> @@ -100,12 +111,12 @@ describe "DocArchiveManager", -> done() it "should return the error", (done)-> - @request.get = sinon.stub().callsArgWith(1, @error, {}, {}) + @request.get = sinon.stub().callsArgWith(1, @stubbedError, {}, {}) @requires["request"] = @request @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires @DocArchiveManager.unarchiveDoc @project_id, @docs[0], (err)=> - err.should.equal @error + should.exist err done() describe "archiveAllDocs", -> From 42f2afc4dda8aa31d58cf6d61b6a8f24d8e99a29 Mon Sep 17 00:00:00 2001 From: Henrique Dias Date: Wed, 3 Jun 2015 20:05:15 -0300 Subject: [PATCH 062/349] remove unarchived docs from s3 --- services/docstore/app/coffee/DocArchiveManager.coffee | 7 ++++++- .../docstore/test/unit/coffee/DocArchiveManager.coffee | 4 +++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 206dc929f5..d82067737e 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -60,7 +60,12 @@ module.exports = DocArchive = return callback new Errors.NotFoundError("Error in S3 request") MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (error) -> return callback(error) if error? - callback() + logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" + request.del options, (err, res, body)-> + if err? || res.statusCode != 204 + logger.err err:err, res:res, "something went wrong deleting doc from aws" + return callback new Errors.NotFoundError("Error in S3 request") + callback() buildS3Options: (content, key)-> return { diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index dcd425138b..33d5205e85 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -25,6 +25,7 @@ describe "DocArchiveManager", -> @request = put: {} get: {} + del: {} @docs = [{ _id: ObjectId() @@ -98,7 +99,8 @@ describe "DocArchiveManager", -> describe "unarchiveDoc", -> it "should use correct options", (done)-> - @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, @docs[0].lines) + @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, @docs[0].lines) + @request.del = sinon.stub().callsArgWith(1, null, statusCode:204, {}) @requires["request"] = @request @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires From 6e4ad90cacd4845554b2e34abfe982baf821e14b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Wed, 10 Jun 2015 15:37:06 +0100 Subject: [PATCH 063/349] bumped mongojs version --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 16da100cfd..21fe9104d6 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -11,7 +11,7 @@ "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.0.0", "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.0.0", - "mongojs": "0.9.11", + "mongojs": "0.18.2", "express": "~4.1.1", "underscore": "~1.6.0", "body-parser": "~1.0.2", From aa599b0d9071ad607f3f66127c67f82d58561700 Mon Sep 17 00:00:00 2001 From: Brian Gough Date: Tue, 23 Jun 2015 13:55:33 +0100 Subject: [PATCH 064/349] added event loop monitor --- services/docstore/app.coffee | 1 + services/docstore/package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index ec9b250851..65d28b3995 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -10,6 +10,7 @@ Path = require "path" Metrics.initialize("docstore") logger.initialize("docstore") Metrics.mongodb.monitor(Path.resolve(__dirname + "/node_modules/mongojs/node_modules/mongodb"), logger) +Metrics.event_loop?.monitor(logger) app = express() diff --git a/services/docstore/package.json b/services/docstore/package.json index 21fe9104d6..fbf41400d3 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -10,7 +10,7 @@ "dependencies": { "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.0.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.0.0", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.1.0", "mongojs": "0.18.2", "express": "~4.1.1", "underscore": "~1.6.0", From 9af2c07c3bd7f2fe1d961b7ea45a6377ffe1f8af Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 12:59:04 +0100 Subject: [PATCH 065/349] always add archiving root in --- services/docstore/app.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 3c3a35d213..be51abecd8 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -21,8 +21,7 @@ app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc -if Settings.filestore?.backend == "s3" - app.get '/project/:project_id/archive', HttpController.archiveAllDocs +app.get '/project/:project_id/archive', HttpController.archiveAllDocs app.get '/status', (req, res)-> res.send('docstore is alive') From 859e8a0e570178d9aa5194d0f79d5f096810f3cb Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 13:00:09 +0100 Subject: [PATCH 066/349] - deal with calling archive twice on same project - clean up unit tests - change s3 keys - use err not error --- .../app/coffee/DocArchiveManager.coffee | 49 ++++---- .../acceptance/coffee/ArchiveDocsTests.coffee | 112 +++++++++++------- .../test/unit/coffee/DocArchiveManager.coffee | 107 ++++++++--------- 3 files changed, 143 insertions(+), 125 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index d82067737e..9c11192e51 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -10,14 +10,18 @@ thirtySeconds = 30 * 1000 module.exports = DocArchive = - archiveAllDocs: (project_id, callback = (error, docs) ->) -> - MongoManager.getProjectsDocs project_id, (error, docs) -> - if error? - return callback(error) + archiveAllDocs: (project_id, callback = (err, docs) ->) -> + MongoManager.getProjectsDocs project_id, (err, docs) -> + if err? + return callback(err) else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") jobs = _.map docs, (doc) -> - (cb)-> DocArchive.archiveDoc project_id, doc, cb + (cb)-> + if doc.inS3 + return cb() + else + DocArchive.archiveDoc project_id, doc, cb async.series jobs, callback @@ -25,22 +29,23 @@ module.exports = DocArchive = logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" options = DocArchive.buildS3Options(doc.lines, project_id+"/"+doc._id) request.put options, (err, res)-> + if err? || res.statusCode != 200 + logger.err err:err, res:res, project_id:project_id, doc_id: doc._id, statusCode: res?.statusCode, "something went wrong archiving doc in aws" + return callback new Error("Error in S3 request") md5lines = crypto.createHash("md5").update(JSON.stringify(doc.lines)).digest("hex") md5response = res.headers.etag.toString().replace(/\"/g, '') - if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong archiving doc in aws" - return callback new Errors.NotFoundError("Error in S3 request") if md5lines != md5response - logger.err responseMD5:md5response, linesMD5:md5lines, "error in response md5 from s3" - return callback new Errors.NotFoundError("Error in S3 md5 response") - MongoManager.markDocAsArchived doc._id, doc.rev, (error) -> - return callback(error) if error? + logger.err responseMD5:md5response, linesMD5:md5lines, project_id:project_id, doc_id: doc._id, "err in response md5 from s3" + return callback new Error("Error in S3 md5 response") + MongoManager.markDocAsArchived doc._id, doc.rev, (err) -> + return callback(err) if err? callback() - unArchiveAllDocs: (project_id, callback = (error) ->) -> - MongoManager.getArchivedProjectDocs project_id, (error, docs) -> - if error? - return callback(error) + unArchiveAllDocs: (project_id, callback = (err) ->) -> + MongoManager.getArchivedProjectDocs project_id, (err, docs) -> + if err? + logger.err err:err, project_id:project_id, "error unarchiving all docs" + return callback(err) else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") jobs = _.map docs, (doc) -> @@ -58,8 +63,8 @@ module.exports = DocArchive = if err? || res.statusCode != 200 logger.err err:err, res:res, "something went wrong unarchiving doc from aws" return callback new Errors.NotFoundError("Error in S3 request") - MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (error) -> - return callback(error) if error? + MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (err) -> + return callback(err) if err? logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" request.del options, (err, res, body)-> if err? || res.statusCode != 204 @@ -70,12 +75,12 @@ module.exports = DocArchive = buildS3Options: (content, key)-> return { aws: - key: settings.filestore.s3.key - secret: settings.filestore.s3.secret - bucket: settings.filestore.stores.user_files + key: settings.docstore.s3.key + secret: settings.docstore.s3.secret + bucket: settings.docstore.s3.bucket timeout: thirtySeconds json: content #headers: # 'content-md5': crypto.createHash("md5").update(JSON.stringify(content)).digest("hex") - uri:"https://#{settings.filestore.stores.user_files}.s3.amazonaws.com/#{key}" + uri:"https://#{settings.docstore.s3.bucket}.s3.amazonaws.com/#{key}" } \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 4e27dc6302..545fff7a2c 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -28,7 +28,7 @@ if Settings.filestore?.backend == "s3" }] jobs = for doc in @docs do (doc) => - (callback) => + (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> doc.lines[0] = doc.lines[0]+" added" DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback @@ -37,58 +37,78 @@ if Settings.filestore?.backend == "s3" afterEach (done) -> db.docs.remove({project_id: @project_id}, done) - if !Settings.filestore?.fail - describe "Archiving all docs", -> - beforeEach (done) -> + describe "Archiving all docs", -> + beforeEach (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - done() - - it "should archive all the docs", (done) -> - @res.statusCode.should.equal 204 + DocstoreClient.archiveAllDoc @project_id, (error, @res) => done() - it "should set inS3 and unset lines in each doc", (done) -> + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => - should.not.exist doc.lines - doc.inS3.should.equal true - callback() - async.series jobs, done + it "should set inS3 and unset lines in each doc", (done) -> - it "should be able get the same docs back", (done) -> + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() - callback() - async.series jobs, done + it "should be able get the same docs back", (done) -> + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done - describe "Unarchiving all docs", -> - - it "should unarchive all the docs", (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, res) => - DocstoreClient.getAllDocs @project_id, (error, res, docs) => - throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs - doc.lines.should.deep.equal @docs[i].lines - done() - - # set fail to true and also run the docstore service with a denied config - if Settings.filestore?.fail - - describe "Test S3 fail request", -> - - it "should return a 404", (done) -> - - DocstoreClient.archiveAllDoc @project_id, (error, res) => - res.statusCode.should.equal 404 + describe "Arching all docs twice", -> + beforeEach (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + @res.statusCode.should.equal 204 + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + @res.statusCode.should.equal 204 + done() + + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() + + it "should set inS3 and unset lines in each doc", (done) -> + + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done + + it "should be able get the same docs back", (done) -> + + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done + + describe "Unarchiving all docs", -> + + it "should unarchive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + DocstoreClient.getAllDocs @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.lines.should.deep.equal @docs[i].lines done() diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index 33d5205e85..2cf47b5a71 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -14,41 +14,58 @@ describe "DocArchiveManager", -> beforeEach -> @settings = - filestore: - backend: "s3" + docstore: s3: secret: "secret" key: "this_key" - stores: - user_files:"sl_user_files" + bucket:"doc-archive-unit-test" @request = put: {} get: {} del: {} - @docs = [{ + @archivedDocs = [{ + _id: ObjectId() + inS3:true + rev: 2 + }, { + _id: ObjectId() + inS3:true + rev: 4 + }, { + _id: ObjectId() + inS3:true + rev: 6 + }] + + @mongoDocs = [{ _id: ObjectId() lines: ["one", "two", "three"] rev: 2 - inS3: true }, { _id: ObjectId() lines: ["aaa", "bbb", "ccc"] rev: 4 + }, { + _id: ObjectId() inS3: true + rev: 6 + }, { + _id: ObjectId() + inS3: true + rev: 6 }, { _id: ObjectId() lines: ["111", "222", "333"] rev: 6 - inS3: true }] @MongoManager = markDocAsArchived: sinon.stub().callsArgWith(2, null) upsertIntoDocCollection: sinon.stub().callsArgWith(3, null) - getProjectsDocs: sinon.stub().callsArgWith(1, null, @docs) - getArchivedProjectDocs: sinon.stub().callsArgWith(1, null, @docs) + getProjectsDocs: sinon.stub().callsArgWith(1, null, @mongoDocs) + getArchivedProjectDocs: sinon.stub().callsArgWith(1, null, @mongoDocs) @requires = "settings-sharelatex": @settings @@ -61,84 +78,71 @@ describe "DocArchiveManager", -> @error = "my errror" @project_id = ObjectId().toString() @stubbedError = new Errors.NotFoundError("Error in S3 request") + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires describe "archiveDoc", -> it "should use correct options", (done)-> @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:""}}) - @requires["request"] = @request - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires - - @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> + @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> opts = @request.put.args[0][0] - assert.deepEqual(opts.aws, {key:@settings.filestore.s3.key, secret:@settings.filestore.s3.secret, bucket:@settings.filestore.stores.user_files}) - opts.json.should.equal @docs[0].lines + assert.deepEqual(opts.aws, {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket}) + opts.json.should.equal @mongoDocs[0].lines opts.timeout.should.equal (30*1000) - opts.uri.should.equal "https://#{@settings.filestore.stores.user_files}.s3.amazonaws.com/#{@project_id}/#{@docs[0]._id}" + opts.uri.should.equal "https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{@mongoDocs[0]._id}" done() it "should return no md5 error", (done)-> - @md5 = crypto.createHash("md5").update(JSON.stringify(@docs[0].lines)).digest("hex") + @md5 = crypto.createHash("md5").update(JSON.stringify(@mongoDocs[0].lines)).digest("hex") @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:@md5}}) - @requires["request"] = @request - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires - - @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> + @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> should.not.exist err done() it "should return the error", (done)-> @request.put = sinon.stub().callsArgWith(1, @stubbedError, {statusCode:400,headers:{etag:""}}) - @requires["request"] = @request - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires - - @DocArchiveManager.archiveDoc @project_id, @docs[0], (err)=> + @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> should.exist err done() describe "unarchiveDoc", -> it "should use correct options", (done)-> - @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, @docs[0].lines) + @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, @mongoDocs[0].lines) @request.del = sinon.stub().callsArgWith(1, null, statusCode:204, {}) - @requires["request"] = @request - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires - - @DocArchiveManager.unarchiveDoc @project_id, @docs[0]._id, (err)=> + @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0]._id, (err)=> opts = @request.get.args[0][0] - assert.deepEqual(opts.aws, {key:@settings.filestore.s3.key, secret:@settings.filestore.s3.secret, bucket:@settings.filestore.stores.user_files}) + assert.deepEqual(opts.aws, {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket}) opts.json.should.equal true opts.timeout.should.equal (30*1000) - opts.uri.should.equal "https://#{@settings.filestore.stores.user_files}.s3.amazonaws.com/#{@project_id}/#{@docs[0]._id}" + opts.uri.should.equal "https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{@mongoDocs[0]._id}" done() it "should return the error", (done)-> @request.get = sinon.stub().callsArgWith(1, @stubbedError, {}, {}) - @requires["request"] = @request - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires - - @DocArchiveManager.unarchiveDoc @project_id, @docs[0], (err)=> + @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0], (err)=> should.exist err done() describe "archiveAllDocs", -> - it "should archive all project docs", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @docs) - @requires["./MongoManager"] = @MongoManager - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + it "should archive all project docs which are not in s3", (done)-> + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @mongoDocs) @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) @DocArchiveManager.archiveAllDocs @project_id, (err)=> - for doc in @docs - @DocArchiveManager.archiveDoc.calledWith(@project_id, doc).should.equal true + @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[0]).should.equal true + @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[1]).should.equal true + @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[4]).should.equal true + + @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[2]).should.equal false + @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[3]).should.equal false + should.not.exist err done() it "should return error if have no docs", (done)-> @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null) - @requires["./MongoManager"] = @MongoManager - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires @DocArchiveManager.archiveAllDocs @project_id, (err)=> should.exist err @@ -146,8 +150,6 @@ describe "DocArchiveManager", -> it "should return the error", (done)-> @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, @error, null) - @requires["./MongoManager"] = @MongoManager - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires @DocArchiveManager.archiveAllDocs @project_id, (err)=> err.should.equal @error @@ -156,31 +158,22 @@ describe "DocArchiveManager", -> describe "unArchiveAllDocs", -> it "should unarchive all inS3 docs", (done)-> - @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, @docs) - @requires["./MongoManager"] = @MongoManager - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, @archivedDocs) @DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null) - @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> - for doc in @docs + for doc in @archivedDocs @DocArchiveManager.unarchiveDoc.calledWith(@project_id, doc._id).should.equal true should.not.exist err done() it "should return error if have no docs", (done)-> @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, null) - @requires["./MongoManager"] = @MongoManager - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires - @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> should.exist err done() it "should return the error", (done)-> @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, @error, null) - @requires["./MongoManager"] = @MongoManager - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires - @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> err.should.equal @error done() From b8884352f6ab2289c462623a8a323250dd575f86 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 13:59:12 +0100 Subject: [PATCH 067/349] added some better error logging --- services/docstore/app/coffee/DocArchiveManager.coffee | 8 +++----- services/docstore/app/coffee/DocManager.coffee | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 9c11192e51..23bd733d3f 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -35,7 +35,7 @@ module.exports = DocArchive = md5lines = crypto.createHash("md5").update(JSON.stringify(doc.lines)).digest("hex") md5response = res.headers.etag.toString().replace(/\"/g, '') if md5lines != md5response - logger.err responseMD5:md5response, linesMD5:md5lines, project_id:project_id, doc_id: doc._id, "err in response md5 from s3" + logger.err responseMD5:md5response, linesMD5:md5lines, project_id:project_id, doc_id: doc?._id, "err in response md5 from s3" return callback new Error("Error in S3 md5 response") MongoManager.markDocAsArchived doc._id, doc.rev, (err) -> return callback(err) if err? @@ -61,14 +61,14 @@ module.exports = DocArchive = options = DocArchive.buildS3Options(true, project_id+"/"+doc_id) request.get options, (err, res, lines)-> if err? || res.statusCode != 200 - logger.err err:err, res:res, "something went wrong unarchiving doc from aws" + logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong unarchiving doc from aws" return callback new Errors.NotFoundError("Error in S3 request") MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (err) -> return callback(err) if err? logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" request.del options, (err, res, body)-> if err? || res.statusCode != 204 - logger.err err:err, res:res, "something went wrong deleting doc from aws" + logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong deleting doc from aws" return callback new Errors.NotFoundError("Error in S3 request") callback() @@ -80,7 +80,5 @@ module.exports = DocArchive = bucket: settings.docstore.s3.bucket timeout: thirtySeconds json: content - #headers: - # 'content-md5': crypto.createHash("md5").update(JSON.stringify(content)).digest("hex") uri:"https://#{settings.docstore.s3.bucket}.s3.amazonaws.com/#{key}" } \ No newline at end of file diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 85beac7031..2e215567fb 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -20,6 +20,7 @@ module.exports = DocManager = else if doc?.inS3 DocArchive.unarchiveDoc project_id, doc_id, (err)-> if err? + logger.err err:err, project_id:project_id, doc_id:doc_id, "error unarchiving doc" return callback(err) MongoManager.findDoc doc_id, callback else From ddf4692f0de7ce601779a26bf8595cb93ead52c7 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 13:59:40 +0100 Subject: [PATCH 068/349] added acceptance test for large doc ~1mb --- .../acceptance/coffee/ArchiveDocsTests.coffee | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 545fff7a2c..fa07f1abae 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -102,6 +102,44 @@ if Settings.filestore?.backend == "s3" callback() async.series jobs, done + + + describe "archiving massive document", (done)-> + beforeEach (done)-> + @timeout 1000 * 30 + quarterMegInBytes = 250000 + lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") + console.log @project_id, @docs[1]._id, "helllllo" + @docs[1].lines = [lines,lines,lines,lines] + DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, => + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + done() + + + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() + + it "should set inS3 and unset lines in each doc", (done) -> + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done + + it "should be able get the same docs back", (done) -> + + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done + describe "Unarchiving all docs", -> it "should unarchive all the docs", (done) -> From 32bf64236bc6ba82922bc01c3b0b9093e800a82e Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 14:16:40 +0100 Subject: [PATCH 069/349] fixed config to work with s3 correctly --- services/docstore/config/settings.defaults.coffee | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 1af857e4f7..e7b4046b64 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -10,11 +10,8 @@ module.exports = mongo: url: 'mongodb://127.0.0.1/sharelatex' - #filestore: - # backend: "s3" - # stores: - # user_files: "" + #docstore: # s3: # key: "" # secret: "" - # fail: false \ No newline at end of file + # bucket: "something" From ef4e437c3f9bf22b524a996780773d57843ef566 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 22:47:33 +0100 Subject: [PATCH 070/349] improve doc manager so it calls get doc recursivly --- .../docstore/app/coffee/DocManager.coffee | 2 +- .../test/unit/coffee/DocManagerTests.coffee | 27 ++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 2e215567fb..2cdfda17fb 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -22,7 +22,7 @@ module.exports = DocManager = if err? logger.err err:err, project_id:project_id, doc_id:doc_id, "error unarchiving doc" return callback(err) - MongoManager.findDoc doc_id, callback + DocManager.getDoc project_id, doc_id, callback else callback err, doc diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 1aef029ddf..64551da527 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -45,21 +45,28 @@ describe "DocManager", -> done() describe "when the doc is deleted", -> + beforeEach -> + @doc = { _id: @doc_id, lines: ["mock-lines"] } + @s3doc = { _id: @doc_id, inS3: true } + @MongoManager.findDoc = sinon.stub() + @MongoManager.findDoc.callsArgWith(1, null, @s3doc) + @MongoManager.findDoc.callsArgWith(1, null, @doc) + spy = sinon.spy @DocManager.getDoc + @DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2) + @DocManager.getDoc @project_id, @doc_id, @callback + + it "should call the DocArchive to unarchive the doc", -> + @DocArchiveManager.unarchiveDoc.calledWith(@project_id, @doc_id).should.equal true + + it "should return the doc", -> + @callback.calledWith(null, @doc).should.equal true + + describe "when the doc is in s3", -> beforeEach -> @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) @DocManager.getDoc @project_id, @doc_id, @callback - it "should try to find the doc in the docs collection", -> - @MongoManager.findDoc - .calledWith(@doc_id) - .should.equal true - - it "should return the doc", -> - @callback - .calledWith(null, @doc) - .should.equal true - describe "when the doc does not exist anywhere", -> beforeEach -> @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null) From cf07e2fec5944c051a81e647a8fdda57cada64bb Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 22:48:17 +0100 Subject: [PATCH 071/349] improve archve doc acceptence tests --- .../acceptance/coffee/ArchiveDocsTests.coffee | 233 +++++++++--------- 1 file changed, 116 insertions(+), 117 deletions(-) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index fa07f1abae..9ba21105d4 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -7,146 +7,145 @@ Settings = require("settings-sharelatex") DocstoreClient = require "./helpers/DocstoreClient" -if Settings.filestore?.backend == "s3" + +describe "Archiving all docs", -> + beforeEach (done) -> + @callback = sinon.stub() + @project_id = ObjectId() + @docs = [{ + _id: ObjectId() + lines: ["one", "two", "three"] + rev: 2 + }, { + _id: ObjectId() + lines: ["aaa", "bbb", "ccc"] + rev: 4 + }, { + _id: ObjectId() + lines: ["111", "222", "333"] + rev: 6 + }] + jobs = for doc in @docs + do (doc) => + (callback) => + DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + doc.lines[0] = doc.lines[0]+" added" + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback + async.series jobs, done + + afterEach (done) -> + db.docs.remove({project_id: @project_id}, done) + describe "Archiving all docs", -> beforeEach (done) -> - @callback = sinon.stub() - @project_id = ObjectId() - @docs = [{ - _id: ObjectId() - lines: ["one", "two", "three"] - rev: 2 - }, { - _id: ObjectId() - lines: ["aaa", "bbb", "ccc"] - rev: 4 - }, { - _id: ObjectId() - lines: ["111", "222", "333"] - rev: 6 - }] - jobs = for doc in @docs - do (doc) => - (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> - doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback - async.series jobs, done - afterEach (done) -> - db.docs.remove({project_id: @project_id}, done) - - - describe "Archiving all docs", -> - beforeEach (done) -> - - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - done() - - it "should archive all the docs", (done) -> - @res.statusCode.should.equal 204 + DocstoreClient.archiveAllDoc @project_id, (error, @res) => done() - it "should set inS3 and unset lines in each doc", (done) -> + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => - should.not.exist doc.lines - doc.inS3.should.equal true - callback() - async.series jobs, done + it "should set inS3 and unset lines in each doc", (done) -> - it "should be able get the same docs back", (done) -> + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() - callback() - async.series jobs, done + it "should be able get the same docs back", (done) -> - describe "Arching all docs twice", -> - beforeEach (done) -> + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done + + describe "Arching all docs twice", -> + beforeEach (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + @res.statusCode.should.equal 204 DocstoreClient.archiveAllDoc @project_id, (error, @res) => @res.statusCode.should.equal 204 - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - @res.statusCode.should.equal 204 - done() + done() - it "should archive all the docs", (done) -> - @res.statusCode.should.equal 204 - done() + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() - it "should set inS3 and unset lines in each doc", (done) -> + it "should set inS3 and unset lines in each doc", (done) -> - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => - should.not.exist doc.lines - doc.inS3.should.equal true - callback() - async.series jobs, done + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done - it "should be able get the same docs back", (done) -> + it "should be able get the same docs back", (done) -> - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() - callback() - async.series jobs, done + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done - describe "archiving massive document", (done)-> - beforeEach (done)-> - @timeout 1000 * 30 - quarterMegInBytes = 250000 - lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") - console.log @project_id, @docs[1]._id, "helllllo" - @docs[1].lines = [lines,lines,lines,lines] - DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, => - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - done() - + describe "archiving massive document", (done)-> + beforeEach (done)-> + @timeout 1000 * 30 + quarterMegInBytes = 250000 + lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") + console.log @project_id, @docs[1]._id, "helllllo" + @docs[1].lines = [lines,lines,lines,lines] + DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, => + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + done() + - it "should archive all the docs", (done) -> - @res.statusCode.should.equal 204 - done() + it "should archive all the docs", (done) -> + @res.statusCode.should.equal 204 + done() - it "should set inS3 and unset lines in each doc", (done) -> - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => - should.not.exist doc.lines - doc.inS3.should.equal true - callback() - async.series jobs, done + it "should set inS3 and unset lines in each doc", (done) -> + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + db.docs.findOne _id: archiveDoc._id, (error, doc) => + should.not.exist doc.lines + doc.inS3.should.equal true + callback() + async.series jobs, done - it "should be able get the same docs back", (done) -> + it "should be able get the same docs back", (done) -> - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() - callback() - async.series jobs, done + jobs = for archiveDoc in @docs + do (archiveDoc) => + (callback) => + DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => + doc.toString().should.equal archiveDoc.lines.toString() + callback() + async.series jobs, done - describe "Unarchiving all docs", -> + describe "Unarchiving all docs", -> - it "should unarchive all the docs", (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, res) => - DocstoreClient.getAllDocs @project_id, (error, res, docs) => - throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs - doc.lines.should.deep.equal @docs[i].lines - done() + it "should unarchive all the docs", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + DocstoreClient.getAllDocs @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.lines.should.deep.equal @docs[i].lines + done() From 599b9770f48045967b041bd5787b0224af5f0b24 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Thu, 13 Aug 2015 22:48:45 +0100 Subject: [PATCH 072/349] add un archive endpoint --- services/docstore/app.coffee | 3 ++- services/docstore/app/coffee/HttpController.coffee | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 96de46d4fc..3a01bead03 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -22,7 +22,8 @@ app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc -app.get '/project/:project_id/archive', HttpController.archiveAllDocs +app.post '/project/:project_id/archive', HttpController.archiveAllDocs +app.post '/project/:project_id/unarchive', HttpController.unArchiveAllDocs app.get '/status', (req, res)-> res.send('docstore is alive') diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 77d129811d..3b99b090d2 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -86,3 +86,11 @@ module.exports = HttpController = DocArchive.archiveAllDocs project_id, (error) -> return next(error) if error? res.send 204 + + unArchiveAllDocs: (req, res, next = (error) ->) -> + project_id = req.params.project_id + logger.log project_id: project_id, "unarchiving all docs" + DocArchive.unArchiveAllDocs project_id, (error) -> + return next(error) if error? + res.send 200 + From 5765b59e0ce249509a5882ed58591bb9519da73b Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 18 Aug 2015 13:31:26 +0100 Subject: [PATCH 073/349] added /deactivate and /reactivate endpoints as web will call those also fixed acceptence test --- services/docstore/app.coffee | 5 +++++ .../test/acceptance/coffee/ArchiveDocsTests.coffee | 1 - .../test/acceptance/coffee/helpers/DocstoreClient.coffee | 9 +++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 3a01bead03..6fe9d308b6 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -22,6 +22,11 @@ app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc + +app.post '/project/:project_id/deactivate', HttpController.archiveAllDocs +app.post '/project/:project_id/reactivate', HttpController.unArchiveAllDocs + +# can delete these two soon app.post '/project/:project_id/archive', HttpController.archiveAllDocs app.post '/project/:project_id/unarchive', HttpController.unArchiveAllDocs diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 9ba21105d4..dd86bc2c61 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -108,7 +108,6 @@ describe "Archiving all docs", -> @timeout 1000 * 30 quarterMegInBytes = 250000 lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") - console.log @project_id, @docs[1]._id, "helllllo" @docs[1].lines = [lines,lines,lines,lines] DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, => DocstoreClient.archiveAllDoc @project_id, (error, @res) => diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 74acf1134a..1bee3f0fdb 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -42,10 +42,15 @@ module.exports = DocstoreClient = }, callback archiveAllDoc: (project_id, callback = (error, res, body) ->) -> - request.get { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/archive" + request.post { + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/deactivate" }, callback + unArchiveAllDoc: (project_id, callback = (error, res, body) ->) -> + request.post { + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/deactivate" + }, callback + getS3Doc: (project_id, doc_id, callback = (error, res, body) ->) -> options = DocArchiveManager.buildS3Options(true, project_id+"/"+doc_id) request.get options, callback From 5dd33ea3134ff4cf0625ac3d449c68690a286849 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 18 Aug 2015 14:10:53 +0100 Subject: [PATCH 074/349] changed back to standard /archive /unarchive --- services/docstore/app.coffee | 5 ----- .../test/acceptance/coffee/helpers/DocstoreClient.coffee | 8 ++------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 6fe9d308b6..3a01bead03 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -22,11 +22,6 @@ app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc - -app.post '/project/:project_id/deactivate', HttpController.archiveAllDocs -app.post '/project/:project_id/reactivate', HttpController.unArchiveAllDocs - -# can delete these two soon app.post '/project/:project_id/archive', HttpController.archiveAllDocs app.post '/project/:project_id/unarchive', HttpController.unArchiveAllDocs diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 1bee3f0fdb..b81408b6f3 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -43,14 +43,10 @@ module.exports = DocstoreClient = archiveAllDoc: (project_id, callback = (error, res, body) ->) -> request.post { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/deactivate" - }, callback - - unArchiveAllDoc: (project_id, callback = (error, res, body) ->) -> - request.post { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/deactivate" + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/archive" }, callback + getS3Doc: (project_id, doc_id, callback = (error, res, body) ->) -> options = DocArchiveManager.buildS3Options(true, project_id+"/"+doc_id) request.get options, callback From 192b0af15a0bf17af7639bd27f9aff824ef47d55 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 1 Sep 2015 15:47:16 +0100 Subject: [PATCH 075/349] added utf-8 char which fails the archive option --- .../docstore/test/acceptance/coffee/ArchiveDocsTests.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index dd86bc2c61..50780f3c74 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -22,7 +22,7 @@ describe "Archiving all docs", -> rev: 4 }, { _id: ObjectId() - lines: ["111", "222", "333"] + lines: ["111", "222", "Antônio Sérgio"] rev: 6 }] jobs = for doc in @docs From aaa2a099f1f2ea50565a7465b0bb7039ed7808d9 Mon Sep 17 00:00:00 2001 From: Henry Oswald Date: Tue, 1 Sep 2015 16:51:10 +0100 Subject: [PATCH 076/349] change acceptance test to use big naught list of strings --- .../docstore/test/acceptance/coffee/ArchiveDocsTests.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 50780f3c74..52d62eb2c6 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -22,7 +22,7 @@ describe "Archiving all docs", -> rev: 4 }, { _id: ObjectId() - lines: ["111", "222", "Antônio Sérgio"] + lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "", "<script>alert('123');</script>", "", " ", "\">", "'>", ">", "", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "ript>alert(123)ript>", "-->", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><\\x3Cscript>javascript:alert(1) ", "'`\"><\\x00script>javascript:alert(1)", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "ABC
DEF", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "test", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "`\"'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "\"`'>", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "XXX", "javascript:alert(1)\"` `>", "", "", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] rev: 6 }] jobs = for doc in @docs From 738e33a0528703834072c28cbd57c40953f315f9 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 1 Sep 2015 16:52:02 +0100 Subject: [PATCH 077/349] change crypto to always use utf-8 as it works with aws --- services/docstore/app/coffee/DocArchiveManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 23bd733d3f..20514e6194 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -32,7 +32,7 @@ module.exports = DocArchive = if err? || res.statusCode != 200 logger.err err:err, res:res, project_id:project_id, doc_id: doc._id, statusCode: res?.statusCode, "something went wrong archiving doc in aws" return callback new Error("Error in S3 request") - md5lines = crypto.createHash("md5").update(JSON.stringify(doc.lines)).digest("hex") + md5lines = crypto.createHash("md5").update(JSON.stringify(doc.lines), "utf8").digest("hex") md5response = res.headers.etag.toString().replace(/\"/g, '') if md5lines != md5response logger.err responseMD5:md5response, linesMD5:md5lines, project_id:project_id, doc_id: doc?._id, "err in response md5 from s3" From ae75b855b4cfc27dd99e487a53dd3874db6f52c0 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Mon, 7 Sep 2015 14:06:20 +0100 Subject: [PATCH 078/349] added failing test for trying to archive load of docs which are already in s3 --- .../test/unit/coffee/DocArchiveManager.coffee | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index 2cf47b5a71..d566a3448a 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -155,6 +155,23 @@ describe "DocArchiveManager", -> err.should.equal @error done() + describe "when most have been already put in s3", -> + + beforeEach -> + numberOfDocs = 10 * 1000 + @mongoDocs = [] + while --numberOfDocs != 0 + @mongoDocs.push({inS3:true, _id: ObjectId()}) + + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @mongoDocs) + @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) + + it "should not throw and error", (done)-> + @DocArchiveManager.archiveAllDocs @project_id, (err)=> + err.should.not.exist + done() + + describe "unArchiveAllDocs", -> it "should unarchive all inS3 docs", (done)-> From 9cfa4b3f84456d776a4ecb30c8594c4d74bc95e3 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Mon, 7 Sep 2015 14:07:37 +0100 Subject: [PATCH 079/349] Don't put docs which are already in s3 through archive job This fixes the bug we saw with 'RangeError: Maximum call stack size exceeded' if lots of docs are already in s3 cb() gets called synchronously multiple times quickly which can cause the execption. I am not sure where the recursion is, maybe inside async. doing setImmediate(cb) also fixes the issue as I beilve it gives the process chance to clear the stack. Similar to process.nextTick --- services/docstore/app/coffee/DocArchiveManager.coffee | 8 +++----- .../docstore/test/unit/coffee/DocArchiveManager.coffee | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 20514e6194..63c5f780fa 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -16,12 +16,10 @@ module.exports = DocArchive = return callback(err) else if !docs? return callback new Errors.NotFoundError("No docs for project #{project_id}") + docs = _.filter docs, (doc)-> doc.inS3 != true jobs = _.map docs, (doc) -> - (cb)-> - if doc.inS3 - return cb() - else - DocArchive.archiveDoc project_id, doc, cb + (cb)-> + DocArchive.archiveDoc project_id, doc, cb async.series jobs, callback diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index d566a3448a..d55e870070 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -168,7 +168,7 @@ describe "DocArchiveManager", -> it "should not throw and error", (done)-> @DocArchiveManager.archiveAllDocs @project_id, (err)=> - err.should.not.exist + should.not.exist err done() From f1bf0c97ecb5c103bc4ca053c0ffb0e82995dce2 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 22 Sep 2015 09:41:26 +0100 Subject: [PATCH 080/349] make archive and unarchive parallelLimit to speed it up --- services/docstore/app/coffee/DocArchiveManager.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 63c5f780fa..87c0f3aaf0 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -20,7 +20,7 @@ module.exports = DocArchive = jobs = _.map docs, (doc) -> (cb)-> DocArchive.archiveDoc project_id, doc, cb - async.series jobs, callback + async.parallelLimit jobs, 5, callback archiveDoc: (project_id, doc, callback)-> @@ -52,7 +52,7 @@ module.exports = DocArchive = return cb() else DocArchive.unarchiveDoc project_id, doc._id, cb - async.series jobs, callback + async.parallelLimit jobs, 5, callback unarchiveDoc: (project_id, doc_id, callback)-> logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" From 5fef2a82b82089828a09f6f0b2779eda1322e066 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Wed, 7 Oct 2015 18:40:12 +0100 Subject: [PATCH 081/349] Acceptance tests no longer run on Travis --- services/docstore/.travis.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/services/docstore/.travis.yml b/services/docstore/.travis.yml index 6f9b984892..5c181b1569 100644 --- a/services/docstore/.travis.yml +++ b/services/docstore/.travis.yml @@ -10,12 +10,5 @@ install: - npm install - grunt install -before_script: - - grunt forever:app:start - script: - grunt test:unit - - grunt test:acceptance - -services: - - mongodb From 9826d125e3e83fc012819c061779cc54c03223c6 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Thu, 15 Oct 2015 22:22:20 +0100 Subject: [PATCH 082/349] added basic health check to docstore --- services/docstore/app.coffee | 41 ++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 3a01bead03..3a6b06f7a8 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -25,6 +25,47 @@ app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.post '/project/:project_id/archive', HttpController.archiveAllDocs app.post '/project/:project_id/unarchive', HttpController.unArchiveAllDocs + +ObjectId = require("mongojs").ObjectId +request = require("request") +async = require("async") +_ = require("underscore") +crypto = require("crypto") + +app.get "/health_check", (req, res)-> + doc_id = ObjectId() + project_id = ObjectId() + url = "http://localhost:#{port}/project/#{project_id}/doc/#{doc_id}" + lines = ["smoke test - delete me", "#{crypto.randomBytes(32).toString("hex")}"] + logger.log lines:lines, url:url, doc_id:doc_id, project_id:project_id, "running health check" + jobs = [ + (cb)-> + opts = + url:url + json: {lines: lines} + request.post(opts, cb) + (cb)-> + request.get {url:url, json:true}, (err, res, body)-> + if res.statusCode != 200 + cb("status code not 200, its #{res.statusCode}") + else if _.isEqual(body.lines, lines) and body._id == doc_id.toString() + cb() + else + cb("lines not equal ") + (cb)-> + request.del url, cb + ] + async.series jobs, (err)-> + if err? + logger.err err:err, "error running health check" + res.send 500 + else + res.send() + + + + + app.get '/status', (req, res)-> res.send('docstore is alive') From de9a24f7bb314105de963f0cc48dfa5f125dea84 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 16 Oct 2015 10:13:54 +0100 Subject: [PATCH 083/349] pulled health check into its own file and use project_id from settings --- services/docstore/app.coffee | 41 +------------------ .../docstore/app/coffee/HealthChecker.coffee | 35 ++++++++++++++++ .../docstore/app/coffee/HttpController.coffee | 10 +++++ .../docstore/config/settings.defaults.coffee | 4 +- 4 files changed, 49 insertions(+), 41 deletions(-) create mode 100644 services/docstore/app/coffee/HealthChecker.coffee diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 3a6b06f7a8..4fb4b1089c 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -25,46 +25,7 @@ app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.post '/project/:project_id/archive', HttpController.archiveAllDocs app.post '/project/:project_id/unarchive', HttpController.unArchiveAllDocs - -ObjectId = require("mongojs").ObjectId -request = require("request") -async = require("async") -_ = require("underscore") -crypto = require("crypto") - -app.get "/health_check", (req, res)-> - doc_id = ObjectId() - project_id = ObjectId() - url = "http://localhost:#{port}/project/#{project_id}/doc/#{doc_id}" - lines = ["smoke test - delete me", "#{crypto.randomBytes(32).toString("hex")}"] - logger.log lines:lines, url:url, doc_id:doc_id, project_id:project_id, "running health check" - jobs = [ - (cb)-> - opts = - url:url - json: {lines: lines} - request.post(opts, cb) - (cb)-> - request.get {url:url, json:true}, (err, res, body)-> - if res.statusCode != 200 - cb("status code not 200, its #{res.statusCode}") - else if _.isEqual(body.lines, lines) and body._id == doc_id.toString() - cb() - else - cb("lines not equal ") - (cb)-> - request.del url, cb - ] - async.series jobs, (err)-> - if err? - logger.err err:err, "error running health check" - res.send 500 - else - res.send() - - - - +app.get "/health_check", HttpController.healthCheck app.get '/status', (req, res)-> res.send('docstore is alive') diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee new file mode 100644 index 0000000000..793193d68b --- /dev/null +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -0,0 +1,35 @@ +ObjectId = require("mongojs").ObjectId +request = require("request") +async = require("async") +_ = require("underscore") +crypto = require("crypto") +settings = require("settings-sharelatex") +port = settings.internal.docstore.port +logger = require "logger-sharelatex" + + +module.exports = + check : (callback)-> + doc_id = ObjectId() + project_id = ObjectId(settings.docstore.healthCheck.project_id) + url = "http://localhost:#{port}/project/#{project_id}/doc/#{doc_id}" + lines = ["smoke test - delete me", "#{crypto.randomBytes(32).toString("hex")}"] + logger.log lines:lines, url:url, doc_id:doc_id, project_id:project_id, "running health check" + jobs = [ + (cb)-> + opts = + url:url + json: {lines: lines} + request.post(opts, cb) + (cb)-> + request.get {url:url, json:true}, (err, res, body)-> + if res.statusCode != 200 + cb("status code not 200, its #{res.statusCode}") + else if _.isEqual(body.lines, lines) and body._id == doc_id.toString() + cb() + else + cb("health check lines not equal #{body.lines} != #{lines}") + (cb)-> + request.del url, cb + ] + async.series jobs, callback diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 3b99b090d2..7d6ada30c8 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -1,6 +1,8 @@ DocManager = require "./DocManager" logger = require "logger-sharelatex" DocArchive = require "./DocArchiveManager" +HealthChecker = require "./HealthChecker" + module.exports = HttpController = getDoc: (req, res, next = (error) ->) -> @@ -94,3 +96,11 @@ module.exports = HttpController = return next(error) if error? res.send 200 + healthCheck: (req, res)-> + HealthChecker.check (err)-> + if err? + logger.err err:err, "error performing health check" + res.send 500 + else + res.send 200 + diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index e7b4046b64..da76fec12f 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -10,7 +10,9 @@ module.exports = mongo: url: 'mongodb://127.0.0.1/sharelatex' - #docstore: + docstore: + healthCheck: + project_id: "5620bece05509b0a7a3cbc61" # s3: # key: "" # secret: "" From 4f5669591a7720a4a712dbdb2948ccf34175730c Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 16 Oct 2015 12:30:53 +0100 Subject: [PATCH 084/349] add timeout to health check requests and always try the delete --- .../docstore/app/coffee/HealthChecker.coffee | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index 793193d68b..c5ee4bc57e 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -10,6 +10,7 @@ logger = require "logger-sharelatex" module.exports = check : (callback)-> + getOpts = -> {url:url, timeout:3000} doc_id = ObjectId() project_id = ObjectId(settings.docstore.healthCheck.project_id) url = "http://localhost:#{port}/project/#{project_id}/doc/#{doc_id}" @@ -17,19 +18,21 @@ module.exports = logger.log lines:lines, url:url, doc_id:doc_id, project_id:project_id, "running health check" jobs = [ (cb)-> - opts = - url:url - json: {lines: lines} + opts = getOpts() + opts.json = {lines: lines} request.post(opts, cb) (cb)-> - request.get {url:url, json:true}, (err, res, body)-> + opts = getOpts() + opts.json = true + request.get opts, (err, res, body)-> if res.statusCode != 200 cb("status code not 200, its #{res.statusCode}") else if _.isEqual(body.lines, lines) and body._id == doc_id.toString() cb() else cb("health check lines not equal #{body.lines} != #{lines}") - (cb)-> - request.del url, cb ] - async.series jobs, callback + async.series jobs, (err)-> + if err? + callback(err) + request.del getOpts(), callback From 29c812cece79ae3458ab17fa330a0e1509ba29ba Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 16 Oct 2015 12:57:05 +0100 Subject: [PATCH 085/349] moved the build opts down --- services/docstore/app/coffee/HealthChecker.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index c5ee4bc57e..aa3ef60108 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -10,11 +10,11 @@ logger = require "logger-sharelatex" module.exports = check : (callback)-> - getOpts = -> {url:url, timeout:3000} doc_id = ObjectId() project_id = ObjectId(settings.docstore.healthCheck.project_id) url = "http://localhost:#{port}/project/#{project_id}/doc/#{doc_id}" lines = ["smoke test - delete me", "#{crypto.randomBytes(32).toString("hex")}"] + getOpts = -> {url:url, timeout:3000} logger.log lines:lines, url:url, doc_id:doc_id, project_id:project_id, "running health check" jobs = [ (cb)-> From 27d3ebc1fdfac637e555a00bc91822735f634c5b Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 6 Nov 2015 12:42:44 +0000 Subject: [PATCH 086/349] Add configurable max_doc_length --- services/docstore/app.coffee | 3 ++- services/docstore/config/settings.defaults.coffee | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 4fb4b1089c..2130e0ef4b 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -19,7 +19,8 @@ app.use Metrics.http.monitor(logger) app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc -app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: "2mb"), HttpController.updateDoc +# Add 16kb overhead for the JSON encoding +app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: Settings.max_doc_size + 16 * 1024), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.post '/project/:project_id/archive', HttpController.archiveAllDocs diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index da76fec12f..4948879acf 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -17,3 +17,5 @@ module.exports = # key: "" # secret: "" # bucket: "something" + + max_doc_size: 2 * 1024 * 1024 # 2mb From 7185657f06445e66cb1e3d4e7dca372ab0c7415b Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 9 Nov 2015 15:24:21 +0000 Subject: [PATCH 087/349] Use max_doc_length rather than max_doc_size to be consistent with other services --- services/docstore/app.coffee | 2 +- services/docstore/config/settings.defaults.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 2130e0ef4b..b0b7294cef 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -20,7 +20,7 @@ app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc # Add 16kb overhead for the JSON encoding -app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: Settings.max_doc_size + 16 * 1024), HttpController.updateDoc +app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: Settings.max_doc_length + 16 * 1024), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.post '/project/:project_id/archive', HttpController.archiveAllDocs diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 4948879acf..e474aea7b9 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -18,4 +18,4 @@ module.exports = # secret: "" # bucket: "something" - max_doc_size: 2 * 1024 * 1024 # 2mb + max_doc_length: 2 * 1024 * 1024 # 2mb From a964119b5ef9f8b3bb3f87b5b4de2c7fd8bdf681 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 1 Dec 2015 21:50:18 +0000 Subject: [PATCH 088/349] check err in health check and null check res --- services/docstore/app/coffee/HealthChecker.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index aa3ef60108..3818afc822 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -25,7 +25,10 @@ module.exports = opts = getOpts() opts.json = true request.get opts, (err, res, body)-> - if res.statusCode != 200 + if err? + logger.err err:err, "docstore returned a error in health check get" + cb(err) + else if res?.statusCode != 200 cb("status code not 200, its #{res.statusCode}") else if _.isEqual(body.lines, lines) and body._id == doc_id.toString() cb() From 1541eb319c5357ead6b3dc9829b4103dc6147470 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 2 Dec 2015 10:10:52 +0000 Subject: [PATCH 089/349] add more null checks to health check --- services/docstore/app/coffee/HealthChecker.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index 3818afc822..d0c181143d 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -28,9 +28,11 @@ module.exports = if err? logger.err err:err, "docstore returned a error in health check get" cb(err) + else if !res? + cb("no response from docstore with get check") else if res?.statusCode != 200 cb("status code not 200, its #{res.statusCode}") - else if _.isEqual(body.lines, lines) and body._id == doc_id.toString() + else if _.isEqual(body?.lines, lines) and body?._id == doc_id.toString() cb() else cb("health check lines not equal #{body.lines} != #{lines}") From 56c0604b96793baf87eeb838b026bc5f8a1a174f Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Fri, 3 Jun 2016 10:58:53 +0100 Subject: [PATCH 090/349] upgrade to node 4.2.1 --- services/docstore/.nvmrc | 1 + services/docstore/package.json | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 services/docstore/.nvmrc diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc new file mode 100644 index 0000000000..fae6e3d04b --- /dev/null +++ b/services/docstore/.nvmrc @@ -0,0 +1 @@ +4.2.1 diff --git a/services/docstore/package.json b/services/docstore/package.json index fbf41400d3..d603ce0313 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", - "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.0.0", + "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.1.0", "mongojs": "0.18.2", "express": "~4.1.1", @@ -31,5 +31,8 @@ "chai": "~1.9.1", "grunt-forever": "~0.4.4", "request": "~2.34.0" + }, + "engines": { + "node": "~4.2.1" } } From 0a0a8e23fe29b7386342bb2574ed119444eef8ac Mon Sep 17 00:00:00 2001 From: Brian Gough <bjg@network-theory.co.uk> Date: Fri, 2 Sep 2016 13:37:21 +0100 Subject: [PATCH 091/349] remove unused modules --- services/docstore/app/coffee/DocManager.coffee | 5 ----- 1 file changed, 5 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 2cdfda17fb..62de6314ec 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -2,11 +2,6 @@ MongoManager = require "./MongoManager" Errors = require "./Errors" logger = require "logger-sharelatex" _ = require "underscore" -async = require "async" -settings = require("settings-sharelatex") -request = require("request") -crypto = require("crypto") -thirtySeconds = 30 * 1000 DocArchive = require "./DocArchiveManager" module.exports = DocManager = From 7a28fb58e7cbc30a3a6d3be98cddaf6ce22d2a61 Mon Sep 17 00:00:00 2001 From: Brian Gough <bjg@network-theory.co.uk> Date: Fri, 2 Sep 2016 13:32:50 +0100 Subject: [PATCH 092/349] clean up mongo query --- .../docstore/app/coffee/DocManager.coffee | 2 +- .../docstore/app/coffee/MongoManager.coffee | 4 +- .../test/unit/coffee/DocManagerTests.coffee | 37 ++++++++++--------- .../test/unit/coffee/MongoManagerTests.coffee | 5 ++- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 62de6314ec..e09d156f22 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -7,7 +7,7 @@ DocArchive = require "./DocArchiveManager" module.exports = DocManager = getDoc: (project_id, doc_id, callback = (error, doc) ->) -> - MongoManager.findDoc doc_id, (err, doc)-> + MongoManager.findDoc project_id, doc_id, (err, doc)-> if err? return callback(err) else if !doc? diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index b454214ff1..00dd935632 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -2,8 +2,8 @@ module.exports = MongoManager = - findDoc: (doc_id, callback = (error, doc) ->) -> - db.docs.find _id: ObjectId(doc_id.toString()), {}, (error, docs = []) -> + findDoc: (project_id, doc_id, callback = (error, doc) ->) -> + db.docs.find {_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, {}, (error, docs = []) -> callback error, docs[0] getProjectsDocs: (project_id, callback)-> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 64551da527..c84f64b75b 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -18,14 +18,15 @@ describe "DocManager", -> err:-> @doc_id = ObjectId().toString() @project_id = ObjectId().toString() + @another_project_id = ObjectId().toString() @callback = sinon.stub() @stubbedError = new Error("blew up") describe "getDoc", -> beforeEach -> @project = { name: "mock-project" } - @doc = { _id: @doc_id, lines: ["mock-lines"] } - @docCollectionDoc = { _id: @doc_id, lines: ["mock-lines"] } + @doc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] } + @docCollectionDoc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] } describe "when the doc is in the doc collection not projects collection", -> @@ -33,24 +34,24 @@ describe "DocManager", -> @MongoManager.findDoc = sinon.stub() it "should get the doc from the doc collection when it is present there", (done)-> - @MongoManager.findDoc.callsArgWith(1, null, @docCollectionDoc) + @MongoManager.findDoc.callsArgWith(2, null, @docCollectionDoc) @DocManager.getDoc @project_id, @doc_id, (err, doc)=> doc.should.equal @docCollectionDoc done() it "should return the error from find doc", (done)-> - @MongoManager.findDoc.callsArgWith(1, @stubbedError) + @MongoManager.findDoc.callsArgWith(2, @stubbedError) @DocManager.getDoc @project_id, @doc_id, (err, doc)=> err.should.equal @stubbedError done() describe "when the doc is deleted", -> beforeEach -> - @doc = { _id: @doc_id, lines: ["mock-lines"] } - @s3doc = { _id: @doc_id, inS3: true } + @doc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] } + @s3doc = { _id: @doc_id, project_id: @project_id, inS3: true } @MongoManager.findDoc = sinon.stub() - @MongoManager.findDoc.callsArgWith(1, null, @s3doc) - @MongoManager.findDoc.callsArgWith(1, null, @doc) + @MongoManager.findDoc.callsArgWith(2, null, @s3doc) + @MongoManager.findDoc.callsArgWith(2, null, @doc) spy = sinon.spy @DocManager.getDoc @DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2) @DocManager.getDoc @project_id, @doc_id, @callback @@ -63,13 +64,13 @@ describe "DocManager", -> describe "when the doc is in s3", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) + @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) @DocManager.getDoc @project_id, @doc_id, @callback describe "when the doc does not exist anywhere", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null) + @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, null) @DocManager.getDoc @project_id, @doc_id, @callback it "should return a NotFoundError", -> @@ -80,7 +81,7 @@ describe "DocManager", -> describe "getAllDocs", -> describe "when the project exists", -> beforeEach -> - @docs = [{ _id: @doc_id, lines: ["mock-lines"] }] + @docs = [{ _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] }] @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @docs) @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, @docs) @DocManager.getAllDocs @project_id, @callback @@ -150,19 +151,19 @@ describe "DocManager", -> beforeEach -> @oldDocLines = ["old", "doc", "lines"] @newDocLines = ["new", "doc", "lines"] - @doc = { _id: @doc_id, lines: @oldDocLines, rev: @rev = 5 } + @doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5 } @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @MongoManager.findDoc = sinon.stub() describe "when the doc lines have changed", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) + @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should get the existing doc", -> @MongoManager.findDoc - .calledWith(@doc_id) + .calledWith(@project_id, @doc_id) .should.equal true it "should upsert the document to the doc collection", -> @@ -189,7 +190,7 @@ describe "DocManager", -> beforeEach -> @error = new Error("doc could not be found") - @MongoManager.findDoc = sinon.stub().callsArgWith(1, @error, null, null) + @MongoManager.findDoc = sinon.stub().callsArgWith(2, @error, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should not upsert the document to the doc collection", -> @@ -200,7 +201,7 @@ describe "DocManager", -> describe "when the doc lines have not changed", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) + @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback it "should not update the doc", -> @@ -214,7 +215,7 @@ describe "DocManager", -> beforeEach -> @doc.lines = [] - @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, @doc) + @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback it "should upsert the document to the doc collection", -> @@ -225,7 +226,7 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(1, null, null, null) + @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback it "should upsert the document to the doc collection", -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index b0e7c07e97..b64473b5ec 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -18,14 +18,15 @@ describe "MongoManager", -> describe "findDoc", -> beforeEach -> - @doc = { name: "mock-doc" } + @doc = { name: "mock-doc"} @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc]) - @MongoManager.findDoc @doc_id, @callback + @MongoManager.findDoc @project_id, @doc_id, @callback it "should find the doc", -> @db.docs.find .calledWith({ _id: ObjectId(@doc_id) + project_id: ObjectId(@project_id) }, {}) .should.equal true From f95fc2f779d7b43f74370ec783eca67895c62905 Mon Sep 17 00:00:00 2001 From: Brian Gough <bjg@network-theory.co.uk> Date: Fri, 2 Sep 2016 13:33:30 +0100 Subject: [PATCH 093/349] add route parameters --- services/docstore/app.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index b0b7294cef..f80f99288d 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -16,6 +16,18 @@ app = express() app.use Metrics.http.monitor(logger) +app.param 'project_id', (req, res, next, project_id) -> + if project_id?.match /^[0-9a-f]{24}$/ + next() + else + next new Error("invalid project id") + +app.param 'doc_id', (req, res, next, doc_id) -> + if doc_id?.match /^[0-9a-f]{24}$/ + next() + else + next new Error("invalid doc id") + app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc From eb9a3b314a6e0fb8cedb11b4739df408f4e62bb3 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 28 Nov 2016 14:55:16 +0000 Subject: [PATCH 094/349] Set/get version in docOps via docstore HTTP API --- .../app/coffee/DocArchiveManager.coffee | 12 +- .../docstore/app/coffee/DocManager.coffee | 29 ++- .../docstore/app/coffee/HttpController.coffee | 8 +- .../docstore/app/coffee/MongoManager.coffee | 23 ++- services/docstore/app/coffee/mongojs.coffee | 2 +- .../docstore/config/settings.defaults.coffee | 14 +- .../acceptance/coffee/ArchiveDocsTests.coffee | 4 +- .../coffee/GettingAllDocsTests.coffee | 2 +- .../coffee/UpdatingDocsTests.coffee | 40 ++++- .../coffee/helpers/DocstoreClient.coffee | 6 +- .../test/unit/coffee/DocManagerTests.coffee | 170 ++++++++++++------ .../unit/coffee/HttpControllerTests.coffee | 29 ++- .../test/unit/coffee/MongoManagerTests.coffee | 47 ++++- 13 files changed, 300 insertions(+), 86 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 87c0f3aaf0..5e0272466c 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -25,7 +25,10 @@ module.exports = DocArchive = archiveDoc: (project_id, doc, callback)-> logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" - options = DocArchive.buildS3Options(doc.lines, project_id+"/"+doc._id) + try + options = DocArchive.buildS3Options(doc.lines, project_id+"/"+doc._id) + catch e + return callback e request.put options, (err, res)-> if err? || res.statusCode != 200 logger.err err:err, res:res, project_id:project_id, doc_id: doc._id, statusCode: res?.statusCode, "something went wrong archiving doc in aws" @@ -56,7 +59,10 @@ module.exports = DocArchive = unarchiveDoc: (project_id, doc_id, callback)-> logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" - options = DocArchive.buildS3Options(true, project_id+"/"+doc_id) + try + options = DocArchive.buildS3Options(true, project_id+"/"+doc_id) + catch e + return callback e request.get options, (err, res, lines)-> if err? || res.statusCode != 200 logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong unarchiving doc from aws" @@ -71,6 +77,8 @@ module.exports = DocArchive = callback() buildS3Options: (content, key)-> + if !settings.docstore.s3? + throw new Error("S3 settings are not configured") return { aws: key: settings.docstore.s3.key diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index e09d156f22..6a963dc291 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -5,7 +5,10 @@ _ = require "underscore" DocArchive = require "./DocArchiveManager" module.exports = DocManager = - + # TODO: For historical reasons, the doc version is currently stored in the docOps + # collection (which is all that this collection contains). In future, we should + # migrate this version property to be part of the docs collection, to guarantee + # consitency between lines and version when writing/reading, and for a simpler schema. getDoc: (project_id, doc_id, callback = (error, doc) ->) -> MongoManager.findDoc project_id, doc_id, (err, doc)-> if err? @@ -19,7 +22,10 @@ module.exports = DocManager = return callback(err) DocManager.getDoc project_id, doc_id, callback else - callback err, doc + MongoManager.getDocVersion doc_id, (error, version) -> + return callback(error) if error? + doc.version = version + callback err, doc getAllDocs: (project_id, callback = (error, docs) ->) -> DocArchive.unArchiveAllDocs project_id, (error) -> @@ -31,7 +37,7 @@ module.exports = DocManager = else return callback(null, docs) - updateDoc: (project_id, doc_id, lines, callback = (error, modified, rev) ->) -> + updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) -> DocManager.getDoc project_id, doc_id, (err, doc)-> if err? and !(err instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" @@ -39,8 +45,12 @@ module.exports = DocManager = isNewDoc = lines.length == 0 linesAreSame = _.isEqual(doc?.lines, lines) + if version? + versionsAreSame = (doc?.version == version) + else + versionsAreSame = true - if linesAreSame and !isNewDoc + if linesAreSame and versionsAreSame and !isNewDoc logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating" return callback null, false, doc?.rev else @@ -54,7 +64,16 @@ module.exports = DocManager = }, "updating doc lines" MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)-> return callback(callback) if error? - callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc + # TODO: While rolling out this code, setting the version via the docstore is optional, + # so if it hasn't been passed, just ignore it. Once the docupdater has totally + # handed control of this to the docstore, we can assume it will always be passed + # and an error guard on it not being set instead. + if version? + MongoManager.setDocVersion doc_id, version, (error) -> + return callback(error) if error? + callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc + else + callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc deleteDoc: (project_id, doc_id, callback = (error) ->) -> DocManager.getDoc project_id, doc_id, (error, doc) -> diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 7d6ada30c8..0dfb30c31e 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -49,6 +49,7 @@ module.exports = HttpController = project_id = req.params.project_id doc_id = req.params.doc_id lines = req.body?.lines + version = req.body?.version if !lines? or lines not instanceof Array logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided" @@ -56,7 +57,7 @@ module.exports = HttpController = return logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc" - DocManager.updateDoc project_id, doc_id, lines, (error, modified, rev) -> + DocManager.updateDoc project_id, doc_id, lines, version, (error, modified, rev) -> return next(error) if error? res.json { modified: modified @@ -72,12 +73,15 @@ module.exports = HttpController = res.send 204 _buildDocView: (doc) -> - return { + doc_view = { _id: doc._id?.toString() lines: doc.lines rev: doc.rev deleted: !!doc.deleted } + if doc.version? + doc_view.version = doc.version + return doc_view _buildRawDocView: (doc)-> return (doc?.lines or []).join("\n") diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 00dd935632..e44c995490 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -44,4 +44,25 @@ module.exports = MongoManager = _id: doc_id rev: rev db.docs.update query, update, (err)-> - callback(err) \ No newline at end of file + callback(err) + + getDocVersion: (doc_id, callback = (error, version) ->) -> + db.docOps.find { + doc_id: ObjectId(doc_id) + }, { + version: 1 + }, (error, docs) -> + return callback(error) if error? + if docs.length < 1 or !docs[0].version? + return callback null, 0 + else + return callback null, docs[0].version + + setDocVersion: (doc_id, version, callback = (error) ->) -> + db.docOps.update { + doc_id: ObjectId(doc_id) + }, { + $set: version: version + }, { + upsert: true + }, callback \ No newline at end of file diff --git a/services/docstore/app/coffee/mongojs.coffee b/services/docstore/app/coffee/mongojs.coffee index 9a8d6c38e5..db3d3c00d8 100644 --- a/services/docstore/app/coffee/mongojs.coffee +++ b/services/docstore/app/coffee/mongojs.coffee @@ -1,6 +1,6 @@ Settings = require "settings-sharelatex" mongojs = require "mongojs" -db = mongojs.connect(Settings.mongo.url, ["docs"]) +db = mongojs.connect(Settings.mongo.url, ["docs", "docOps"]) module.exports = db: db ObjectId: mongojs.ObjectId diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index e474aea7b9..e74334d2ad 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -1,7 +1,7 @@ http = require('http') http.globalAgent.maxSockets = 300 -module.exports = +module.exports = Settings = internal: docstore: port: 3016 @@ -12,10 +12,12 @@ module.exports = docstore: healthCheck: - project_id: "5620bece05509b0a7a3cbc61" - # s3: - # key: "" - # secret: "" - # bucket: "something" + project_id: "" max_doc_length: 2 * 1024 * 1024 # 2mb + +if process.env['AWS_ACCESS_KEY_ID']? and process.env['AWS_SECRET_ACCESS_KEY']? and process.env['AWS_BUCKET']? + Settings.docstore.s3 = + key: process.env['AWS_ACCESS_KEY_ID'] + secret: process.env['AWS_SECRET_ACCESS_KEY'] + bucket: process.env['AWS_BUCKET'] \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 52d62eb2c6..26c57e7712 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -30,7 +30,7 @@ describe "Archiving all docs", -> (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback async.series jobs, done afterEach (done) -> @@ -109,7 +109,7 @@ describe "Archiving all docs", -> quarterMegInBytes = 250000 lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") @docs[1].lines = [lines,lines,lines,lines] - DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, => + DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, null, => DocstoreClient.archiveAllDoc @project_id, (error, @res) => done() diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index 4463abcdad..eb4261b7ae 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -27,7 +27,7 @@ describe "Getting all docs", -> (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, callback + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback async.series jobs, done it "should return all the docs", (done) -> diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index b18be15c25..5f21f55845 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -11,13 +11,16 @@ describe "Applying updates to a doc", -> @doc_id = ObjectId() @originalLines = ["original", "lines"] @newLines = ["new", "lines"] - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + @version = 42 + DocstoreClient.createDoc @project_id, @doc_id, @originalLines, (error) => throw error if error? - done() + DocstoreClient.setDocVersion @doc_id, @version, (error) => + throw error if error? + done() describe "when the content has changed", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @newLines, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @newLines, null, (error, res, @body) => done() it "should return modified = true", -> @@ -26,14 +29,15 @@ describe "Applying updates to a doc", -> it "should return the rev", -> @body.rev.should.equal 2 - it "should update the doc in the API", (done) -> + it "should update the doc in the API but not change the version", (done) -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @newLines + doc.version.should.equal @version done() describe "when the content has not been updated", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, (error, res, @body) => done() it "should return modified = false", -> @@ -47,7 +51,7 @@ describe "Applying updates to a doc", -> describe "when the doc does not exist", -> beforeEach (done) -> @missing_doc_id = ObjectId() - DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, null, (error, @res, @body) => done() it "should create the doc", -> @@ -56,12 +60,13 @@ describe "Applying updates to a doc", -> it "should be retreivable", (done)-> DocstoreClient.getDoc @project_id, @missing_doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @originalLines + doc.version.should.equal 0 done() describe "when malformed doc lines are provided", -> describe "when the lines are not an array", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, null, (error, @res, @body) => done() it "should return 400", -> @@ -74,7 +79,7 @@ describe "Applying updates to a doc", -> describe "when the lines are not present", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, null, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, null, null, (error, @res, @body) => done() it "should return 400", -> @@ -89,7 +94,7 @@ describe "Applying updates to a doc", -> beforeEach (done) -> line = new Array(1025).join("x") # 1kb @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, null, (error, res, @body) => done() it "should return modified = true", -> @@ -100,3 +105,20 @@ describe "Applying updates to a doc", -> doc.lines.should.deep.equal @largeLines done() + describe "when the version has changed", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version + 1, (error, res, @body) => + done() + + it "should return modified = true", -> + @body.modified.should.equal true + + it "should return the rev", -> + @body.rev.should.equal 2 + + it "should update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + doc.version.should.equal @version + 1 + done() + diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index b81408b6f3..6c12628826 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -7,6 +7,9 @@ module.exports = DocstoreClient = createDoc: (project_id, doc_id, lines, callback = (error) ->) -> db.docs.save({_id: doc_id, project_id:project_id, lines: lines, rev:1}, callback) + + setDocVersion: (doc_id, version, callback = (error) ->) -> + db.docOps.save({doc_id: doc_id, version: version}, callback) createDeletedDoc: (project_id, doc_id, lines, callback = (error) ->) -> db.docs.insert { @@ -29,11 +32,12 @@ module.exports = DocstoreClient = json: true }, callback - updateDoc: (project_id, doc_id, lines, callback = (error, res, body) ->) -> + updateDoc: (project_id, doc_id, lines, version, callback = (error, res, body) ->) -> request.post { url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" json: lines: lines + version: version }, callback deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index c84f64b75b..d603f672d7 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -26,49 +26,59 @@ describe "DocManager", -> beforeEach -> @project = { name: "mock-project" } @doc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] } - @docCollectionDoc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] } - - describe "when the doc is in the doc collection not projects collection", -> + @version = 42 + @MongoManager.findDoc = sinon.stub() + @MongoManager.getDocVersion = sinon.stub().yields(null, @version) + describe "when the doc is in the doc collection", -> beforeEach -> - @MongoManager.findDoc = sinon.stub() + @MongoManager.findDoc.yields(null, @doc) + @DocManager.getDoc @project_id, @doc_id, @callback - it "should get the doc from the doc collection when it is present there", (done)-> - @MongoManager.findDoc.callsArgWith(2, null, @docCollectionDoc) - @DocManager.getDoc @project_id, @doc_id, (err, doc)=> - doc.should.equal @docCollectionDoc - done() + it "should get the doc from the doc collection", -> + @MongoManager.findDoc + .calledWith(@project_id, @doc_id) + .should.equal true - it "should return the error from find doc", (done)-> - @MongoManager.findDoc.callsArgWith(2, @stubbedError) - @DocManager.getDoc @project_id, @doc_id, (err, doc)=> - err.should.equal @stubbedError - done() + it "should get the doc version from the docOps collection", -> + @MongoManager.getDocVersion + .calledWith(@doc_id) + .should.equal true + + it "should return the callback with the doc with the version", -> + @callback.called.should.equal true + doc = @callback.args[0][1] + doc.lines.should.equal @doc.lines + doc.version.should.equal @version + + describe "when MongoManager.findDoc errors", -> + beforeEach -> + @MongoManager.findDoc.yields(@stubbedError) + @DocManager.getDoc @project_id, @doc_id, @callback - describe "when the doc is deleted", -> + it "should return the error", -> + @callback.calledWith(@stubbedError).should.equal true + + describe "when the doc is archived", -> beforeEach -> - @doc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] } - @s3doc = { _id: @doc_id, project_id: @project_id, inS3: true } - @MongoManager.findDoc = sinon.stub() - @MongoManager.findDoc.callsArgWith(2, null, @s3doc) - @MongoManager.findDoc.callsArgWith(2, null, @doc) - spy = sinon.spy @DocManager.getDoc - @DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2) + @doc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"], inS3: true } + @MongoManager.findDoc.yields(null, @doc) + @DocArchiveManager.unarchiveDoc = (project_id, doc_id, callback) => + @doc.inS3 = false + callback() + sinon.spy @DocArchiveManager, "unarchiveDoc" @DocManager.getDoc @project_id, @doc_id, @callback it "should call the DocArchive to unarchive the doc", -> @DocArchiveManager.unarchiveDoc.calledWith(@project_id, @doc_id).should.equal true + + it "should look up the doc twice", -> + @MongoManager.findDoc.calledTwice.should.equal true it "should return the doc", -> @callback.calledWith(null, @doc).should.equal true - describe "when the doc is in s3", -> - beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) - - @DocManager.getDoc @project_id, @doc_id, @callback - - describe "when the doc does not exist anywhere", -> + describe "when the doc does not exist in the docs collection", -> beforeEach -> @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, null) @DocManager.getDoc @project_id, @doc_id, @callback @@ -151,25 +161,32 @@ describe "DocManager", -> beforeEach -> @oldDocLines = ["old", "doc", "lines"] @newDocLines = ["new", "doc", "lines"] - @doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5 } + @version = 42 + @doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5, version: @version } @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) - @MongoManager.findDoc = sinon.stub() + @MongoManager.setDocVersion = sinon.stub().yields() + @DocManager.getDoc = sinon.stub() describe "when the doc lines have changed", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should get the existing doc", -> - @MongoManager.findDoc + @DocManager.getDoc .calledWith(@project_id, @doc_id) .should.equal true it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection .calledWith(@project_id, @doc_id, @newDocLines) - .should.equal true + .should.equal true + + it "should update the version", -> + @MongoManager.setDocVersion + .calledWith(@doc_id, @version) + .should.equal true it "should log out the old and new doc lines", -> @logger.log @@ -186,12 +203,71 @@ describe "DocManager", -> it "should return the callback with the new rev", -> @callback.calledWith(null, true, @rev + 1).should.equal true - describe "when there is a generic error getting the doc", -> + describe "when the version has changed", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @callback + it "should get the existing doc", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should upsert the document to the doc collection", -> + @MongoManager.upsertIntoDocCollection + .calledWith(@project_id, @doc_id, @oldDocLines) + .should.equal true + + it "should update the version", -> + @MongoManager.setDocVersion + .calledWith(@doc_id, @version + 1) + .should.equal true + + it "should return the callback with the new rev", -> + @callback.calledWith(null, true, @rev + 1).should.equal true + + describe "when the version is null and the lines are different", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @callback + + it "should get the existing doc", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should upsert the document to the doc collection", -> + @MongoManager.upsertIntoDocCollection + .calledWith(@project_id, @doc_id, @newDocLines) + .should.equal true + + it "should not update the version", -> + @MongoManager.setDocVersion + .called + .should.equal false + + it "should return the callback with the new rev", -> + @callback.calledWith(null, true, @rev + 1).should.equal true + + describe "when the version is null and the lines are the same", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, null, @callback + + it "should not update the version", -> + @MongoManager.setDocVersion.called.should.equal false + + it "should not update the doc", -> + @MongoManager.upsertIntoDocCollection.called.should.equal false + + it "should return the callback with the existing rev", -> + @callback.calledWith(null, false, @rev).should.equal true + + describe "when there is a generic error getting the doc", -> beforeEach -> @error = new Error("doc could not be found") - @MongoManager.findDoc = sinon.stub().callsArgWith(2, @error, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + @DocManager.getDoc = sinon.stub().callsArgWith(2, @error, null, null) + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should not upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection.called.should.equal false @@ -201,8 +277,8 @@ describe "DocManager", -> describe "when the doc lines have not changed", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @callback + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @callback it "should not update the doc", -> @MongoManager.upsertIntoDocCollection.called.should.equal false @@ -210,12 +286,10 @@ describe "DocManager", -> it "should return the callback with the existing rev", -> @callback.calledWith(null, false, @rev).should.equal true - describe "when the doc lines are an empty array", -> beforeEach -> - @doc.lines = [] - @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback it "should upsert the document to the doc collection", -> @@ -223,19 +297,15 @@ describe "DocManager", -> .calledWith(@project_id, @doc_id, @doc.lines) .should.equal true - describe "when the doc does not exist", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @callback + @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection .calledWith(@project_id, @doc_id, @newDocLines) - .should.equal true + .should.equal true it "should return the callback with the new rev", -> @callback.calledWith(null, true, 1).should.equal true - - - diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index c76ced9696..4d9ae795ab 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -13,6 +13,7 @@ describe "HttpController", -> "./DocManager": @DocManager = {} "./DocArchiveManager": @DocArchiveManager = {} "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } + "./HealthChecker": {} @res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() } @req = { query:{}} @next = sinon.stub() @@ -54,6 +55,7 @@ describe "HttpController", -> lines: @doc.lines rev: @doc.rev deleted: false + version: @doc.version }) .should.equal true @@ -81,6 +83,7 @@ describe "HttpController", -> lines: @doc.lines rev: @doc.rev deleted: true + version: @doc.version }) .should.equal true @@ -192,12 +195,12 @@ describe "HttpController", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] - @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, true, @rev = 5) + @DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should update the document", -> @DocManager.updateDoc - .calledWith(@project_id, @doc_id, @lines) + .calledWith(@project_id, @doc_id, @lines, undefined) .should.equal true it "should return a modified status", -> @@ -209,7 +212,7 @@ describe "HttpController", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] - @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, false, @rev = 5) + @DocManager.updateDoc = sinon.stub().yields(null, false, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should return a modified status", -> @@ -220,7 +223,7 @@ describe "HttpController", -> describe "when the doc lines are not provided", -> beforeEach -> @req.body = {} - @DocManager.updateDoc = sinon.stub().callsArgWith(3, null, false) + @DocManager.updateDoc = sinon.stub().yields(null, false) @HttpController.updateDoc @req, @res, @next it "should not update the document", -> @@ -231,6 +234,24 @@ describe "HttpController", -> .calledWith(400) .should.equal true + describe "when the doc version is provided", -> + beforeEach -> + @req.body = + lines: @lines = ["hello", "world"] + version: @version = 42 + @DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5) + @HttpController.updateDoc @req, @res, @next + + it "should update the document with the lines and version", -> + @DocManager.updateDoc + .calledWith(@project_id, @doc_id, @lines, @version) + .should.equal true + + it "should return a modified status", -> + @res.json + .calledWith(modified: true, rev: @rev) + .should.equal true + describe "deleteDoc", -> beforeEach -> @req.params = diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index b64473b5ec..54a352417a 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -9,7 +9,7 @@ describe "MongoManager", -> beforeEach -> @MongoManager = SandboxedModule.require modulePath, requires: "./mongojs": - db: @db = { docs: {} } + db: @db = { docs: {}, docOps: {} } ObjectId: ObjectId @project_id = ObjectId().toString() @doc_id = ObjectId().toString() @@ -88,4 +88,47 @@ describe "MongoManager", -> err.should.equal @stubbedErr done() - \ No newline at end of file + describe "getDocVersion", -> + describe "when the doc exists", -> + beforeEach -> + @doc = + version: @version = 42 + @db.docOps.find = sinon.stub().callsArgWith(2, null, [@doc]) + @MongoManager.getDocVersion @doc_id, @callback + + it "should look for the doc in the database", -> + @db.docOps.find + .calledWith({ doc_id: ObjectId(@doc_id) }, {version: 1}) + .should.equal true + + it "should call the callback with the version", -> + @callback.calledWith(null, @version).should.equal true + + describe "when the doc doesn't exist", -> + beforeEach -> + @db.docOps.find = sinon.stub().callsArgWith(2, null, []) + @MongoManager.getDocVersion @doc_id, @callback + + it "should call the callback with 0", -> + @callback.calledWith(null, 0).should.equal true + + describe "setDocVersion", -> + beforeEach -> + @version = 42 + @db.docOps.update = sinon.stub().callsArg(3) + @MongoManager.setDocVersion @doc_id, @version, @callback + + it "should update the doc version", -> + @db.docOps.update + .calledWith({ + doc_id: ObjectId(@doc_id) + }, { + $set: + version: @version + }, { + upsert: true + }) + .should.equal true + + it "should call the callback", -> + @callback.called.should.equal true \ No newline at end of file From f7ba5546588cb98227e58259b4b41c68f951ffef Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 28 Nov 2016 16:51:43 +0000 Subject: [PATCH 095/349] set up acceptance tests to run via docker --- services/docstore/Gruntfile.coffee | 7 ++++++ .../docstore/config/settings.defaults.coffee | 14 ++++++----- .../test/acceptance/scripts/full-test.sh | 23 +++++++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100755 services/docstore/test/acceptance/scripts/full-test.sh diff --git a/services/docstore/Gruntfile.coffee b/services/docstore/Gruntfile.coffee index 05e00c5a42..9e5af27034 100644 --- a/services/docstore/Gruntfile.coffee +++ b/services/docstore/Gruntfile.coffee @@ -6,6 +6,7 @@ module.exports = (grunt) -> app: options: index: "app.js" + coffee: app_src: expand: true, @@ -67,6 +68,10 @@ module.exports = (grunt) -> reporter: grunt.option('reporter') or 'spec' timeout: 10000 src: ["test/smoke/js/**/*.js"] + + shell: + dockerTests: + command: 'docker run -v "$(pwd):/app" -e AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" -e AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" -e AWS_BUCKET="$AWS_BUCKET" --rm sl-acceptance-test-runner' grunt.loadNpmTasks 'grunt-contrib-coffee' grunt.loadNpmTasks 'grunt-contrib-clean' @@ -89,6 +94,8 @@ module.exports = (grunt) -> grunt.registerTask 'test:smoke', ['compile:smoke_tests', 'mochaTest:smoke'] grunt.registerTask 'install', 'compile:app' + + grunt.registerTask 'test:acceptance:docker', ['compile:acceptance_tests', 'shell:dockerTests'] grunt.registerTask 'default', ['run'] diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index e474aea7b9..e74334d2ad 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -1,7 +1,7 @@ http = require('http') http.globalAgent.maxSockets = 300 -module.exports = +module.exports = Settings = internal: docstore: port: 3016 @@ -12,10 +12,12 @@ module.exports = docstore: healthCheck: - project_id: "5620bece05509b0a7a3cbc61" - # s3: - # key: "" - # secret: "" - # bucket: "something" + project_id: "" max_doc_length: 2 * 1024 * 1024 # 2mb + +if process.env['AWS_ACCESS_KEY_ID']? and process.env['AWS_SECRET_ACCESS_KEY']? and process.env['AWS_BUCKET']? + Settings.docstore.s3 = + key: process.env['AWS_ACCESS_KEY_ID'] + secret: process.env['AWS_SECRET_ACCESS_KEY'] + bucket: process.env['AWS_BUCKET'] \ No newline at end of file diff --git a/services/docstore/test/acceptance/scripts/full-test.sh b/services/docstore/test/acceptance/scripts/full-test.sh new file mode 100755 index 0000000000..a7a8eeca51 --- /dev/null +++ b/services/docstore/test/acceptance/scripts/full-test.sh @@ -0,0 +1,23 @@ +#! /usr/bin/env bash + +echo $AWS_BUCKET + +echo ">> Starting server..." + +grunt forever:app:start + +echo ">> Server started" + +sleep 5 + +echo ">> Running acceptance tests..." +grunt mochaTest:acceptance +_test_exit_code=$? + +echo ">> Killing server" + +grunt forever:app:stop + +echo ">> Done" + +exit $_test_exit_code From 7204c08fb24d307bb0100a837b4a8258b5868b48 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Tue, 29 Nov 2016 14:29:51 +0000 Subject: [PATCH 096/349] Rebuild npm modules as part of acceptance test docker run --- services/docstore/test/acceptance/scripts/full-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/test/acceptance/scripts/full-test.sh b/services/docstore/test/acceptance/scripts/full-test.sh index a7a8eeca51..f68ebbd3be 100755 --- a/services/docstore/test/acceptance/scripts/full-test.sh +++ b/services/docstore/test/acceptance/scripts/full-test.sh @@ -1,6 +1,6 @@ #! /usr/bin/env bash -echo $AWS_BUCKET +npm rebuild echo ">> Starting server..." From 10008fa9c46aca451f808cfb98aea0854dfef127 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Tue, 29 Nov 2016 14:41:12 +0000 Subject: [PATCH 097/349] Don't add colours in automated test script --- services/docstore/test/acceptance/scripts/full-test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/test/acceptance/scripts/full-test.sh b/services/docstore/test/acceptance/scripts/full-test.sh index f68ebbd3be..9f6167e667 100755 --- a/services/docstore/test/acceptance/scripts/full-test.sh +++ b/services/docstore/test/acceptance/scripts/full-test.sh @@ -4,19 +4,19 @@ npm rebuild echo ">> Starting server..." -grunt forever:app:start +grunt --no-color forever:app:start echo ">> Server started" sleep 5 echo ">> Running acceptance tests..." -grunt mochaTest:acceptance +grunt --no-color mochaTest:acceptance _test_exit_code=$? echo ">> Killing server" -grunt forever:app:stop +grunt --no-color forever:app:stop echo ">> Done" From 50f2983912f19727a5ec84830ac4b97c389f7f8f Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Tue, 29 Nov 2016 16:49:35 +0000 Subject: [PATCH 098/349] Log out version when updating doc --- services/docstore/app/coffee/DocManager.coffee | 2 ++ services/docstore/test/unit/coffee/DocManagerTests.coffee | 2 ++ 2 files changed, 4 insertions(+) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 6a963dc291..c37b68152f 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -61,6 +61,8 @@ module.exports = DocManager = oldDocLines: doc?.lines newDocLines: lines rev: oldRev + oldVersion: doc?.version + newVersion: version }, "updating doc lines" MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)-> return callback(callback) if error? diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index d603f672d7..d16c30206b 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -196,6 +196,8 @@ describe "DocManager", -> oldDocLines: @oldDocLines newDocLines: @newDocLines rev: @doc.rev + oldVersion: @version + newVersion: @version "updating doc lines" ) .should.equal true From 8b95a04a36678d77e453812b6ef0ffab2413c662 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Wed, 30 Nov 2016 15:08:56 +0000 Subject: [PATCH 099/349] Don't look up version in mongo if not needed --- .../docstore/app/coffee/DocManager.coffee | 17 ++++--- .../docstore/app/coffee/HttpController.coffee | 4 +- .../test/unit/coffee/DocManagerTests.coffee | 44 +++++++++++-------- .../unit/coffee/HttpControllerTests.coffee | 16 +++---- 4 files changed, 46 insertions(+), 35 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index c37b68152f..216002f8ee 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -9,7 +9,7 @@ module.exports = DocManager = # collection (which is all that this collection contains). In future, we should # migrate this version property to be part of the docs collection, to guarantee # consitency between lines and version when writing/reading, and for a simpler schema. - getDoc: (project_id, doc_id, callback = (error, doc) ->) -> + getDoc: (project_id, doc_id, filter = { version: false }, callback = (error, doc) ->) -> MongoManager.findDoc project_id, doc_id, (err, doc)-> if err? return callback(err) @@ -20,11 +20,14 @@ module.exports = DocManager = if err? logger.err err:err, project_id:project_id, doc_id:doc_id, "error unarchiving doc" return callback(err) - DocManager.getDoc project_id, doc_id, callback + DocManager.getDoc project_id, doc_id, filter, callback else - MongoManager.getDocVersion doc_id, (error, version) -> - return callback(error) if error? - doc.version = version + if filter.version + MongoManager.getDocVersion doc_id, (error, version) -> + return callback(error) if error? + doc.version = version + callback err, doc + else callback err, doc getAllDocs: (project_id, callback = (error, docs) ->) -> @@ -38,7 +41,7 @@ module.exports = DocManager = return callback(null, docs) updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) -> - DocManager.getDoc project_id, doc_id, (err, doc)-> + DocManager.getDoc project_id, doc_id, {version: true}, (err, doc)-> if err? and !(err instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" return callback(err) @@ -78,7 +81,7 @@ module.exports = DocManager = callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc deleteDoc: (project_id, doc_id, callback = (error) ->) -> - DocManager.getDoc project_id, doc_id, (error, doc) -> + DocManager.getDoc project_id, doc_id, {}, (error, doc) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, (error) -> diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 0dfb30c31e..e87d89ea64 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -10,7 +10,7 @@ module.exports = HttpController = doc_id = req.params.doc_id include_deleted = req.query?.include_deleted == "true" logger.log project_id: project_id, doc_id: doc_id, "getting doc" - DocManager.getDoc project_id, doc_id, (error, doc) -> + DocManager.getDoc project_id, doc_id, {version: true}, (error, doc) -> return next(error) if error? logger.log doc: doc, "got doc" if !doc? @@ -24,7 +24,7 @@ module.exports = HttpController = project_id = req.params.project_id doc_id = req.params.doc_id logger.log project_id: project_id, doc_id: doc_id, "getting raw doc" - DocManager.getDoc project_id, doc_id, (error, doc) -> + DocManager.getDoc project_id, doc_id, {version: false}, (error, doc) -> return next(error) if error? if !doc? res.send 404 diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index d16c30206b..58f26abaf3 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -33,7 +33,7 @@ describe "DocManager", -> describe "when the doc is in the doc collection", -> beforeEach -> @MongoManager.findDoc.yields(null, @doc) - @DocManager.getDoc @project_id, @doc_id, @callback + @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback it "should get the doc from the doc collection", -> @MongoManager.findDoc @@ -50,11 +50,19 @@ describe "DocManager", -> doc = @callback.args[0][1] doc.lines.should.equal @doc.lines doc.version.should.equal @version + + describe "without the version filter", -> + beforeEach -> + @MongoManager.findDoc.yields(null, @doc) + @DocManager.getDoc @project_id, @doc_id, {version: false}, @callback + + it "should not get the doc version from the docOps collection", -> + @MongoManager.getDocVersion.called.should.equal false describe "when MongoManager.findDoc errors", -> beforeEach -> @MongoManager.findDoc.yields(@stubbedError) - @DocManager.getDoc @project_id, @doc_id, @callback + @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback it "should return the error", -> @callback.calledWith(@stubbedError).should.equal true @@ -67,7 +75,7 @@ describe "DocManager", -> @doc.inS3 = false callback() sinon.spy @DocArchiveManager, "unarchiveDoc" - @DocManager.getDoc @project_id, @doc_id, @callback + @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback it "should call the DocArchive to unarchive the doc", -> @DocArchiveManager.unarchiveDoc.calledWith(@project_id, @doc_id).should.equal true @@ -81,7 +89,7 @@ describe "DocManager", -> describe "when the doc does not exist in the docs collection", -> beforeEach -> @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, null) - @DocManager.getDoc @project_id, @doc_id, @callback + @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback it "should return a NotFoundError", -> @callback @@ -120,7 +128,7 @@ describe "DocManager", -> beforeEach -> @lines = ["mock", "doc", "lines"] @rev = 77 - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, {lines: @lines, rev:@rev}) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, {lines: @lines, rev:@rev}) @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @MongoManager.markDocAsDeleted = sinon.stub().callsArg(1) @DocManager.deleteDoc @project_id, @doc_id, @callback @@ -145,7 +153,7 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, null) @MongoManager.upsertIntoDocCollection = sinon.stub() @DocManager.deleteDoc @project_id, @doc_id, @callback @@ -170,7 +178,7 @@ describe "DocManager", -> describe "when the doc lines have changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should get the existing doc", -> @@ -207,12 +215,12 @@ describe "DocManager", -> describe "when the version has changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @callback - it "should get the existing doc", -> + it "should get the existing doc with the version", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id) + .calledWith(@project_id, @doc_id, {version: true}) .should.equal true it "should upsert the document to the doc collection", -> @@ -230,12 +238,12 @@ describe "DocManager", -> describe "when the version is null and the lines are different", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @callback - it "should get the existing doc", -> + it "should get the existing doc with the version", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id) + .calledWith(@project_id, @doc_id, {version: true}) .should.equal true it "should upsert the document to the doc collection", -> @@ -253,7 +261,7 @@ describe "DocManager", -> describe "when the version is null and the lines are the same", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, null, @callback it "should not update the version", -> @@ -268,7 +276,7 @@ describe "DocManager", -> describe "when there is a generic error getting the doc", -> beforeEach -> @error = new Error("doc could not be found") - @DocManager.getDoc = sinon.stub().callsArgWith(2, @error, null, null) + @DocManager.getDoc = sinon.stub().callsArgWith(3, @error, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should not upsert the document to the doc collection", -> @@ -279,7 +287,7 @@ describe "DocManager", -> describe "when the doc lines have not changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @callback it "should not update the doc", -> @@ -291,7 +299,7 @@ describe "DocManager", -> describe "when the doc lines are an empty array", -> beforeEach -> @doc.lines = [] - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback it "should upsert the document to the doc collection", -> @@ -301,7 +309,7 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, null, null) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback it "should upsert the document to the doc collection", -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 4d9ae795ab..a34237982e 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -40,12 +40,12 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @HttpController.getDoc @req, @res, @next - it "should get the document (including deleted)", -> + it "should get the document with the version (including deleted)", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id) + .calledWith(@project_id, @doc_id, {version: true}) .should.equal true it "should return the doc as JSON", -> @@ -64,11 +64,11 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @deletedDoc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @deletedDoc) it "should get the doc from the doc manager", -> @HttpController.getDoc @req, @res, @next - @DocManager.getDoc.calledWith(@project_id, @doc_id).should.equal true + @DocManager.getDoc.calledWith(@project_id, @doc_id, {version: true}).should.equal true it "should return 404 if the query string delete is not set ", -> @HttpController.getDoc @req, @res, @next @@ -92,12 +92,12 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(2, null, @doc) + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @HttpController.getRawDoc @req, @res, @next - it "should get the document", -> + it "should get the document without the version", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id) + .calledWith(@project_id, @doc_id, {version: false}) .should.equal true it "should set the content type header", -> From e156d8017c4c1d3d6b064fff5b1a9fc6f531756e Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Wed, 30 Nov 2016 15:29:43 +0000 Subject: [PATCH 100/349] Be explicit in version filter --- services/docstore/app/coffee/DocManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 216002f8ee..e30370154e 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -81,7 +81,7 @@ module.exports = DocManager = callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc deleteDoc: (project_id, doc_id, callback = (error) ->) -> - DocManager.getDoc project_id, doc_id, {}, (error, doc) -> + DocManager.getDoc project_id, doc_id, { version: false }, (error, doc) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, (error) -> From ab527c3c5db51969d48c0cddb08aead067e436cf Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 2 Dec 2016 15:02:54 +0000 Subject: [PATCH 101/349] remove code left over from migration --- services/docstore/app/coffee/DocManager.coffee | 6 +----- services/docstore/app/coffee/MongoManager.coffee | 13 +++++++------ .../test/unit/coffee/DocManagerTests.coffee | 13 ++----------- .../test/unit/coffee/MongoManagerTests.coffee | 8 ++++---- 4 files changed, 14 insertions(+), 26 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index e30370154e..e49e96f03f 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -84,8 +84,4 @@ module.exports = DocManager = DocManager.getDoc project_id, doc_id, { version: false }, (error, doc) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? - MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, (error) -> - return callback(error) if error? - MongoManager.markDocAsDeleted doc_id, (error) -> - return callback(error) if error? - callback() + MongoManager.markDocAsDeleted project_id, doc_id, callback diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index e44c995490..d1c941e788 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -27,12 +27,13 @@ module.exports = MongoManager = db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback - markDocAsDeleted: (doc_id, callback)-> - update = - $set: {} - update.$set["deleted"] = true - db.docs.update _id: ObjectId(doc_id), update, (err)-> - callback(err) + markDocAsDeleted: (project_id, doc_id, callback)-> + db.docs.update { + _id: ObjectId(doc_id), + project_id: ObjectId(project_id) + }, { + $set: { deleted: true } + }, callback markDocAsArchived: (doc_id, rev, callback)-> update = diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 58f26abaf3..109c36a2b2 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -129,8 +129,7 @@ describe "DocManager", -> @lines = ["mock", "doc", "lines"] @rev = 77 @DocManager.getDoc = sinon.stub().callsArgWith(3, null, {lines: @lines, rev:@rev}) - @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) - @MongoManager.markDocAsDeleted = sinon.stub().callsArg(1) + @MongoManager.markDocAsDeleted = sinon.stub().callsArg(2) @DocManager.deleteDoc @project_id, @doc_id, @callback it "should get the doc", -> @@ -138,14 +137,9 @@ describe "DocManager", -> .calledWith(@project_id, @doc_id) .should.equal true - it "should update the doc lines", -> - @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @lines) - .should.equal true - it "should mark doc as deleted", -> @MongoManager.markDocAsDeleted - .calledWith(@doc_id) + .calledWith(@project_id, @doc_id) .should.equal true it "should return the callback", -> @@ -154,11 +148,8 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(3, null, null) - @MongoManager.upsertIntoDocCollection = sinon.stub() @DocManager.deleteDoc @project_id, @doc_id, @callback - it "should not try to insert a deleted doc", -> - @MongoManager.upsertIntoDocCollection.called.should.equal false it "should return a NotFoundError", -> @callback diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 54a352417a..cf1479a880 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -76,15 +76,15 @@ describe "MongoManager", -> @db.docs.update = sinon.stub().callsArgWith(2, @stubbedErr) @oldRev = 77 - it "should process the update", (done)-> - @MongoManager.markDocAsDeleted @doc_id, (err)=> + it "should process the update", (done) -> + @MongoManager.markDocAsDeleted @project_id, @doc_id, (err)=> args = @db.docs.update.args[0] - assert.deepEqual args[0], {_id: ObjectId(@doc_id)} + assert.deepEqual args[0], {_id: ObjectId(@doc_id), project_id: ObjectId(@project_id)} assert.equal args[1]["$set"]["deleted"], true done() it "should return the error", (done)-> - @MongoManager.markDocAsDeleted @doc_id, (err)=> + @MongoManager.markDocAsDeleted @project_id, @doc_id, (err)=> err.should.equal @stubbedErr done() From 144bae3a5557291d9719598d93ac00e7d6d9315f Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 2 Dec 2016 15:17:38 +0000 Subject: [PATCH 102/349] Add an error guard around the version being present --- .../docstore/app/coffee/DocManager.coffee | 19 +++------- .../docstore/app/coffee/HealthChecker.coffee | 2 +- .../docstore/app/coffee/HttpController.coffee | 5 +++ .../acceptance/coffee/ArchiveDocsTests.coffee | 4 +- .../coffee/GettingAllDocsTests.coffee | 2 +- .../coffee/UpdatingDocsTests.coffee | 30 +++++++++++---- .../test/unit/coffee/DocManagerTests.coffee | 37 ++++--------------- .../unit/coffee/HttpControllerTests.coffee | 26 ++++++------- 8 files changed, 56 insertions(+), 69 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index e49e96f03f..64b5b41522 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -41,6 +41,9 @@ module.exports = DocManager = return callback(null, docs) updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) -> + if !lines? or !version? + return callback(new Error("no lines or version provided")) + DocManager.getDoc project_id, doc_id, {version: true}, (err, doc)-> if err? and !(err instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" @@ -48,10 +51,7 @@ module.exports = DocManager = isNewDoc = lines.length == 0 linesAreSame = _.isEqual(doc?.lines, lines) - if version? - versionsAreSame = (doc?.version == version) - else - versionsAreSame = true + versionsAreSame = (doc?.version == version) if linesAreSame and versionsAreSame and !isNewDoc logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating" @@ -69,15 +69,8 @@ module.exports = DocManager = }, "updating doc lines" MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)-> return callback(callback) if error? - # TODO: While rolling out this code, setting the version via the docstore is optional, - # so if it hasn't been passed, just ignore it. Once the docupdater has totally - # handed control of this to the docstore, we can assume it will always be passed - # and an error guard on it not being set instead. - if version? - MongoManager.setDocVersion doc_id, version, (error) -> - return callback(error) if error? - callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc - else + MongoManager.setDocVersion doc_id, version, (error) -> + return callback(error) if error? callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc deleteDoc: (project_id, doc_id, callback = (error) ->) -> diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index d0c181143d..639d752477 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -19,7 +19,7 @@ module.exports = jobs = [ (cb)-> opts = getOpts() - opts.json = {lines: lines} + opts.json = {lines: lines, version: 42} request.post(opts, cb) (cb)-> opts = getOpts() diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index e87d89ea64..5425b78c13 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -55,6 +55,11 @@ module.exports = HttpController = logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided" res.send 400 # Bad Request return + + if !version? or typeof version is not "number" + logger.error project_id: project_id, doc_id: doc_id, "no doc version provided" + res.send 400 # Bad Request + return logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc" DocManager.updateDoc project_id, doc_id, lines, version, (error, modified, rev) -> diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 26c57e7712..0d602b49cb 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -30,7 +30,7 @@ describe "Archiving all docs", -> (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, 42, callback async.series jobs, done afterEach (done) -> @@ -109,7 +109,7 @@ describe "Archiving all docs", -> quarterMegInBytes = 250000 lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") @docs[1].lines = [lines,lines,lines,lines] - DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, null, => + DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, 42, => DocstoreClient.archiveAllDoc @project_id, (error, @res) => done() diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index eb4261b7ae..6a9c164001 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -27,7 +27,7 @@ describe "Getting all docs", -> (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, 42, callback async.series jobs, done it "should return all the docs", (done) -> diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 5f21f55845..0fdf3ae0b2 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -18,9 +18,9 @@ describe "Applying updates to a doc", -> throw error if error? done() - describe "when the content has changed", -> + describe "when the lines have changed", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @newLines, null, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @version, (error, res, @body) => done() it "should return modified = true", -> @@ -35,9 +35,9 @@ describe "Applying updates to a doc", -> doc.version.should.equal @version done() - describe "when the content has not been updated", -> + describe "when the lines and version have not been updated", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, (error, res, @body) => done() it "should return modified = false", -> @@ -51,7 +51,7 @@ describe "Applying updates to a doc", -> describe "when the doc does not exist", -> beforeEach (done) -> @missing_doc_id = ObjectId() - DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, null, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, 0, (error, @res, @body) => done() it "should create the doc", -> @@ -66,7 +66,7 @@ describe "Applying updates to a doc", -> describe "when malformed doc lines are provided", -> describe "when the lines are not an array", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, null, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @version, (error, @res, @body) => done() it "should return 400", -> @@ -79,7 +79,7 @@ describe "Applying updates to a doc", -> describe "when the lines are not present", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, null, null, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, null, @version, (error, @res, @body) => done() it "should return 400", -> @@ -89,12 +89,26 @@ describe "Applying updates to a doc", -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @originalLines done() + + describe "when no version is provided", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, (error, @res, @body) => + done() + + it "should return 400", -> + @res.statusCode.should.equal 400 + + it "should not update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + doc.version.should.equal @version + done() describe "when the content is large", -> beforeEach (done) -> line = new Array(1025).join("x") # 1kb @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, null, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, (error, res, @body) => done() it "should return modified = true", -> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 109c36a2b2..676a7fbe02 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -227,42 +227,19 @@ describe "DocManager", -> it "should return the callback with the new rev", -> @callback.calledWith(null, true, @rev + 1).should.equal true - describe "when the version is null and the lines are different", -> + describe "when the version is null", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @callback - it "should get the existing doc with the version", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id, {version: true}) - .should.equal true + it "should return an error", -> + @callback.calledWith(new Error("no lines or version provided")).should.equal true - it "should upsert the document to the doc collection", -> - @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @newDocLines) - .should.equal true - - it "should not update the version", -> - @MongoManager.setDocVersion - .called - .should.equal false - - it "should return the callback with the new rev", -> - @callback.calledWith(null, true, @rev + 1).should.equal true - - describe "when the version is null and the lines are the same", -> + describe "when the lines are null", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, null, @callback - - it "should not update the version", -> - @MongoManager.setDocVersion.called.should.equal false + @DocManager.updateDoc @project_id, @doc_id, null, @version, @callback - it "should not update the doc", -> - @MongoManager.upsertIntoDocCollection.called.should.equal false - - it "should return the callback with the existing rev", -> - @callback.calledWith(null, false, @rev).should.equal true + it "should return an error", -> + @callback.calledWith(new Error("no lines or version provided")).should.equal true describe "when there is a generic error getting the doc", -> beforeEach -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index a34237982e..8293eb7b40 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -195,12 +195,13 @@ describe "HttpController", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] + version: @version = 42 @DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should update the document", -> @DocManager.updateDoc - .calledWith(@project_id, @doc_id, @lines, undefined) + .calledWith(@project_id, @doc_id, @lines, @version) .should.equal true it "should return a modified status", -> @@ -212,6 +213,7 @@ describe "HttpController", -> beforeEach -> @req.body = lines: @lines = ["hello", "world"] + version: @version = 42 @DocManager.updateDoc = sinon.stub().yields(null, false, @rev = 5) @HttpController.updateDoc @req, @res, @next @@ -222,7 +224,7 @@ describe "HttpController", -> describe "when the doc lines are not provided", -> beforeEach -> - @req.body = {} + @req.body = { version: 42 } @DocManager.updateDoc = sinon.stub().yields(null, false) @HttpController.updateDoc @req, @res, @next @@ -234,22 +236,18 @@ describe "HttpController", -> .calledWith(400) .should.equal true - describe "when the doc version is provided", -> + describe "when the doc version is not provided", -> beforeEach -> - @req.body = - lines: @lines = ["hello", "world"] - version: @version = 42 - @DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5) + @req.body = { lines : [ "foo" ]} + @DocManager.updateDoc = sinon.stub().yields(null, false) @HttpController.updateDoc @req, @res, @next - it "should update the document with the lines and version", -> - @DocManager.updateDoc - .calledWith(@project_id, @doc_id, @lines, @version) - .should.equal true + it "should not update the document", -> + @DocManager.updateDoc.called.should.equal false - it "should return a modified status", -> - @res.json - .calledWith(modified: true, rev: @rev) + it "should return a 400 (bad request) response", -> + @res.send + .calledWith(400) .should.equal true describe "deleteDoc", -> From ca96d168dde5839e7bbea24e9dcd09f01ba128e2 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 2 Dec 2016 15:22:08 +0000 Subject: [PATCH 103/349] Make attributes that can be set in mongo flexible --- .../docstore/app/coffee/DocArchiveManager.coffee | 2 +- services/docstore/app/coffee/DocManager.coffee | 2 +- services/docstore/app/coffee/MongoManager.coffee | 14 ++++++-------- .../test/unit/coffee/DocManagerTests.coffee | 8 ++++---- .../test/unit/coffee/MongoManagerTests.coffee | 4 ++-- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 5e0272466c..345f751f2a 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -67,7 +67,7 @@ module.exports = DocArchive = if err? || res.statusCode != 200 logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong unarchiving doc from aws" return callback new Errors.NotFoundError("Error in S3 request") - MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), lines, (err) -> + MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), {lines}, (err) -> return callback(err) if err? logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" request.del options, (err, res, body)-> diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 64b5b41522..09218ed5b8 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -67,7 +67,7 @@ module.exports = DocManager = oldVersion: doc?.version newVersion: version }, "updating doc lines" - MongoManager.upsertIntoDocCollection project_id, doc_id, lines, (error)-> + MongoManager.upsertIntoDocCollection project_id, doc_id, {lines}, (error)-> return callback(callback) if error? MongoManager.setDocVersion doc_id, version, (error) -> return callback(error) if error? diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index d1c941e788..73820dbd09 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -15,18 +15,16 @@ module.exports = MongoManager = inS3: true db.docs.find query, {}, callback - upsertIntoDocCollection: (project_id, doc_id, lines, callback)-> + upsertIntoDocCollection: (project_id, doc_id, updates, callback)-> update = - $set:{} - $inc:{} - $unset:{} - update.$set["lines"] = lines + $set: updates + $inc: + rev: 1 + $unset: + inS3: true update.$set["project_id"] = ObjectId(project_id) - update.$inc["rev"] = 1 #on new docs being created this will set the rev to 1 - update.$unset["inS3"] = true db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback - markDocAsDeleted: (project_id, doc_id, callback)-> db.docs.update { _id: ObjectId(doc_id), diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 676a7fbe02..95cda2b95c 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -179,7 +179,7 @@ describe "DocManager", -> it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @newDocLines) + .calledWith(@project_id, @doc_id, {lines: @newDocLines}) .should.equal true it "should update the version", -> @@ -216,7 +216,7 @@ describe "DocManager", -> it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @oldDocLines) + .calledWith(@project_id, @doc_id, {lines: @oldDocLines}) .should.equal true it "should update the version", -> @@ -272,7 +272,7 @@ describe "DocManager", -> it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @doc.lines) + .calledWith(@project_id, @doc_id, {lines: @doc.lines}) .should.equal true describe "when the doc does not exist", -> @@ -282,7 +282,7 @@ describe "DocManager", -> it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, @newDocLines) + .calledWith(@project_id, @doc_id, {lines: @newDocLines}) .should.equal true it "should return the callback with the new rev", -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index cf1479a880..19a68c4d79 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -58,7 +58,7 @@ describe "MongoManager", -> @oldRev = 77 it "should upsert the document", (done)-> - @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, (err)=> + @MongoManager.upsertIntoDocCollection @project_id, @doc_id, {@lines}, (err)=> args = @db.docs.update.args[0] assert.deepEqual args[0], {_id: ObjectId(@doc_id)} assert.equal args[1]["$set"]["lines"], @lines @@ -67,7 +67,7 @@ describe "MongoManager", -> done() it "should return the error", (done)-> - @MongoManager.upsertIntoDocCollection @project_id, @doc_id, @lines, (err)=> + @MongoManager.upsertIntoDocCollection @project_id, @doc_id, {@lines}, (err)=> err.should.equal @stubbedErr done() From 0a65a5eabf564308765affe91eccb9d705368199 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 5 Dec 2016 14:21:49 +0000 Subject: [PATCH 104/349] Set and get ranges along with lines --- .../docstore/app/coffee/DocManager.coffee | 68 ++++++--- .../docstore/app/coffee/HttpController.coffee | 5 +- .../docstore/app/coffee/RangeManager.coffee | 35 +++++ .../acceptance/coffee/ArchiveDocsTests.coffee | 22 ++- .../coffee/DeletingDocsTests.coffee | 3 +- .../coffee/GettingAllDocsTests.coffee | 6 +- .../acceptance/coffee/GettingDocsTests.coffee | 20 ++- .../coffee/UpdatingDocsTests.coffee | 130 +++++++++++------ .../coffee/helpers/DocstoreClient.coffee | 18 +-- .../test/unit/coffee/DocManagerTests.coffee | 131 ++++++++++++------ .../unit/coffee/HttpControllerTests.coffee | 3 +- 11 files changed, 294 insertions(+), 147 deletions(-) create mode 100644 services/docstore/app/coffee/RangeManager.coffee diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 09218ed5b8..df63383bb1 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -3,6 +3,7 @@ Errors = require "./Errors" logger = require "logger-sharelatex" _ = require "underscore" DocArchive = require "./DocArchiveManager" +RangeManager = require "./RangeManager" module.exports = DocManager = # TODO: For historical reasons, the doc version is currently stored in the docOps @@ -40,7 +41,7 @@ module.exports = DocManager = else return callback(null, docs) - updateDoc: (project_id, doc_id, lines, version, callback = (error, modified, rev) ->) -> + updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) -> if !lines? or !version? return callback(new Error("no lines or version provided")) @@ -48,33 +49,56 @@ module.exports = DocManager = if err? and !(err instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" return callback(err) + + ranges = RangeManager.jsonRangesToMongo(ranges) - isNewDoc = lines.length == 0 - linesAreSame = _.isEqual(doc?.lines, lines) - versionsAreSame = (doc?.version == version) - - if linesAreSame and versionsAreSame and !isNewDoc - logger.log project_id: project_id, doc_id: doc_id, rev: doc?.rev, "doc lines have not changed - not updating" - return callback null, false, doc?.rev + if !doc? + # If the document doesn't exist, we'll make sure to create/update all parts of it. + updateLines = true + updateVersion = true + updateRanges = true else - oldRev = doc?.rev || 0 - logger.log { - project_id: project_id - doc_id: doc_id, - oldDocLines: doc?.lines - newDocLines: lines - rev: oldRev - oldVersion: doc?.version - newVersion: version - }, "updating doc lines" - MongoManager.upsertIntoDocCollection project_id, doc_id, {lines}, (error)-> + updateLines = not _.isEqual(doc.lines, lines) + updateVersion = (doc.version != version) + updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges) + + modified = false + rev = doc?.rev || 0 + + updateLinesAndRangesIfNeeded = (cb) -> + if updateLines or updateRanges + update = {} + if updateLines + update.lines = lines + if updateRanges + update.ranges = ranges + logger.log { project_id, doc_id, oldDoc: doc, update: update }, "updating doc lines and ranges" + + modified = true + rev += 1 # rev will be incremented in mongo by MongoManager.upsertIntoDocCollection + MongoManager.upsertIntoDocCollection project_id, doc_id, update, cb + else + logger.log { project_id, doc_id, }, "doc lines have not changed - not updating" + cb() + + updateVersionIfNeeded = (cb) -> + if updateVersion + logger.log { project_id, doc_id, oldVersion: doc?.version, newVersion: version }, "updating doc version" + modified = true + MongoManager.setDocVersion doc_id, version, cb + else + logger.log { project_id, doc_id, version }, "doc version has not changed - not updating" + cb() + + updateLinesAndRangesIfNeeded (error) -> + return callback(error) if error? + updateVersionIfNeeded (error) -> return callback(callback) if error? - MongoManager.setDocVersion doc_id, version, (error) -> - return callback(error) if error? - callback null, true, oldRev + 1 # rev will have been incremented in mongo by MongoManager.updateDoc + callback null, modified, rev deleteDoc: (project_id, doc_id, callback = (error) ->) -> DocManager.getDoc project_id, doc_id, { version: false }, (error, doc) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? MongoManager.markDocAsDeleted project_id, doc_id, callback + diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 5425b78c13..cae8fedb53 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -50,6 +50,7 @@ module.exports = HttpController = doc_id = req.params.doc_id lines = req.body?.lines version = req.body?.version + ranges = req.body?.ranges if !lines? or lines not instanceof Array logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided" @@ -62,7 +63,7 @@ module.exports = HttpController = return logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc" - DocManager.updateDoc project_id, doc_id, lines, version, (error, modified, rev) -> + DocManager.updateDoc project_id, doc_id, lines, version, ranges, (error, modified, rev) -> return next(error) if error? res.json { modified: modified @@ -86,6 +87,8 @@ module.exports = HttpController = } if doc.version? doc_view.version = doc.version + if doc.ranges? + doc_view.ranges = doc.ranges return doc_view _buildRawDocView: (doc)-> diff --git a/services/docstore/app/coffee/RangeManager.coffee b/services/docstore/app/coffee/RangeManager.coffee new file mode 100644 index 0000000000..9cc65677d4 --- /dev/null +++ b/services/docstore/app/coffee/RangeManager.coffee @@ -0,0 +1,35 @@ +_ = require "underscore" +{ObjectId} = require("./mongojs") + +module.exports = RangeManager = + shouldUpdateRanges: (doc_ranges, incoming_ranges) -> + # TODO: If we have no incoming_ranges, just ignore for now while + # we're rolling this out, but eventually this should be a mandatory + # field and this will become an error condition + return false if !incoming_ranges? + + # If the ranges are empty, we don't store them in the DB, so set + # doc_ranges to an empty object as default, since this is was the + # incoming_ranges will be for an empty range set. + if !doc_ranges? + doc_ranges = {} + + return not _.isEqual(doc_ranges, incoming_ranges) + + jsonRangesToMongo: (ranges) -> + return null if !ranges? + for change in ranges.changes or [] + change.id = @_safeObjectId(change.id) + if change.metadata?.ts? + change.metadata.ts = new Date(change.metadata.ts) + for comment in ranges.comments or [] + comment.id = @_safeObjectId(comment.id) + if comment.metadata?.ts? + comment.metadata.ts = new Date(comment.metadata.ts) + return ranges + + _safeObjectId: (data) -> + try + return ObjectId(data) + catch + return data \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 0d602b49cb..80204da731 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -8,7 +8,7 @@ Settings = require("settings-sharelatex") DocstoreClient = require "./helpers/DocstoreClient" -describe "Archiving all docs", -> +describe "Archiving", -> beforeEach (done) -> @callback = sinon.stub() @project_id = ObjectId() @@ -25,18 +25,19 @@ describe "Archiving all docs", -> lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] rev: 6 }] + @version = 42 + @ranges = [] jobs = for doc in @docs do (doc) => (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + DocstoreClient.createDoc @project_id, doc._id, doc.lines, @version, @ranges, (err)=> doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, 42, callback + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, @version, @ranges, callback async.series jobs, done afterEach (done) -> db.docs.remove({project_id: @project_id}, done) - describe "Archiving all docs", -> beforeEach (done) -> @@ -101,18 +102,17 @@ describe "Archiving all docs", -> callback() async.series jobs, done - - - describe "archiving massive document", (done)-> + describe "Archiving a large document", (done)-> beforeEach (done)-> @timeout 1000 * 30 quarterMegInBytes = 250000 lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") @docs[1].lines = [lines,lines,lines,lines] - DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, 42, => + @version = 42 + @ranges = [] + DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, @version, @ranges, () => DocstoreClient.archiveAllDoc @project_id, (error, @res) => done() - it "should archive all the docs", (done) -> @res.statusCode.should.equal 204 @@ -129,7 +129,6 @@ describe "Archiving all docs", -> async.series jobs, done it "should be able get the same docs back", (done) -> - jobs = for archiveDoc in @docs do (archiveDoc) => (callback) => @@ -138,8 +137,7 @@ describe "Archiving all docs", -> callback() async.series jobs, done - describe "Unarchiving all docs", -> - + describe "Unarchiving", -> it "should unarchive all the docs", (done) -> DocstoreClient.archiveAllDoc @project_id, (error, res) => DocstoreClient.getAllDocs @project_id, (error, res, docs) => diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee index d2d5a05727..82dbfb4c66 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -11,7 +11,8 @@ describe "Deleting a doc", -> @doc_id = ObjectId() @lines = ["original", "lines"] @version = 42 - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + @ranges = [] + DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => throw error if error? done() diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index 6a9c164001..33128c5da2 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -22,12 +22,14 @@ describe "Getting all docs", -> lines: ["111", "222", "333"] rev: 6 }] + version = 42 + ranges = 42 jobs = for doc in @docs do (doc) => (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> + DocstoreClient.createDoc @project_id, doc._id, doc.lines, version, ranges, (err)=> doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, 42, callback + DocstoreClient.updateDoc @project_id, doc._id, doc.lines, version, ranges, callback async.series jobs, done it "should return all the docs", (done) -> diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index 345f29f89f..b17a294f24 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -10,7 +10,17 @@ describe "Getting a doc", -> @project_id = ObjectId() @doc_id = ObjectId() @lines = ["original", "lines"] - DocstoreClient.createDoc @project_id, @doc_id, @lines, (error) => + @version = 42 + @ranges = { + changes: [{ + id: ObjectId().toString() + op: { i: "foo", p: 3 } + meta: + user_id: ObjectId().toString() + ts: new Date().toString() + }] + } + DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => throw error if error? done() @@ -18,6 +28,8 @@ describe "Getting a doc", -> it "should get the doc lines and version", (done) -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @lines + doc.version.should.equal @version + doc.ranges.should.deep.equal @ranges done() describe "when the doc does not exist", -> @@ -30,11 +42,15 @@ describe "Getting a doc", -> describe "when the doc is a deleted doc", -> beforeEach (done) -> @deleted_doc_id = ObjectId() - DocstoreClient.createDeletedDoc @project_id, @deleted_doc_id, @lines, done + DocstoreClient.createDoc @project_id, @deleted_doc_id, @lines, @version, @ranges, (error) => + throw error if error? + DocstoreClient.deleteDoc @project_id, @deleted_doc_id, done it "should return the doc", (done) -> DocstoreClient.getDoc @project_id, @deleted_doc_id, {include_deleted:true},(error, res, doc) => doc.lines.should.deep.equal @lines + doc.version.should.equal @version + doc.ranges.should.deep.equal @ranges doc.deleted.should.equal true done() diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 0fdf3ae0b2..0dd60baa05 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -11,33 +11,32 @@ describe "Applying updates to a doc", -> @doc_id = ObjectId() @originalLines = ["original", "lines"] @newLines = ["new", "lines"] + @originalRanges = { + changes: [{ + id: ObjectId().toString() + op: { i: "foo", p: 3 } + meta: + user_id: ObjectId().toString() + ts: new Date().toString() + }] + } + @newRanges = { + changes: [{ + id: ObjectId().toString() + op: { i: "bar", p: 6 } + meta: + user_id: ObjectId().toString() + ts: new Date().toString() + }] + } @version = 42 - DocstoreClient.createDoc @project_id, @doc_id, @originalLines, (error) => + DocstoreClient.createDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error) => throw error if error? - DocstoreClient.setDocVersion @doc_id, @version, (error) => - throw error if error? - done() + done() - describe "when the lines have changed", -> + describe "when nothing has been updated", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @version, (error, res, @body) => - done() - - it "should return modified = true", -> - @body.modified.should.equal true - - it "should return the rev", -> - @body.rev.should.equal 2 - - it "should update the doc in the API but not change the version", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @newLines - doc.version.should.equal @version - done() - - describe "when the lines and version have not been updated", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error, res, @body) => done() it "should return modified = false", -> @@ -46,12 +45,68 @@ describe "Applying updates to a doc", -> it "should not update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @originalLines + doc.version.should.equal @version + doc.ranges.should.deep.equal @originalRanges + done() + + describe "when the lines have changed", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @version, @originalRanges, (error, res, @body) => + done() + + it "should return modified = true", -> + @body.modified.should.equal true + + it "should return the rev", -> + @body.rev.should.equal 2 + + it "should update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @newLines + doc.version.should.equal @version + doc.ranges.should.deep.equal @originalRanges + done() + + describe "when the version has changed", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version + 1, @originalRanges, (error, res, @body) => + done() + + it "should return modified = true", -> + @body.modified.should.equal true + + it "should return the rev", -> + @body.rev.should.equal 2 + + it "should update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + doc.version.should.equal @version + 1 + doc.ranges.should.deep.equal @originalRanges + done() + + describe "when the ranges have changed", -> + beforeEach (done) -> + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, @newRanges, (error, res, @body) => + done() + + it "should return modified = true", -> + @body.modified.should.equal true + + it "should return the rev", -> + @body.rev.should.equal 2 + + it "should update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + doc.version.should.equal @version + doc.ranges.should.deep.equal @newRanges done() describe "when the doc does not exist", -> beforeEach (done) -> @missing_doc_id = ObjectId() - DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, 0, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, 0, @originalRanges, (error, @res, @body) => done() it "should create the doc", -> @@ -61,12 +116,13 @@ describe "Applying updates to a doc", -> DocstoreClient.getDoc @project_id, @missing_doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @originalLines doc.version.should.equal 0 + doc.ranges.should.deep.equal @originalRanges done() describe "when malformed doc lines are provided", -> describe "when the lines are not an array", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @version, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @version, @originalRanges, (error, @res, @body) => done() it "should return 400", -> @@ -79,7 +135,7 @@ describe "Applying updates to a doc", -> describe "when the lines are not present", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, null, @version, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, null, @version, @originalRanges, (error, @res, @body) => done() it "should return 400", -> @@ -92,7 +148,7 @@ describe "Applying updates to a doc", -> describe "when no version is provided", -> beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, (error, @res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, @originalRanges, (error, @res, @body) => done() it "should return 400", -> @@ -108,7 +164,7 @@ describe "Applying updates to a doc", -> beforeEach (done) -> line = new Array(1025).join("x") # 1kb @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, (error, res, @body) => + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, res, @body) => done() it "should return modified = true", -> @@ -118,21 +174,3 @@ describe "Applying updates to a doc", -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @largeLines done() - - describe "when the version has changed", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version + 1, (error, res, @body) => - done() - - it "should return modified = true", -> - @body.modified.should.equal true - - it "should return the rev", -> - @body.rev.should.equal 2 - - it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - doc.version.should.equal @version + 1 - done() - diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 6c12628826..b4ccdcb418 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -5,19 +5,8 @@ DocArchiveManager = require("../../../../app/js/DocArchiveManager.js") module.exports = DocstoreClient = - createDoc: (project_id, doc_id, lines, callback = (error) ->) -> - db.docs.save({_id: doc_id, project_id:project_id, lines: lines, rev:1}, callback) - - setDocVersion: (doc_id, version, callback = (error) ->) -> - db.docOps.save({doc_id: doc_id, version: version}, callback) - - createDeletedDoc: (project_id, doc_id, lines, callback = (error) ->) -> - db.docs.insert { - _id: doc_id - project_id: project_id - lines: lines - deleted: true - }, callback + createDoc: (project_id, doc_id, lines, version, ranges, callback = (error) ->) -> + DocstoreClient.updateDoc project_id, doc_id, lines, version, ranges, callback getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) -> request.get { @@ -32,12 +21,13 @@ module.exports = DocstoreClient = json: true }, callback - updateDoc: (project_id, doc_id, lines, version, callback = (error, res, body) ->) -> + updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, res, body) ->) -> request.post { url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" json: lines: lines version: version + ranges: ranges }, callback deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 95cda2b95c..f88ca914b4 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -12,6 +12,10 @@ describe "DocManager", -> @DocManager = SandboxedModule.require modulePath, requires: "./MongoManager": @MongoManager = {} "./DocArchiveManager": @DocArchiveManager = {} + "./RangeManager": @RangeManager = { + jsonRangesToMongo: (r) -> r + shouldUpdateRanges: sinon.stub().returns false + } "logger-sharelatex": @logger = log: sinon.stub() warn:-> @@ -160,17 +164,35 @@ describe "DocManager", -> beforeEach -> @oldDocLines = ["old", "doc", "lines"] @newDocLines = ["new", "doc", "lines"] + @originalRanges = { + changes: [{ + id: ObjectId().toString() + op: { i: "foo", p: 3 } + meta: + user_id: ObjectId().toString() + ts: new Date().toString() + }] + } + @newRanges = { + changes: [{ + id: ObjectId().toString() + op: { i: "bar", p: 6 } + meta: + user_id: ObjectId().toString() + ts: new Date().toString() + }] + } @version = 42 - @doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5, version: @version } + @doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5, version: @version, ranges: @originalRanges } @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @MongoManager.setDocVersion = sinon.stub().yields() @DocManager.getDoc = sinon.stub() - describe "when the doc lines have changed", -> + describe "when only the doc lines have changed", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback it "should get the existing doc", -> @DocManager.getDoc @@ -182,61 +204,84 @@ describe "DocManager", -> .calledWith(@project_id, @doc_id, {lines: @newDocLines}) .should.equal true - it "should update the version", -> - @MongoManager.setDocVersion - .calledWith(@doc_id, @version) - .should.equal true - - it "should log out the old and new doc lines", -> - @logger.log - .calledWith( - project_id: @project_id - doc_id: @doc_id - oldDocLines: @oldDocLines - newDocLines: @newDocLines - rev: @doc.rev - oldVersion: @version - newVersion: @version - "updating doc lines" - ) - .should.equal true + it "should not update the version", -> + @MongoManager.setDocVersion.called.should.equal false it "should return the callback with the new rev", -> @callback.calledWith(null, true, @rev + 1).should.equal true - describe "when the version has changed", -> + describe "when the doc ranges have changed", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @callback + @RangeManager.shouldUpdateRanges.returns true + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @newRanges, @callback + + it "should get the existing doc", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should upsert the ranges", -> + @MongoManager.upsertIntoDocCollection + .calledWith(@project_id, @doc_id, {ranges: @newRanges}) + .should.equal true + + it "should not update the version", -> + @MongoManager.setDocVersion.called.should.equal false + + it "should return the callback with the new rev", -> + @callback.calledWith(null, true, @rev + 1).should.equal true + + describe "when only the version has changed", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @originalRanges, @callback it "should get the existing doc with the version", -> @DocManager.getDoc .calledWith(@project_id, @doc_id, {version: true}) .should.equal true - it "should upsert the document to the doc collection", -> - @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, {lines: @oldDocLines}) - .should.equal true + it "should not change the lines or ranges", -> + @MongoManager.upsertIntoDocCollection.called.should.equal false it "should update the version", -> @MongoManager.setDocVersion .calledWith(@doc_id, @version + 1) .should.equal true - it "should return the callback with the new rev", -> - @callback.calledWith(null, true, @rev + 1).should.equal true + it "should return the callback with the old rev", -> + @callback.calledWith(null, true, @rev).should.equal true + + describe "when the doc has not changed at all", -> + beforeEach -> + @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @originalRanges, @callback + + it "should get the existing doc", -> + @DocManager.getDoc + .calledWith(@project_id, @doc_id) + .should.equal true + + it "should not update the ranges or lines", -> + @MongoManager.upsertIntoDocCollection.called.should.equal false + + it "should not update the version", -> + @MongoManager.setDocVersion.called.should.equal false + + it "should return the callback with the old rev and modified == false", -> + @callback.calledWith(null, false, @rev).should.equal true describe "when the version is null", -> beforeEach -> - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @originalRanges, @callback it "should return an error", -> @callback.calledWith(new Error("no lines or version provided")).should.equal true describe "when the lines are null", -> beforeEach -> - @DocManager.updateDoc @project_id, @doc_id, null, @version, @callback + @DocManager.updateDoc @project_id, @doc_id, null, @version, @originalRanges, @callback it "should return an error", -> @callback.calledWith(new Error("no lines or version provided")).should.equal true @@ -245,7 +290,7 @@ describe "DocManager", -> beforeEach -> @error = new Error("doc could not be found") @DocManager.getDoc = sinon.stub().callsArgWith(3, @error, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback it "should not upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection.called.should.equal false @@ -256,7 +301,7 @@ describe "DocManager", -> describe "when the doc lines have not changed", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @callback + @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @originalRanges, @callback it "should not update the doc", -> @MongoManager.upsertIntoDocCollection.called.should.equal false @@ -264,25 +309,19 @@ describe "DocManager", -> it "should return the callback with the existing rev", -> @callback.calledWith(null, false, @rev).should.equal true - describe "when the doc lines are an empty array", -> - beforeEach -> - @doc.lines = [] - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @doc.lines, @callback - - it "should upsert the document to the doc collection", -> - @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, {lines: @doc.lines}) - .should.equal true - describe "when the doc does not exist", -> beforeEach -> @DocManager.getDoc = sinon.stub().callsArgWith(3, null, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @callback + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback it "should upsert the document to the doc collection", -> @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, {lines: @newDocLines}) + .calledWith(@project_id, @doc_id, {lines: @newDocLines, ranges: @originalRanges}) + .should.equal true + + it "should set the version", -> + @MongoManager.setDocVersion + .calledWith(@doc_id, @version) .should.equal true it "should return the callback with the new rev", -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 8293eb7b40..839e960bca 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -196,12 +196,13 @@ describe "HttpController", -> @req.body = lines: @lines = ["hello", "world"] version: @version = 42 + ranges: @ranges = { changes: "mock" } @DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5) @HttpController.updateDoc @req, @res, @next it "should update the document", -> @DocManager.updateDoc - .calledWith(@project_id, @doc_id, @lines, @version) + .calledWith(@project_id, @doc_id, @lines, @version, @ranges) .should.equal true it "should return a modified status", -> From bd5086c05422e0f423f3bd995344e1e748998e77 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 5 Dec 2016 14:37:44 +0000 Subject: [PATCH 105/349] Don't return deleted docs with all project docs --- services/docstore/app/coffee/MongoManager.coffee | 2 +- .../test/acceptance/coffee/GettingAllDocsTests.coffee | 11 ++++++++++- .../test/unit/coffee/MongoManagerTests.coffee | 3 ++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index e44c995490..ef35756d0c 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -7,7 +7,7 @@ module.exports = MongoManager = callback error, docs[0] getProjectsDocs: (project_id, callback)-> - db.docs.find project_id: ObjectId(project_id.toString()), {}, callback + db.docs.find {project_id: ObjectId(project_id.toString()), deleted: { $ne: true }}, {}, callback getArchivedProjectDocs: (project_id, callback)-> query = diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index eb4261b7ae..4248513a74 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -22,15 +22,24 @@ describe "Getting all docs", -> lines: ["111", "222", "333"] rev: 6 }] + @deleted_doc = { + _id: ObjectId() + lines: ["deleted"] + rev: 8 + } jobs = for doc in @docs do (doc) => (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> doc.lines[0] = doc.lines[0]+" added" DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback + jobs.push (cb) => + DocstoreClient.createDoc @project_id, @deleted_doc._id, @deleted_doc.lines, (err)=> + DocstoreClient.updateDoc @project_id, @deleted_doc._id, @deleted_doc.lines, null, (err) => + DocstoreClient.deleteDoc @project_id, @deleted_doc._id, done async.series jobs, done - it "should return all the docs", (done) -> + it "should return all the (non-deleted) docs", (done) -> DocstoreClient.getAllDocs @project_id, (error, res, docs) => throw error if error? docs.length.should.equal @docs.length diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 54a352417a..5064bcffbc 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -42,10 +42,11 @@ describe "MongoManager", -> @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc, @doc3, @doc4]) @MongoManager.getProjectsDocs @project_id, @callback - it "should find the docs via the project_id", -> + it "should find the non-deleted docs via the project_id", -> @db.docs.find .calledWith({ project_id: ObjectId(@project_id) + deleted: { $ne: true } }, {}) .should.equal true From 2985cb587a5b7e83d033a764847424626f35b404 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 5 Dec 2016 15:38:38 +0000 Subject: [PATCH 106/349] Add tests for RangeManager --- .../docstore/app/coffee/RangeManager.coffee | 2 + .../test/unit/coffee/RangeManagerTests.coffee | 162 ++++++++++++++++++ 2 files changed, 164 insertions(+) create mode 100644 services/docstore/test/unit/coffee/RangeManagerTests.coffee diff --git a/services/docstore/app/coffee/RangeManager.coffee b/services/docstore/app/coffee/RangeManager.coffee index 9cc65677d4..4022d55d04 100644 --- a/services/docstore/app/coffee/RangeManager.coffee +++ b/services/docstore/app/coffee/RangeManager.coffee @@ -22,6 +22,8 @@ module.exports = RangeManager = change.id = @_safeObjectId(change.id) if change.metadata?.ts? change.metadata.ts = new Date(change.metadata.ts) + if change.metadata?.user_id? + change.metadata.user_id = @_safeObjectId(change.metadata.user_id) for comment in ranges.comments or [] comment.id = @_safeObjectId(comment.id) if comment.metadata?.ts? diff --git a/services/docstore/test/unit/coffee/RangeManagerTests.coffee b/services/docstore/test/unit/coffee/RangeManagerTests.coffee new file mode 100644 index 0000000000..bf8b01e7d7 --- /dev/null +++ b/services/docstore/test/unit/coffee/RangeManagerTests.coffee @@ -0,0 +1,162 @@ +SandboxedModule = require('sandboxed-module') +sinon = require('sinon') +require('chai').should() +modulePath = require('path').join __dirname, '../../../app/js/RangeManager' +ObjectId = require("mongojs").ObjectId +assert = require("chai").assert +_ = require "underscore" + +describe "RangeManager", -> + beforeEach -> + @RangeManager = SandboxedModule.require modulePath, requires: + "./mongojs": + ObjectId: ObjectId + + describe "jsonRangesToMongo", -> + it "should convert ObjectIds and dates to proper objects", -> + change_id = ObjectId().toString() + comment_id = ObjectId().toString() + user_id = ObjectId().toString() + ts = new Date().toJSON() + @RangeManager.jsonRangesToMongo({ + changes: [{ + id: change_id + op: { i: "foo", p: 3 } + metadata: + user_id: user_id + ts: ts + }] + comments: [{ + id: comment_id + offset: 42 + length: 5 + metadata: + ts: ts + }] + }).should.deep.equal { + changes: [{ + id: ObjectId(change_id) + op: { i: "foo", p: 3 } + metadata: + user_id: ObjectId(user_id) + ts: new Date(ts) + }] + comments: [{ + id: ObjectId(comment_id) + offset: 42 + length: 5 + metadata: + ts: new Date(ts) + }] + } + + it "should leave malformed ObjectIds as they are", -> + change_id = "foo" + comment_id = "bar" + user_id = "baz" + @RangeManager.jsonRangesToMongo({ + changes: [{ + id: change_id + metadata: + user_id: user_id + }] + comments: [{ + id: comment_id + }] + }).should.deep.equal { + changes: [{ + id: change_id + metadata: + user_id: user_id + }] + comments: [{ + id: comment_id + }] + } + + it "should be consistent when transformed through json -> mongo -> json", -> + change_id = ObjectId().toString() + comment_id = ObjectId().toString() + user_id = ObjectId().toString() + ts = new Date().toJSON() + ranges1 = { + changes: [{ + id: change_id + op: { i: "foo", p: 3 } + metadata: + user_id: user_id + ts: ts + }] + comments: [{ + id: comment_id + offset: 42 + length: 5 + metadata: + ts: ts + }] + } + ranges1_copy = JSON.parse(JSON.stringify(ranges1)) # jsonRangesToMongo modifies in place + ranges2 = JSON.parse(JSON.stringify(@RangeManager.jsonRangesToMongo(ranges1_copy))) + ranges1.should.deep.equal ranges2 + + describe "shouldUpdateRanges", -> + beforeEach () -> + @ranges = { + changes: [{ + id: ObjectId() + op: { i: "foo", p: 3 } + metadata: + user_id: ObjectId() + ts: new Date() + }] + comments: [{ + id: ObjectId() + offset: 42 + length: 5 + metadata: + ts: new Date() + }] + } + @ranges_copy = @RangeManager.jsonRangesToMongo(JSON.parse(JSON.stringify(@ranges))) + + describe "with a blank new range", -> + it "should return false", -> + @RangeManager.shouldUpdateRanges(@ranges, null).should.equal false + + describe "with a blank old range", -> + it "should treat it like {}", -> + @RangeManager.shouldUpdateRanges(null, {}).should.equal false + @RangeManager.shouldUpdateRanges(null, @ranges).should.equal true + + describe "with no changes", -> + it "should return false", -> + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal false + + describe "with changes", -> + it "should return true when the change id changes", -> + @ranges_copy.changes[0].id = ObjectId() + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + + it "should return true when the change user id changes", -> + @ranges_copy.changes[0].metadata.user_id = ObjectId() + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + + it "should return true when the change ts changes", -> + @ranges_copy.changes[0].metadata.ts = new Date(Date.now() + 1000) + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + + it "should return true when the change op changes", -> + @ranges_copy.changes[0].op.i = "bar" + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + + it "should return true when the comment id changes", -> + @ranges_copy.comments[0].id = ObjectId() + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + + it "should return true when the comment ts changes", -> + @ranges_copy.comments[0].metadata.ts = new Date(Date.now() + 1000) + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + + it "should return true when the comment offset changes", -> + @ranges_copy.comments[0].offset = 17 + @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true \ No newline at end of file From 77176255346b2db99b65391c6e258a0de72031d5 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 5 Dec 2016 16:31:51 +0000 Subject: [PATCH 107/349] Include deleted docs when archiving --- .../app/coffee/DocArchiveManager.coffee | 2 +- .../docstore/app/coffee/DocManager.coffee | 4 +- .../docstore/app/coffee/HttpController.coffee | 2 +- .../docstore/app/coffee/MongoManager.coffee | 7 +++- .../test/unit/coffee/DocArchiveManager.coffee | 10 ++--- .../test/unit/coffee/DocManagerTests.coffee | 12 +++--- .../unit/coffee/HttpControllerTests.coffee | 8 ++-- .../test/unit/coffee/MongoManagerTests.coffee | 37 ++++++++++++++----- 8 files changed, 51 insertions(+), 31 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 5e0272466c..52af544df6 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -11,7 +11,7 @@ thirtySeconds = 30 * 1000 module.exports = DocArchive = archiveAllDocs: (project_id, callback = (err, docs) ->) -> - MongoManager.getProjectsDocs project_id, (err, docs) -> + MongoManager.getProjectsDocs project_id, true, (err, docs) -> if err? return callback(err) else if !docs? diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index e30370154e..6ac4678343 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -30,9 +30,9 @@ module.exports = DocManager = else callback err, doc - getAllDocs: (project_id, callback = (error, docs) ->) -> + getAllNonDeletedDocs: (project_id, callback = (error, docs) ->) -> DocArchive.unArchiveAllDocs project_id, (error) -> - MongoManager.getProjectsDocs project_id, (error, docs) -> + MongoManager.getProjectsDocs project_id, false, (error, docs) -> if err? return callback(error) else if !docs? diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index e87d89ea64..c1fa3ed3d3 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -35,7 +35,7 @@ module.exports = HttpController = getAllDocs: (req, res, next = (error) ->) -> project_id = req.params.project_id logger.log project_id: project_id, "getting all docs" - DocManager.getAllDocs project_id, (error, docs = []) -> + DocManager.getAllNonDeletedDocs project_id, (error, docs = []) -> return next(error) if error? docViews = [] for doc in docs diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index ef35756d0c..13551639d7 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -6,8 +6,11 @@ module.exports = MongoManager = db.docs.find {_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, {}, (error, docs = []) -> callback error, docs[0] - getProjectsDocs: (project_id, callback)-> - db.docs.find {project_id: ObjectId(project_id.toString()), deleted: { $ne: true }}, {}, callback + getProjectsDocs: (project_id, include_deleted, callback)-> + query = {project_id: ObjectId(project_id.toString())} + if !include_deleted + query.deleted = { $ne: true } + db.docs.find query, {}, callback getArchivedProjectDocs: (project_id, callback)-> query = diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index d55e870070..05abcc0fb3 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -64,7 +64,7 @@ describe "DocArchiveManager", -> @MongoManager = markDocAsArchived: sinon.stub().callsArgWith(2, null) upsertIntoDocCollection: sinon.stub().callsArgWith(3, null) - getProjectsDocs: sinon.stub().callsArgWith(1, null, @mongoDocs) + getProjectsDocs: sinon.stub().callsArgWith(2, null, @mongoDocs) getArchivedProjectDocs: sinon.stub().callsArgWith(1, null, @mongoDocs) @requires = @@ -127,7 +127,7 @@ describe "DocArchiveManager", -> describe "archiveAllDocs", -> it "should archive all project docs which are not in s3", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @mongoDocs) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, @mongoDocs) @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) @DocArchiveManager.archiveAllDocs @project_id, (err)=> @@ -142,14 +142,14 @@ describe "DocArchiveManager", -> done() it "should return error if have no docs", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, null) @DocArchiveManager.archiveAllDocs @project_id, (err)=> should.exist err done() it "should return the error", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, @error, null) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, @error, null) @DocArchiveManager.archiveAllDocs @project_id, (err)=> err.should.equal @error @@ -163,7 +163,7 @@ describe "DocArchiveManager", -> while --numberOfDocs != 0 @mongoDocs.push({inS3:true, _id: ObjectId()}) - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @mongoDocs) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, @mongoDocs) @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) it "should not throw and error", (done)-> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 58f26abaf3..a932e5dac9 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -96,17 +96,17 @@ describe "DocManager", -> .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id} in project #{@project_id}")) .should.equal true - describe "getAllDocs", -> + describe "getAllNonDeletedDocs", -> describe "when the project exists", -> beforeEach -> @docs = [{ _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] }] - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, @docs) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, @docs) @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, @docs) - @DocManager.getAllDocs @project_id, @callback + @DocManager.getAllNonDeletedDocs @project_id, @callback it "should get the project from the database", -> @MongoManager.getProjectsDocs - .calledWith(@project_id) + .calledWith(@project_id, false) .should.equal true it "should return the docs", -> @@ -114,9 +114,9 @@ describe "DocManager", -> describe "when there are no docs for the project", -> beforeEach -> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(1, null, null) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, null) @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, null) - @DocManager.getAllDocs @project_id, @callback + @DocManager.getAllNonDeletedDocs @project_id, @callback it "should return a NotFoundError", -> @callback diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index a34237982e..592ee9c407 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -120,11 +120,11 @@ describe "HttpController", -> lines: ["mock", "lines", "two"] rev: 4 }] - @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) + @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(1, null, @docs) @HttpController.getAllDocs @req, @res, @next - it "should get all the docs", -> - @DocManager.getAllDocs + it "should get all the (non-deleted) docs", -> + @DocManager.getAllNonDeletedDocs .calledWith(@project_id) .should.equal true @@ -158,7 +158,7 @@ describe "HttpController", -> lines: ["mock", "lines", "two"] rev: 4 }] - @DocManager.getAllDocs = sinon.stub().callsArgWith(1, null, @docs) + @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(1, null, @docs) @HttpController.getAllDocs @req, @res, @next it "should return the non null docs as JSON", -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 5064bcffbc..0576da3ddd 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -40,18 +40,35 @@ describe "MongoManager", -> @doc3 = { name: "mock-doc3" } @doc4 = { name: "mock-doc4" } @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc, @doc3, @doc4]) - @MongoManager.getProjectsDocs @project_id, @callback + + describe "with included_deleted = false", -> + beforeEach -> + @MongoManager.getProjectsDocs @project_id, false, @callback - it "should find the non-deleted docs via the project_id", -> - @db.docs.find - .calledWith({ - project_id: ObjectId(@project_id) - deleted: { $ne: true } - }, {}) - .should.equal true + it "should find the non-deleted docs via the project_id", -> + @db.docs.find + .calledWith({ + project_id: ObjectId(@project_id) + deleted: { $ne: true } + }, {}) + .should.equal true - it "should call the callback with the docs", -> - @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true + it "should call the callback with the docs", -> + @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true + + describe "with included_deleted = true", -> + beforeEach -> + @MongoManager.getProjectsDocs @project_id, true, @callback + + it "should find all via the project_id", -> + @db.docs.find + .calledWith({ + project_id: ObjectId(@project_id) + }, {}) + .should.equal true + + it "should call the callback with the docs", -> + @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true describe "upsertIntoDocCollection", -> beforeEach -> From 3d195de3e91000e8317e7a5969d36b85cfac8b7a Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 5 Dec 2016 16:48:01 +0000 Subject: [PATCH 108/349] Improve testing of archiving and be explicit about include_deleted parameter --- services/docstore/app/coffee/DocArchiveManager.coffee | 2 +- services/docstore/app/coffee/DocManager.coffee | 2 +- services/docstore/app/coffee/MongoManager.coffee | 4 ++-- .../test/acceptance/coffee/ArchiveDocsTests.coffee | 8 ++++++-- services/docstore/test/unit/coffee/DocManagerTests.coffee | 2 +- .../docstore/test/unit/coffee/MongoManagerTests.coffee | 4 ++-- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 52af544df6..ffad78bc4e 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -11,7 +11,7 @@ thirtySeconds = 30 * 1000 module.exports = DocArchive = archiveAllDocs: (project_id, callback = (err, docs) ->) -> - MongoManager.getProjectsDocs project_id, true, (err, docs) -> + MongoManager.getProjectsDocs project_id, {include_deleted: true}, (err, docs) -> if err? return callback(err) else if !docs? diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 6ac4678343..5a6d3961b9 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -32,7 +32,7 @@ module.exports = DocManager = getAllNonDeletedDocs: (project_id, callback = (error, docs) ->) -> DocArchive.unArchiveAllDocs project_id, (error) -> - MongoManager.getProjectsDocs project_id, false, (error, docs) -> + MongoManager.getProjectsDocs project_id, {include_deleted: false}, (error, docs) -> if err? return callback(error) else if !docs? diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 13551639d7..2dd5b8b24c 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -6,9 +6,9 @@ module.exports = MongoManager = db.docs.find {_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, {}, (error, docs = []) -> callback error, docs[0] - getProjectsDocs: (project_id, include_deleted, callback)-> + getProjectsDocs: (project_id, options = {include_deleted: true}, callback)-> query = {project_id: ObjectId(project_id.toString())} - if !include_deleted + if !options.include_deleted query.deleted = { $ne: true } db.docs.find query, {}, callback diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 26c57e7712..ef34901b6a 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -31,6 +31,9 @@ describe "Archiving all docs", -> DocstoreClient.createDoc @project_id, doc._id, doc.lines, (err)=> doc.lines[0] = doc.lines[0]+" added" DocstoreClient.updateDoc @project_id, doc._id, doc.lines, null, callback + # Make sure archiving works on deleted docs too + jobs.push (cb) => + DocstoreClient.deleteDoc @project_id, @docs[2]._id, cb async.series jobs, done afterEach (done) -> @@ -141,10 +144,11 @@ describe "Archiving all docs", -> describe "Unarchiving all docs", -> it "should unarchive all the docs", (done) -> + non_deleted_docs = @docs.slice(0,2) DocstoreClient.archiveAllDoc @project_id, (error, res) => DocstoreClient.getAllDocs @project_id, (error, res, docs) => throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs + docs.length.should.equal non_deleted_docs.length + for doc, i in non_deleted_docs doc.lines.should.deep.equal @docs[i].lines done() diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index a932e5dac9..e427ea9e79 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -106,7 +106,7 @@ describe "DocManager", -> it "should get the project from the database", -> @MongoManager.getProjectsDocs - .calledWith(@project_id, false) + .calledWith(@project_id, {include_deleted: false}) .should.equal true it "should return the docs", -> diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 0576da3ddd..d330001e11 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -43,7 +43,7 @@ describe "MongoManager", -> describe "with included_deleted = false", -> beforeEach -> - @MongoManager.getProjectsDocs @project_id, false, @callback + @MongoManager.getProjectsDocs @project_id, include_deleted: false, @callback it "should find the non-deleted docs via the project_id", -> @db.docs.find @@ -58,7 +58,7 @@ describe "MongoManager", -> describe "with included_deleted = true", -> beforeEach -> - @MongoManager.getProjectsDocs @project_id, true, @callback + @MongoManager.getProjectsDocs @project_id, include_deleted: true, @callback it "should find all via the project_id", -> @db.docs.find From 6fa8b89154a2426aecdf90904cc2c4649d7d48cb Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 5 Dec 2016 17:27:31 +0000 Subject: [PATCH 109/349] Be explicit about the data we return from mongo --- .../app/coffee/DocArchiveManager.coffee | 2 +- .../docstore/app/coffee/DocManager.coffee | 10 +++--- .../docstore/app/coffee/HttpController.coffee | 9 ++--- .../docstore/app/coffee/MongoManager.coffee | 8 ++--- .../coffee/UpdatingDocsTests.coffee | 2 +- .../test/unit/coffee/DocArchiveManager.coffee | 12 +++---- .../test/unit/coffee/DocManagerTests.coffee | 34 ++++++------------- .../unit/coffee/HttpControllerTests.coffee | 17 ++++------ .../test/unit/coffee/MongoManagerTests.coffee | 16 +++++---- 9 files changed, 47 insertions(+), 63 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index e02c167edd..925ad3bfc9 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -11,7 +11,7 @@ thirtySeconds = 30 * 1000 module.exports = DocArchive = archiveAllDocs: (project_id, callback = (err, docs) ->) -> - MongoManager.getProjectsDocs project_id, {include_deleted: true}, (err, docs) -> + MongoManager.getProjectsDocs project_id, {include_deleted: true}, {lines: true, rev: true, inS3: true}, (err, docs) -> if err? return callback(err) else if !docs? diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 8a280772ea..9102b22749 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -11,7 +11,7 @@ module.exports = DocManager = # migrate this version property to be part of the docs collection, to guarantee # consitency between lines and version when writing/reading, and for a simpler schema. getDoc: (project_id, doc_id, filter = { version: false }, callback = (error, doc) ->) -> - MongoManager.findDoc project_id, doc_id, (err, doc)-> + MongoManager.findDoc project_id, doc_id, filter, (err, doc)-> if err? return callback(err) else if !doc? @@ -31,9 +31,9 @@ module.exports = DocManager = else callback err, doc - getAllNonDeletedDocs: (project_id, callback = (error, docs) ->) -> + getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> DocArchive.unArchiveAllDocs project_id, (error) -> - MongoManager.getProjectsDocs project_id, {include_deleted: false}, (error, docs) -> + MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> if err? return callback(error) else if !docs? @@ -45,7 +45,7 @@ module.exports = DocManager = if !lines? or !version? return callback(new Error("no lines or version provided")) - DocManager.getDoc project_id, doc_id, {version: true}, (err, doc)-> + DocManager.getDoc project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true}, (err, doc)-> if err? and !(err instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" return callback(err) @@ -93,7 +93,7 @@ module.exports = DocManager = updateLinesAndRangesIfNeeded (error) -> return callback(error) if error? updateVersionIfNeeded (error) -> - return callback(callback) if error? + return callback(error) if error? callback null, modified, rev deleteDoc: (project_id, doc_id, callback = (error) ->) -> diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 40b27cd66e..a51e825f90 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -10,7 +10,7 @@ module.exports = HttpController = doc_id = req.params.doc_id include_deleted = req.query?.include_deleted == "true" logger.log project_id: project_id, doc_id: doc_id, "getting doc" - DocManager.getDoc project_id, doc_id, {version: true}, (error, doc) -> + DocManager.getDoc project_id, doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true}, (error, doc) -> return next(error) if error? logger.log doc: doc, "got doc" if !doc? @@ -24,7 +24,7 @@ module.exports = HttpController = project_id = req.params.project_id doc_id = req.params.doc_id logger.log project_id: project_id, doc_id: doc_id, "getting raw doc" - DocManager.getDoc project_id, doc_id, {version: false}, (error, doc) -> + DocManager.getDoc project_id, doc_id, {lines: true}, (error, doc) -> return next(error) if error? if !doc? res.send 404 @@ -35,7 +35,7 @@ module.exports = HttpController = getAllDocs: (req, res, next = (error) ->) -> project_id = req.params.project_id logger.log project_id: project_id, "getting all docs" - DocManager.getAllNonDeletedDocs project_id, (error, docs = []) -> + DocManager.getAllNonDeletedDocs project_id, {lines: true, rev: true}, (error, docs = []) -> return next(error) if error? docViews = [] for doc in docs @@ -83,12 +83,13 @@ module.exports = HttpController = _id: doc._id?.toString() lines: doc.lines rev: doc.rev - deleted: !!doc.deleted } if doc.version? doc_view.version = doc.version if doc.ranges? doc_view.ranges = doc.ranges + if doc.deleted? + doc_view.deleted = doc.deleted return doc_view _buildRawDocView: (doc)-> diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index d6d7b46923..fe6f06e8cb 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -2,15 +2,15 @@ module.exports = MongoManager = - findDoc: (project_id, doc_id, callback = (error, doc) ->) -> - db.docs.find {_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, {}, (error, docs = []) -> + findDoc: (project_id, doc_id, filter, callback = (error, doc) ->) -> + db.docs.find {_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, filter, (error, docs = []) -> callback error, docs[0] - getProjectsDocs: (project_id, options = {include_deleted: true}, callback)-> + getProjectsDocs: (project_id, options = {include_deleted: true}, filter, callback)-> query = {project_id: ObjectId(project_id.toString())} if !options.include_deleted query.deleted = { $ne: true } - db.docs.find query, {}, callback + db.docs.find query, filter, callback getArchivedProjectDocs: (project_id, callback)-> query = diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 0dd60baa05..f34a4e3e76 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -76,7 +76,7 @@ describe "Applying updates to a doc", -> @body.modified.should.equal true it "should return the rev", -> - @body.rev.should.equal 2 + @body.rev.should.equal 1 it "should update the doc in the API", (done) -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index 05abcc0fb3..cac4594dd2 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -64,8 +64,8 @@ describe "DocArchiveManager", -> @MongoManager = markDocAsArchived: sinon.stub().callsArgWith(2, null) upsertIntoDocCollection: sinon.stub().callsArgWith(3, null) - getProjectsDocs: sinon.stub().callsArgWith(2, null, @mongoDocs) - getArchivedProjectDocs: sinon.stub().callsArgWith(1, null, @mongoDocs) + getProjectsDocs: sinon.stub().callsArgWith(3, null, @mongoDocs) + getArchivedProjectDocs: sinon.stub().callsArgWith(2, null, @mongoDocs) @requires = "settings-sharelatex": @settings @@ -127,7 +127,7 @@ describe "DocArchiveManager", -> describe "archiveAllDocs", -> it "should archive all project docs which are not in s3", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, @mongoDocs) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @mongoDocs) @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) @DocArchiveManager.archiveAllDocs @project_id, (err)=> @@ -142,14 +142,14 @@ describe "DocArchiveManager", -> done() it "should return error if have no docs", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, null) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null) @DocArchiveManager.archiveAllDocs @project_id, (err)=> should.exist err done() it "should return the error", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, @error, null) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, @error, null) @DocArchiveManager.archiveAllDocs @project_id, (err)=> err.should.equal @error @@ -163,7 +163,7 @@ describe "DocArchiveManager", -> while --numberOfDocs != 0 @mongoDocs.push({inS3:true, _id: ObjectId()}) - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, @mongoDocs) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @mongoDocs) @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) it "should not throw and error", (done)-> diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index c17211e1de..c1356e6e6a 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -92,7 +92,7 @@ describe "DocManager", -> describe "when the doc does not exist in the docs collection", -> beforeEach -> - @MongoManager.findDoc = sinon.stub().callsArgWith(2, null, null) + @MongoManager.findDoc = sinon.stub().yields(null, null) @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback it "should return a NotFoundError", -> @@ -104,13 +104,14 @@ describe "DocManager", -> describe "when the project exists", -> beforeEach -> @docs = [{ _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] }] - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, @docs) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @docs) @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, @docs) - @DocManager.getAllNonDeletedDocs @project_id, @callback + @filter = { lines: true } + @DocManager.getAllNonDeletedDocs @project_id, @filter, @callback it "should get the project from the database", -> @MongoManager.getProjectsDocs - .calledWith(@project_id, {include_deleted: false}) + .calledWith(@project_id, {include_deleted: false}, @filter) .should.equal true it "should return the docs", -> @@ -118,13 +119,13 @@ describe "DocManager", -> describe "when there are no docs for the project", -> beforeEach -> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(2, null, null) - @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, null) - @DocManager.getAllNonDeletedDocs @project_id, @callback + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null) + @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null) + @DocManager.getAllNonDeletedDocs @project_id, @filter, @callback it "should return a NotFoundError", -> @callback - .calledWith(new Errors.NotFoundError("No such docs for project #{@project_id}")) + .calledWith(new Errors.NotFoundError("No docs for project #{@project_id}")) .should.equal true describe "deleteDoc", -> @@ -196,7 +197,7 @@ describe "DocManager", -> it "should get the existing doc", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id) + .calledWith(@project_id, @doc_id, {version: true, rev: true, lines: true, version: true, ranges: true}) .should.equal true it "should upsert the document to the doc collection", -> @@ -216,11 +217,6 @@ describe "DocManager", -> @RangeManager.shouldUpdateRanges.returns true @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @newRanges, @callback - it "should get the existing doc", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id) - .should.equal true - it "should upsert the ranges", -> @MongoManager.upsertIntoDocCollection .calledWith(@project_id, @doc_id, {ranges: @newRanges}) @@ -237,11 +233,6 @@ describe "DocManager", -> @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @originalRanges, @callback - it "should get the existing doc with the version", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id, {version: true}) - .should.equal true - it "should not change the lines or ranges", -> @MongoManager.upsertIntoDocCollection.called.should.equal false @@ -258,11 +249,6 @@ describe "DocManager", -> @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @originalRanges, @callback - it "should get the existing doc", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id) - .should.equal true - it "should not update the ranges or lines", -> @MongoManager.upsertIntoDocCollection.called.should.equal false diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index c207a56d09..b775c5f91c 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -45,7 +45,7 @@ describe "HttpController", -> it "should get the document with the version (including deleted)", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id, {version: true}) + .calledWith(@project_id, @doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true}) .should.equal true it "should return the doc as JSON", -> @@ -54,7 +54,6 @@ describe "HttpController", -> _id: @doc_id lines: @doc.lines rev: @doc.rev - deleted: false version: @doc.version }) .should.equal true @@ -68,7 +67,7 @@ describe "HttpController", -> it "should get the doc from the doc manager", -> @HttpController.getDoc @req, @res, @next - @DocManager.getDoc.calledWith(@project_id, @doc_id, {version: true}).should.equal true + @DocManager.getDoc.calledWith(@project_id, @doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true}).should.equal true it "should return 404 if the query string delete is not set ", -> @HttpController.getDoc @req, @res, @next @@ -97,7 +96,7 @@ describe "HttpController", -> it "should get the document without the version", -> @DocManager.getDoc - .calledWith(@project_id, @doc_id, {version: false}) + .calledWith(@project_id, @doc_id, {lines: true}) .should.equal true it "should set the content type header", -> @@ -120,12 +119,12 @@ describe "HttpController", -> lines: ["mock", "lines", "two"] rev: 4 }] - @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(1, null, @docs) + @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, @docs) @HttpController.getAllDocs @req, @res, @next it "should get all the (non-deleted) docs", -> @DocManager.getAllNonDeletedDocs - .calledWith(@project_id) + .calledWith(@project_id, {lines: true, rev: true}) .should.equal true it "should return the doc as JSON", -> @@ -134,12 +133,10 @@ describe "HttpController", -> _id: @docs[0]._id.toString() lines: @docs[0].lines rev: @docs[0].rev - deleted: false }, { _id: @docs[1]._id.toString() lines: @docs[1].lines rev: @docs[1].rev - deleted: false }]) .should.equal true @@ -158,7 +155,7 @@ describe "HttpController", -> lines: ["mock", "lines", "two"] rev: 4 }] - @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(1, null, @docs) + @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, @docs) @HttpController.getAllDocs @req, @res, @next it "should return the non null docs as JSON", -> @@ -167,12 +164,10 @@ describe "HttpController", -> _id: @docs[0]._id.toString() lines: @docs[0].lines rev: @docs[0].rev - deleted: false }, { _id: @docs[2]._id.toString() lines: @docs[2].lines rev: @docs[2].rev - deleted: false }]) .should.equal true diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 642531134a..b65de2cde9 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -20,14 +20,15 @@ describe "MongoManager", -> beforeEach -> @doc = { name: "mock-doc"} @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc]) - @MongoManager.findDoc @project_id, @doc_id, @callback + @filter = { lines: true } + @MongoManager.findDoc @project_id, @doc_id, @filter, @callback it "should find the doc", -> @db.docs.find .calledWith({ _id: ObjectId(@doc_id) project_id: ObjectId(@project_id) - }, {}) + }, @filter) .should.equal true it "should call the callback with the doc", -> @@ -35,6 +36,7 @@ describe "MongoManager", -> describe "getProjectsDocs", -> beforeEach -> + @filter = {lines: true} @doc1 = { name: "mock-doc1" } @doc2 = { name: "mock-doc2" } @doc3 = { name: "mock-doc3" } @@ -43,28 +45,28 @@ describe "MongoManager", -> describe "with included_deleted = false", -> beforeEach -> - @MongoManager.getProjectsDocs @project_id, include_deleted: false, @callback + @MongoManager.getProjectsDocs @project_id, include_deleted: false, @filter, @callback it "should find the non-deleted docs via the project_id", -> @db.docs.find .calledWith({ project_id: ObjectId(@project_id) deleted: { $ne: true } - }, {}) + }, @filter) .should.equal true it "should call the callback with the docs", -> @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true describe "with included_deleted = true", -> - beforeEach -> - @MongoManager.getProjectsDocs @project_id, include_deleted: true, @callback + beforeEach -> + @MongoManager.getProjectsDocs @project_id, include_deleted: true, @filter, @callback it "should find all via the project_id", -> @db.docs.find .calledWith({ project_id: ObjectId(@project_id) - }, {}) + }, @filter) .should.equal true it "should call the callback with the docs", -> From 0174495f7597bc690282cb7c3f45cb1199ce6c76 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 9 Dec 2016 14:37:24 +0000 Subject: [PATCH 110/349] Add an end point to get all the ranges in a project --- services/docstore/app.coffee | 1 + .../docstore/app/coffee/HttpController.coffee | 39 ++++++++++--------- .../coffee/GettingAllDocsTests.coffee | 19 +++++++-- .../coffee/helpers/DocstoreClient.coffee | 6 +++ .../unit/coffee/HttpControllerTests.coffee | 31 +++++++++++++++ 5 files changed, 74 insertions(+), 22 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index f80f99288d..e41593cd4c 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -29,6 +29,7 @@ app.param 'doc_id', (req, res, next, doc_id) -> next new Error("invalid doc id") app.get '/project/:project_id/doc', HttpController.getAllDocs +app.get '/project/:project_id/ranges', HttpController.getAllRanges app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc # Add 16kb overhead for the JSON encoding diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index a51e825f90..36996d943a 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -37,13 +37,14 @@ module.exports = HttpController = logger.log project_id: project_id, "getting all docs" DocManager.getAllNonDeletedDocs project_id, {lines: true, rev: true}, (error, docs = []) -> return next(error) if error? - docViews = [] - for doc in docs - if doc? # There can end up being null docs for some reason :( (probably a race condition) - docViews.push HttpController._buildDocView(doc) - else - logger.error err: new Error("null doc"), project_id: project_id, "encountered null doc" - res.json docViews + res.json HttpController._buildDocsArrayView(project_id, docs) + + getAllRanges: (req, res, next = (error) ->) -> + project_id = req.params.project_id + logger.log {project_id}, "getting all ranges" + DocManager.getAllNonDeletedDocs project_id, {ranges: true}, (error, docs = []) -> + return next(error) if error? + res.json HttpController._buildDocsArrayView(project_id, docs) updateDoc: (req, res, next = (error) ->) -> project_id = req.params.project_id @@ -79,21 +80,23 @@ module.exports = HttpController = res.send 204 _buildDocView: (doc) -> - doc_view = { - _id: doc._id?.toString() - lines: doc.lines - rev: doc.rev - } - if doc.version? - doc_view.version = doc.version - if doc.ranges? - doc_view.ranges = doc.ranges - if doc.deleted? - doc_view.deleted = doc.deleted + doc_view = { _id: doc._id?.toString() } + for attribute in ["lines", "rev", "version", "ranges", "deleted"] + if doc[attribute]? + doc_view[attribute] = doc[attribute] return doc_view _buildRawDocView: (doc)-> return (doc?.lines or []).join("\n") + + _buildDocsArrayView: (project_id, docs) -> + docViews = [] + for doc in docs + if doc? # There can end up being null docs for some reason :( (probably a race condition) + docViews.push HttpController._buildDocView(doc) + else + logger.error err: new Error("null doc"), project_id: project_id, "encountered null doc" + return docViews archiveAllDocs: (req, res, next = (error) ->) -> project_id = req.params.project_id diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index 6bbfb4cfa9..7244693888 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -12,33 +12,36 @@ describe "Getting all docs", -> @docs = [{ _id: ObjectId() lines: ["one", "two", "three"] + ranges: {"mock": "one"} rev: 2 }, { _id: ObjectId() lines: ["aaa", "bbb", "ccc"] + ranges: {"mock": "two"} rev: 4 }, { _id: ObjectId() lines: ["111", "222", "333"] + ranges: {"mock": "three"} rev: 6 }] @deleted_doc = { _id: ObjectId() lines: ["deleted"] + ranges: {"mock": "four"} rev: 8 } version = 42 - ranges = 42 jobs = for doc in @docs do (doc) => (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, version, ranges, callback + DocstoreClient.createDoc @project_id, doc._id, doc.lines, version, doc.ranges, callback jobs.push (cb) => - DocstoreClient.createDoc @project_id, @deleted_doc._id, @deleted_doc.lines, version, {}, (err)=> + DocstoreClient.createDoc @project_id, @deleted_doc._id, @deleted_doc.lines, version, @deleted_doc.ranges, (err)=> DocstoreClient.deleteDoc @project_id, @deleted_doc._id, cb async.series jobs, done - it "should return all the (non-deleted) docs", (done) -> + it "getAllDocs should return all the (non-deleted) docs", (done) -> DocstoreClient.getAllDocs @project_id, (error, res, docs) => throw error if error? docs.length.should.equal @docs.length @@ -46,4 +49,12 @@ describe "Getting all docs", -> doc.lines.should.deep.equal @docs[i].lines done() + it "getAllRanges should return all the (non-deleted) doc ranges", (done) -> + DocstoreClient.getAllRanges @project_id, (error, res, docs) => + throw error if error? + docs.length.should.equal @docs.length + for doc, i in docs + doc.ranges.should.deep.equal @docs[i].ranges + done() + diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index b4ccdcb418..05d8069d69 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -21,6 +21,12 @@ module.exports = DocstoreClient = json: true }, callback + getAllRanges: (project_id, callback = (error, res, body) ->) -> + request.get { + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/ranges" + json: true + }, callback + updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, res, body) ->) -> request.post { url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index b775c5f91c..6b157050d4 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -180,6 +180,37 @@ describe "HttpController", -> ) .should.equal true + describe "getAllRanges", -> + describe "normally", -> + beforeEach -> + @req.params = + project_id: @project_id + @docs = [{ + _id: ObjectId() + ranges: {"mock_ranges": "one"} + }, { + _id: ObjectId() + ranges: {"mock_ranges": "two"} + }] + @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, @docs) + @HttpController.getAllRanges @req, @res, @next + + it "should get all the (non-deleted) doc ranges", -> + @DocManager.getAllNonDeletedDocs + .calledWith(@project_id, {ranges: true}) + .should.equal true + + it "should return the doc as JSON", -> + @res.json + .calledWith([{ + _id: @docs[0]._id.toString() + ranges: @docs[0].ranges + }, { + _id: @docs[1]._id.toString() + ranges: @docs[1].ranges + }]) + .should.equal true + describe "updateDoc", -> beforeEach -> @req.params = From 5e730b33b208da5b5893809e1e3b54da93682c96 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 16 Dec 2016 16:44:08 +0000 Subject: [PATCH 111/349] Support new comment op format --- .../docstore/app/coffee/RangeManager.coffee | 4 +-- .../test/unit/coffee/RangeManagerTests.coffee | 30 +++++++------------ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/services/docstore/app/coffee/RangeManager.coffee b/services/docstore/app/coffee/RangeManager.coffee index 4022d55d04..b46fe50b26 100644 --- a/services/docstore/app/coffee/RangeManager.coffee +++ b/services/docstore/app/coffee/RangeManager.coffee @@ -26,8 +26,8 @@ module.exports = RangeManager = change.metadata.user_id = @_safeObjectId(change.metadata.user_id) for comment in ranges.comments or [] comment.id = @_safeObjectId(comment.id) - if comment.metadata?.ts? - comment.metadata.ts = new Date(comment.metadata.ts) + if comment.op?.t? + comment.op.t = @_safeObjectId(comment.op.t) return ranges _safeObjectId: (data) -> diff --git a/services/docstore/test/unit/coffee/RangeManagerTests.coffee b/services/docstore/test/unit/coffee/RangeManagerTests.coffee index bf8b01e7d7..0fe3983982 100644 --- a/services/docstore/test/unit/coffee/RangeManagerTests.coffee +++ b/services/docstore/test/unit/coffee/RangeManagerTests.coffee @@ -17,6 +17,7 @@ describe "RangeManager", -> change_id = ObjectId().toString() comment_id = ObjectId().toString() user_id = ObjectId().toString() + thread_id = ObjectId().toString() ts = new Date().toJSON() @RangeManager.jsonRangesToMongo({ changes: [{ @@ -28,10 +29,7 @@ describe "RangeManager", -> }] comments: [{ id: comment_id - offset: 42 - length: 5 - metadata: - ts: ts + op: { c: "foo", p: 3, t: thread_id } }] }).should.deep.equal { changes: [{ @@ -43,10 +41,7 @@ describe "RangeManager", -> }] comments: [{ id: ObjectId(comment_id) - offset: 42 - length: 5 - metadata: - ts: new Date(ts) + op: { c: "foo", p: 3, t: ObjectId(thread_id) } }] } @@ -78,6 +73,7 @@ describe "RangeManager", -> change_id = ObjectId().toString() comment_id = ObjectId().toString() user_id = ObjectId().toString() + thread_id = ObjectId().toString() ts = new Date().toJSON() ranges1 = { changes: [{ @@ -89,10 +85,7 @@ describe "RangeManager", -> }] comments: [{ id: comment_id - offset: 42 - length: 5 - metadata: - ts: ts + op: { c: "foo", p: 3, t: thread_id } }] } ranges1_copy = JSON.parse(JSON.stringify(ranges1)) # jsonRangesToMongo modifies in place @@ -111,10 +104,7 @@ describe "RangeManager", -> }] comments: [{ id: ObjectId() - offset: 42 - length: 5 - metadata: - ts: new Date() + op: { c: "foo", p: 3, t: ObjectId() } }] } @ranges_copy = @RangeManager.jsonRangesToMongo(JSON.parse(JSON.stringify(@ranges))) @@ -153,10 +143,10 @@ describe "RangeManager", -> @ranges_copy.comments[0].id = ObjectId() @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true - it "should return true when the comment ts changes", -> - @ranges_copy.comments[0].metadata.ts = new Date(Date.now() + 1000) + it "should return true when the comment offset changes", -> + @ranges_copy.comments[0].op.p = 17 @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true - it "should return true when the comment offset changes", -> - @ranges_copy.comments[0].offset = 17 + it "should return true when the comment content changes", -> + @ranges_copy.comments[0].op.c = "bar" @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true \ No newline at end of file From fb39bb044238476f5b1f9fc8efbd45ebc06fbf66 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Thu, 19 Jan 2017 12:15:14 +0100 Subject: [PATCH 112/349] Validate that ranges are present in a set document request --- .../docstore/app/coffee/DocManager.coffee | 4 ++-- .../docstore/app/coffee/HttpController.coffee | 5 +++++ .../docstore/app/coffee/RangeManager.coffee | 6 ++---- .../test/unit/coffee/DocManagerTests.coffee | 11 ++++++++-- .../unit/coffee/HttpControllerTests.coffee | 21 ++++++++++++++++--- .../test/unit/coffee/RangeManagerTests.coffee | 7 +++++-- 6 files changed, 41 insertions(+), 13 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 9102b22749..6cf679c6c1 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -42,8 +42,8 @@ module.exports = DocManager = return callback(null, docs) updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) -> - if !lines? or !version? - return callback(new Error("no lines or version provided")) + if !lines? or !version? or !ranges? + return callback(new Error("no lines, version or ranges provided")) DocManager.getDoc project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true}, (err, doc)-> if err? and !(err instanceof Errors.NotFoundError) diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 36996d943a..7c8dd0aecf 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -62,6 +62,11 @@ module.exports = HttpController = logger.error project_id: project_id, doc_id: doc_id, "no doc version provided" res.send 400 # Bad Request return + + if !ranges? + logger.error project_id: project_id, doc_id: doc_id, "no doc ranges provided" + res.send 400 # Bad Request + return logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc" DocManager.updateDoc project_id, doc_id, lines, version, ranges, (error, modified, rev) -> diff --git a/services/docstore/app/coffee/RangeManager.coffee b/services/docstore/app/coffee/RangeManager.coffee index b46fe50b26..661d6e4b28 100644 --- a/services/docstore/app/coffee/RangeManager.coffee +++ b/services/docstore/app/coffee/RangeManager.coffee @@ -3,10 +3,8 @@ _ = require "underscore" module.exports = RangeManager = shouldUpdateRanges: (doc_ranges, incoming_ranges) -> - # TODO: If we have no incoming_ranges, just ignore for now while - # we're rolling this out, but eventually this should be a mandatory - # field and this will become an error condition - return false if !incoming_ranges? + if !incoming_ranges? + throw new Error("expected incoming_ranges") # If the ranges are empty, we don't store them in the DB, so set # doc_ranges to an empty object as default, since this is was the diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index c1356e6e6a..9b43bc05af 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -263,14 +263,21 @@ describe "DocManager", -> @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @originalRanges, @callback it "should return an error", -> - @callback.calledWith(new Error("no lines or version provided")).should.equal true + @callback.calledWith(new Error("no lines, version or ranges provided")).should.equal true describe "when the lines are null", -> beforeEach -> @DocManager.updateDoc @project_id, @doc_id, null, @version, @originalRanges, @callback it "should return an error", -> - @callback.calledWith(new Error("no lines or version provided")).should.equal true + @callback.calledWith(new Error("no lines, version or ranges provided")).should.equal true + + describe "when the ranges are null", -> + beforeEach -> + @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, null, @callback + + it "should return an error", -> + @callback.calledWith(new Error("no lines, version or ranges provided")).should.equal true describe "when there is a generic error getting the doc", -> beforeEach -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 6b157050d4..1a0752d850 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -241,6 +241,7 @@ describe "HttpController", -> @req.body = lines: @lines = ["hello", "world"] version: @version = 42 + ranges: {} @DocManager.updateDoc = sinon.stub().yields(null, false, @rev = 5) @HttpController.updateDoc @req, @res, @next @@ -251,7 +252,7 @@ describe "HttpController", -> describe "when the doc lines are not provided", -> beforeEach -> - @req.body = { version: 42 } + @req.body = { version: 42, ranges: {} } @DocManager.updateDoc = sinon.stub().yields(null, false) @HttpController.updateDoc @req, @res, @next @@ -263,9 +264,23 @@ describe "HttpController", -> .calledWith(400) .should.equal true - describe "when the doc version is not provided", -> + describe "when the doc version are not provided", -> beforeEach -> - @req.body = { lines : [ "foo" ]} + @req.body = { version: 42, lines: ["hello world"] } + @DocManager.updateDoc = sinon.stub().yields(null, false) + @HttpController.updateDoc @req, @res, @next + + it "should not update the document", -> + @DocManager.updateDoc.called.should.equal false + + it "should return a 400 (bad request) response", -> + @res.send + .calledWith(400) + .should.equal true + + describe "when the doc ranges is not provided", -> + beforeEach -> + @req.body = { lines : [ "foo" ], version: 42 } @DocManager.updateDoc = sinon.stub().yields(null, false) @HttpController.updateDoc @req, @res, @next diff --git a/services/docstore/test/unit/coffee/RangeManagerTests.coffee b/services/docstore/test/unit/coffee/RangeManagerTests.coffee index 0fe3983982..ea2416ab63 100644 --- a/services/docstore/test/unit/coffee/RangeManagerTests.coffee +++ b/services/docstore/test/unit/coffee/RangeManagerTests.coffee @@ -1,6 +1,7 @@ SandboxedModule = require('sandboxed-module') sinon = require('sinon') require('chai').should() +expect = require('chai').expect modulePath = require('path').join __dirname, '../../../app/js/RangeManager' ObjectId = require("mongojs").ObjectId assert = require("chai").assert @@ -110,8 +111,10 @@ describe "RangeManager", -> @ranges_copy = @RangeManager.jsonRangesToMongo(JSON.parse(JSON.stringify(@ranges))) describe "with a blank new range", -> - it "should return false", -> - @RangeManager.shouldUpdateRanges(@ranges, null).should.equal false + it "should throw an error", -> + expect(() => + @RangeManager.shouldUpdateRanges(@ranges, null) + ).to.throw(Error) describe "with a blank old range", -> it "should treat it like {}", -> From 315a1d5e80b54ae8fafb0f0d4e8cc5806325e379 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Tue, 31 Jan 2017 10:23:51 +0100 Subject: [PATCH 113/349] Add ranges into health check --- services/docstore/app/coffee/HealthChecker.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index 639d752477..cb5d053aa1 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -19,7 +19,7 @@ module.exports = jobs = [ (cb)-> opts = getOpts() - opts.json = {lines: lines, version: 42} + opts.json = {lines: lines, version: 42, ranges: {}} request.post(opts, cb) (cb)-> opts = getOpts() From 929ffbd83a0d85c6aa97c6f0c4e77afaacb2c1c2 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Mon, 20 Feb 2017 10:07:30 +0000 Subject: [PATCH 114/349] Don't npm rebuild inside container --- services/docstore/test/acceptance/scripts/full-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/test/acceptance/scripts/full-test.sh b/services/docstore/test/acceptance/scripts/full-test.sh index 9f6167e667..8584cd17d0 100755 --- a/services/docstore/test/acceptance/scripts/full-test.sh +++ b/services/docstore/test/acceptance/scripts/full-test.sh @@ -1,6 +1,6 @@ #! /usr/bin/env bash -npm rebuild +# npm rebuild echo ">> Starting server..." From d09a4cb2756e64c9bf8361953da066be73e5aeac Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Mon, 6 Mar 2017 15:11:04 +0000 Subject: [PATCH 115/349] Lengthen sleep for acceptance tests --- services/docstore/test/acceptance/scripts/full-test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/test/acceptance/scripts/full-test.sh b/services/docstore/test/acceptance/scripts/full-test.sh index 8584cd17d0..afd5ef2ecb 100755 --- a/services/docstore/test/acceptance/scripts/full-test.sh +++ b/services/docstore/test/acceptance/scripts/full-test.sh @@ -8,7 +8,7 @@ grunt --no-color forever:app:start echo ">> Server started" -sleep 5 +sleep 20 echo ">> Running acceptance tests..." grunt --no-color mochaTest:acceptance From dbfe5ac7125973ef8883982d649851f681e94174 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Thu, 9 Mar 2017 17:34:33 +0000 Subject: [PATCH 116/349] error if doc lines are not array when unarchiving --- services/docstore/app/coffee/DocArchiveManager.coffee | 3 +++ ...rchiveManager.coffee => DocArchiveManagerTests.coffee} | 8 ++++++++ 2 files changed, 11 insertions(+) rename services/docstore/test/unit/coffee/{DocArchiveManager.coffee => DocArchiveManagerTests.coffee} (94%) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 925ad3bfc9..8a2c3a2958 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -67,6 +67,9 @@ module.exports = DocArchive = if err? || res.statusCode != 200 logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong unarchiving doc from aws" return callback new Errors.NotFoundError("Error in S3 request") + if !(lines instanceof Array) + logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "doc lines from aws are not in array format, likely not JSON parsable" + return callback(new Error("Error unpacking doc")) MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), {lines}, (err) -> return callback(err) if err? logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee similarity index 94% rename from services/docstore/test/unit/coffee/DocArchiveManager.coffee rename to services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee index cac4594dd2..7966b30552 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee @@ -124,6 +124,14 @@ describe "DocArchiveManager", -> should.exist err done() + it "should error if the doc lines are a string not an array", (done)-> + @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, "this is a string") + @request.del = sinon.stub() + @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0], (err)=> + should.exist err + @request.del.called.should.equal false + done() + describe "archiveAllDocs", -> it "should archive all project docs which are not in s3", (done)-> From 8bd0df3530198bd2d6165f785fffeb515d929954 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Thu, 9 Mar 2017 17:36:28 +0000 Subject: [PATCH 117/349] also log out lines in error message --- services/docstore/app/coffee/DocArchiveManager.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 8a2c3a2958..a23c0fc384 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -68,7 +68,7 @@ module.exports = DocArchive = logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong unarchiving doc from aws" return callback new Errors.NotFoundError("Error in S3 request") if !(lines instanceof Array) - logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "doc lines from aws are not in array format, likely not JSON parsable" + logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, lines:lines, "doc lines from aws are not in array format, likely not JSON parsable" return callback(new Error("Error unpacking doc")) MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), {lines}, (err) -> return callback(err) if err? @@ -90,4 +90,4 @@ module.exports = DocArchive = timeout: thirtySeconds json: content uri:"https://#{settings.docstore.s3.bucket}.s3.amazonaws.com/#{key}" - } \ No newline at end of file + } From d6146b29708f6fe345b4df6d8bd9cf60dab68f23 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Thu, 9 Mar 2017 18:18:50 +0000 Subject: [PATCH 118/349] got failing acceptence test --- .../test/acceptance/coffee/ArchiveDocsTests.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 7bec662ab2..e8e25e3ab2 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -150,3 +150,15 @@ describe "Archiving", -> for doc, i in non_deleted_docs doc.lines.should.deep.equal @docs[i].lines done() + + describe "Unarchiving automatically", -> + it "should unarchive the docs ", (done) -> + DocstoreClient.archiveAllDoc @project_id, (error, res) => + DocstoreClient.getDoc @project_id, @docs[0]._id, {}, (error, res, doc) => + doc.lines.should.deep.equal @docs[0].lines + doc.version.should.equal @docs[0].version + doc.ranges.should.deep.equal @docs[0].ranges + done() + + + From f067c039fef59438a80f4265582d709ac89439b4 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Thu, 9 Mar 2017 18:51:54 +0000 Subject: [PATCH 119/349] always search for inS3 when getting a doc --- services/docstore/app/coffee/DocManager.coffee | 4 +++- .../test/acceptance/coffee/ArchiveDocsTests.coffee | 6 +++--- .../test/unit/coffee/DocManagerTests.coffee | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 6cf679c6c1..875184ca4e 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -10,7 +10,9 @@ module.exports = DocManager = # collection (which is all that this collection contains). In future, we should # migrate this version property to be part of the docs collection, to guarantee # consitency between lines and version when writing/reading, and for a simpler schema. - getDoc: (project_id, doc_id, filter = { version: false }, callback = (error, doc) ->) -> + getDoc: (project_id, doc_id, filter = { version: false, inS3:true}, callback = (error, doc) ->) -> + if filter? and !filter.inS3? + filter.inS3 = true MongoManager.findDoc project_id, doc_id, filter, (err, doc)-> if err? return callback(err) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index e8e25e3ab2..a7616fcd86 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -12,6 +12,7 @@ describe "Archiving", -> beforeEach (done) -> @callback = sinon.stub() @project_id = ObjectId() + @version = 42 @docs = [{ _id: ObjectId() lines: ["one", "two", "three"] @@ -23,9 +24,8 @@ describe "Archiving", -> }, { _id: ObjectId() lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] - rev: 6 + version:@version }] - @version = 42 @ranges = [] jobs = for doc in @docs do (doc) => @@ -157,7 +157,7 @@ describe "Archiving", -> DocstoreClient.getDoc @project_id, @docs[0]._id, {}, (error, res, doc) => doc.lines.should.deep.equal @docs[0].lines doc.version.should.equal @docs[0].version - doc.ranges.should.deep.equal @docs[0].ranges + doc.ranges.should.deep.equal @ranges done() diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 9b43bc05af..c07e6a4e4a 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -34,6 +34,20 @@ describe "DocManager", -> @MongoManager.findDoc = sinon.stub() @MongoManager.getDocVersion = sinon.stub().yields(null, @version) + describe "when using a filter", -> + beforeEach -> + @MongoManager.findDoc.yields(null, @doc) + + it "should always get inS3 even when filter is passed", (done)-> + @DocManager.getDoc @project_id, @doc_id, {version: true}, => + @MongoManager.findDoc.args[0][2].inS3.should.equal true + done() + + it "should always get inS3 even when no filter is passed", (done)-> + @DocManager.getDoc @project_id, @doc_id, undefined, => + @MongoManager.findDoc.args[0][2].inS3.should.equal true + done() + describe "when the doc is in the doc collection", -> beforeEach -> @MongoManager.findDoc.yields(null, @doc) From 7adc67d13aee7ef11a21a9c302bc43064d5381f3 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 10 Mar 2017 10:36:48 +0000 Subject: [PATCH 120/349] add missing error handler --- services/docstore/app/coffee/DocManager.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 875184ca4e..15e14d5428 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -35,6 +35,8 @@ module.exports = DocManager = getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> DocArchive.unArchiveAllDocs project_id, (error) -> + if error? + return callback(error) MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> if err? return callback(error) From ffd1aa0ca46dea2ef7f4a02d370d2f7186bc64a0 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 10 Mar 2017 11:45:03 +0000 Subject: [PATCH 121/349] just get doc_id for quick check to see if it exists --- services/docstore/app/coffee/DocManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 15e14d5428..a794864e45 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -101,7 +101,7 @@ module.exports = DocManager = callback null, modified, rev deleteDoc: (project_id, doc_id, callback = (error) ->) -> - DocManager.getDoc project_id, doc_id, { version: false }, (error, doc) -> + DocManager.getDoc project_id, doc_id, { _id: true }, (error, doc) -> return callback(error) if error? return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? MongoManager.markDocAsDeleted project_id, doc_id, callback From c0e23df82b55f14ec37a6e0948cb1595c94e8b61 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 15 Mar 2017 22:09:56 +0000 Subject: [PATCH 122/349] break getDoc into multiple helpers, stop passing filters though from other calls --- .../docstore/app/coffee/DocManager.coffee | 36 +++++- .../docstore/app/coffee/HttpController.coffee | 4 +- .../acceptance/coffee/ArchiveDocsTests.coffee | 6 +- .../test/unit/coffee/DocManagerTests.coffee | 120 ++++++++++++++---- .../unit/coffee/HttpControllerTests.coffee | 16 +-- 5 files changed, 139 insertions(+), 43 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index a794864e45..d9f0bd6747 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -6,13 +6,16 @@ DocArchive = require "./DocArchiveManager" RangeManager = require "./RangeManager" module.exports = DocManager = + + # TODO: For historical reasons, the doc version is currently stored in the docOps # collection (which is all that this collection contains). In future, we should # migrate this version property to be part of the docs collection, to guarantee # consitency between lines and version when writing/reading, and for a simpler schema. - getDoc: (project_id, doc_id, filter = { version: false, inS3:true}, callback = (error, doc) ->) -> - if filter? and !filter.inS3? - filter.inS3 = true + _getDoc: (project_id, doc_id, filter = {}, callback = (error, doc) ->) -> + if filter.inS3 != true + return callback("must include inS3 when getting doc") + MongoManager.findDoc project_id, doc_id, filter, (err, doc)-> if err? return callback(err) @@ -23,7 +26,7 @@ module.exports = DocManager = if err? logger.err err:err, project_id:project_id, doc_id:doc_id, "error unarchiving doc" return callback(err) - DocManager.getDoc project_id, doc_id, filter, callback + DocManager._getDoc project_id, doc_id, filter, callback else if filter.version MongoManager.getDocVersion doc_id, (error, version) -> @@ -33,6 +36,25 @@ module.exports = DocManager = else callback err, doc + checkDocExists: (project_id, doc_id, callback = (err, exists)->)-> + DocManager._getDoc project_id, doc_id, {_id:1, inS3:true}, (err, doc)-> + if err? + return callback(err) + callback(err, doc?) + + getFullDoc: (project_id, doc_id, callback = (err, doc)->)-> + DocManager._getDoc project_id, doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}, (err, doc)-> + if err? + return callback(err) + callback(err, doc) + + + getDocLines: (project_id, doc_id, callback = (err, doc)->)-> + DocManager._getDoc project_id, doc_id, {lines:true, inS3:true}, (err, doc)-> + if err? + return callback(err) + callback(err, doc) + getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> DocArchive.unArchiveAllDocs project_id, (error) -> if error? @@ -49,7 +71,7 @@ module.exports = DocManager = if !lines? or !version? or !ranges? return callback(new Error("no lines, version or ranges provided")) - DocManager.getDoc project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true}, (err, doc)-> + DocManager._getDoc project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}, (err, doc)-> if err? and !(err instanceof Errors.NotFoundError) logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" return callback(err) @@ -101,8 +123,8 @@ module.exports = DocManager = callback null, modified, rev deleteDoc: (project_id, doc_id, callback = (error) ->) -> - DocManager.getDoc project_id, doc_id, { _id: true }, (error, doc) -> + DocManager.checkDocExists project_id, doc_id, (error, exists) -> return callback(error) if error? - return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !doc? + return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !exists MongoManager.markDocAsDeleted project_id, doc_id, callback diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 7c8dd0aecf..75298580b3 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -10,7 +10,7 @@ module.exports = HttpController = doc_id = req.params.doc_id include_deleted = req.query?.include_deleted == "true" logger.log project_id: project_id, doc_id: doc_id, "getting doc" - DocManager.getDoc project_id, doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true}, (error, doc) -> + DocManager.getFullDoc project_id, doc_id, (error, doc) -> return next(error) if error? logger.log doc: doc, "got doc" if !doc? @@ -24,7 +24,7 @@ module.exports = HttpController = project_id = req.params.project_id doc_id = req.params.doc_id logger.log project_id: project_id, doc_id: doc_id, "getting raw doc" - DocManager.getDoc project_id, doc_id, {lines: true}, (error, doc) -> + DocManager.getDocLines project_id, doc_id, (error, doc) -> return next(error) if error? if !doc? res.send 404 diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index a7616fcd86..26c627c085 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -16,15 +16,17 @@ describe "Archiving", -> @docs = [{ _id: ObjectId() lines: ["one", "two", "three"] + version:@version rev: 2 }, { _id: ObjectId() lines: ["aaa", "bbb", "ccc"] rev: 4 + version:93 }, { _id: ObjectId() lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] - version:@version + version:313 }] @ranges = [] jobs = for doc in @docs @@ -152,7 +154,7 @@ describe "Archiving", -> done() describe "Unarchiving automatically", -> - it "should unarchive the docs ", (done) -> + it "should unarchive the docs", (done) -> DocstoreClient.archiveAllDoc @project_id, (error, res) => DocstoreClient.getDoc @project_id, @docs[0]._id, {}, (error, res, doc) => doc.lines.should.deep.equal @docs[0].lines diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index c07e6a4e4a..082badd0f3 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -1,6 +1,7 @@ SandboxedModule = require('sandboxed-module') sinon = require('sinon') chai = require('chai') +assert = require("chai").assert chai.should() expect = chai.expect modulePath = require('path').join __dirname, '../../../app/js/DocManager' @@ -26,6 +27,72 @@ describe "DocManager", -> @callback = sinon.stub() @stubbedError = new Error("blew up") + + describe "checkDocExists", -> + beforeEach -> + @DocManager._getDoc = sinon.stub() + + it "should call get doc with a quick filter", (done)-> + @DocManager._getDoc.callsArgWith(3, null, {_id:@doc_id}) + @DocManager.checkDocExists @project_id, @doc_id, (err, exist)=> + exist.should.equal true + @DocManager._getDoc.calledWith(@project_id, @doc_id, {_id:1, inS3:true}).should.equal true + done() + + it "should return false when doc is not there", (done)-> + @DocManager._getDoc.callsArgWith(3, null) + @DocManager.checkDocExists @project_id, @doc_id, (err, exist)=> + exist.should.equal false + done() + + it "should return error when get doc errors", (done)-> + @DocManager._getDoc.callsArgWith(3, "error") + @DocManager.checkDocExists @project_id, @doc_id, (err, exist)=> + err.should.equal "error" + done() + + describe "getFullDoc", -> + beforeEach -> + @DocManager._getDoc = sinon.stub() + @doc = + _id: @doc_id + lines:["2134"] + + it "should call get doc with a quick filter", (done)-> + @DocManager._getDoc.callsArgWith(3, null, @doc) + @DocManager.getFullDoc @project_id, @doc_id, (err, doc)=> + doc.should.equal @doc + @DocManager._getDoc.calledWith(@project_id, @doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}).should.equal true + done() + + it "should return error when get doc errors", (done)-> + @DocManager._getDoc.callsArgWith(3, "error") + @DocManager.getFullDoc @project_id, @doc_id, (err, exist)=> + err.should.equal "error" + done() + + describe "getRawDoc", -> + + beforeEach -> + @DocManager._getDoc = sinon.stub() + @doc = + lines:["2134"] + + it "should call get doc with a quick filter", (done)-> + @DocManager._getDoc.callsArgWith(3, null, @doc) + @DocManager.getDocLines @project_id, @doc_id, (err, doc)=> + doc.should.equal @doc + @DocManager._getDoc.calledWith(@project_id, @doc_id, {lines: true, inS3:true}).should.equal true + done() + + it "should return error when get doc errors", (done)-> + @DocManager._getDoc.callsArgWith(3, "error") + @DocManager.getDocLines @project_id, @doc_id, (err, exist)=> + err.should.equal "error" + done() + + + describe "getDoc", -> beforeEach -> @project = { name: "mock-project" } @@ -38,20 +105,26 @@ describe "DocManager", -> beforeEach -> @MongoManager.findDoc.yields(null, @doc) - it "should always get inS3 even when filter is passed", (done)-> - @DocManager.getDoc @project_id, @doc_id, {version: true}, => - @MongoManager.findDoc.args[0][2].inS3.should.equal true + it "should error if inS3 is not set to true", (done)-> + @DocManager._getDoc @project_id, @doc_id, {inS3: false}, (err)-> + expect(err).to.exist done() it "should always get inS3 even when no filter is passed", (done)-> - @DocManager.getDoc @project_id, @doc_id, undefined, => - @MongoManager.findDoc.args[0][2].inS3.should.equal true + @DocManager._getDoc @project_id, @doc_id, undefined, (err)=> + @MongoManager.findDoc.called.should.equal false + expect(err).to.exist + done() + + it "should not error if inS3 is set to true", (done)-> + @DocManager._getDoc @project_id, @doc_id, {inS3: true}, (err)-> + expect(err).to.not.exist done() describe "when the doc is in the doc collection", -> beforeEach -> @MongoManager.findDoc.yields(null, @doc) - @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback + @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback it "should get the doc from the doc collection", -> @MongoManager.findDoc @@ -72,7 +145,7 @@ describe "DocManager", -> describe "without the version filter", -> beforeEach -> @MongoManager.findDoc.yields(null, @doc) - @DocManager.getDoc @project_id, @doc_id, {version: false}, @callback + @DocManager._getDoc @project_id, @doc_id, {version: false, inS3:true}, @callback it "should not get the doc version from the docOps collection", -> @MongoManager.getDocVersion.called.should.equal false @@ -80,7 +153,7 @@ describe "DocManager", -> describe "when MongoManager.findDoc errors", -> beforeEach -> @MongoManager.findDoc.yields(@stubbedError) - @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback + @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback it "should return the error", -> @callback.calledWith(@stubbedError).should.equal true @@ -93,7 +166,7 @@ describe "DocManager", -> @doc.inS3 = false callback() sinon.spy @DocArchiveManager, "unarchiveDoc" - @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback + @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback it "should call the DocArchive to unarchive the doc", -> @DocArchiveManager.unarchiveDoc.calledWith(@project_id, @doc_id).should.equal true @@ -107,7 +180,7 @@ describe "DocManager", -> describe "when the doc does not exist in the docs collection", -> beforeEach -> @MongoManager.findDoc = sinon.stub().yields(null, null) - @DocManager.getDoc @project_id, @doc_id, {version: true}, @callback + @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback it "should return a NotFoundError", -> @callback @@ -147,12 +220,12 @@ describe "DocManager", -> beforeEach -> @lines = ["mock", "doc", "lines"] @rev = 77 - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, {lines: @lines, rev:@rev}) + @DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, true) @MongoManager.markDocAsDeleted = sinon.stub().callsArg(2) @DocManager.deleteDoc @project_id, @doc_id, @callback it "should get the doc", -> - @DocManager.getDoc + @DocManager.checkDocExists .calledWith(@project_id, @doc_id) .should.equal true @@ -166,10 +239,9 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, null) + @DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, false) @DocManager.deleteDoc @project_id, @doc_id, @callback - it "should return a NotFoundError", -> @callback .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) @@ -202,16 +274,16 @@ describe "DocManager", -> @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @MongoManager.setDocVersion = sinon.stub().yields() - @DocManager.getDoc = sinon.stub() + @DocManager._getDoc = sinon.stub() describe "when only the doc lines have changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback it "should get the existing doc", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id, {version: true, rev: true, lines: true, version: true, ranges: true}) + @DocManager._getDoc + .calledWith(@project_id, @doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}) .should.equal true it "should upsert the document to the doc collection", -> @@ -227,7 +299,7 @@ describe "DocManager", -> describe "when the doc ranges have changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) @RangeManager.shouldUpdateRanges.returns true @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @newRanges, @callback @@ -244,7 +316,7 @@ describe "DocManager", -> describe "when only the version has changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @originalRanges, @callback it "should not change the lines or ranges", -> @@ -260,7 +332,7 @@ describe "DocManager", -> describe "when the doc has not changed at all", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @originalRanges, @callback it "should not update the ranges or lines", -> @@ -296,7 +368,7 @@ describe "DocManager", -> describe "when there is a generic error getting the doc", -> beforeEach -> @error = new Error("doc could not be found") - @DocManager.getDoc = sinon.stub().callsArgWith(3, @error, null, null) + @DocManager._getDoc = sinon.stub().callsArgWith(3, @error, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback it "should not upsert the document to the doc collection", -> @@ -307,7 +379,7 @@ describe "DocManager", -> describe "when the doc lines have not changed", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @originalRanges, @callback it "should not update the doc", -> @@ -318,7 +390,7 @@ describe "DocManager", -> describe "when the doc does not exist", -> beforeEach -> - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, null, null) + @DocManager._getDoc = sinon.stub().callsArgWith(3, null, null, null) @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback it "should upsert the document to the doc collection", -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 1a0752d850..0f32f4b9e3 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -40,12 +40,12 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, @doc) @HttpController.getDoc @req, @res, @next it "should get the document with the version (including deleted)", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true}) + @DocManager.getFullDoc + .calledWith(@project_id, @doc_id) .should.equal true it "should return the doc as JSON", -> @@ -63,11 +63,11 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @deletedDoc) + @DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, @deletedDoc) it "should get the doc from the doc manager", -> @HttpController.getDoc @req, @res, @next - @DocManager.getDoc.calledWith(@project_id, @doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true}).should.equal true + @DocManager.getFullDoc.calledWith(@project_id, @doc_id).should.equal true it "should return 404 if the query string delete is not set ", -> @HttpController.getDoc @req, @res, @next @@ -91,12 +91,12 @@ describe "HttpController", -> @req.params = project_id: @project_id doc_id: @doc_id - @DocManager.getDoc = sinon.stub().callsArgWith(3, null, @doc) + @DocManager.getDocLines = sinon.stub().callsArgWith(2, null, @doc) @HttpController.getRawDoc @req, @res, @next it "should get the document without the version", -> - @DocManager.getDoc - .calledWith(@project_id, @doc_id, {lines: true}) + @DocManager.getDocLines + .calledWith(@project_id, @doc_id) .should.equal true it "should set the content type header", -> From e879f9c742250127dbdcdaf1c0b82c9a82e28f83 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Thu, 16 Mar 2017 16:46:58 +0000 Subject: [PATCH 123/349] Upgrade metrics --- services/docstore/app.coffee | 1 - .../docstore/app/coffee/MongoManager.coffee | 41 ++++++++++++++++++- .../test/unit/coffee/MongoManagerTests.coffee | 3 +- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index e41593cd4c..f81b4f3ea8 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -9,7 +9,6 @@ Path = require "path" Metrics.initialize("docstore") logger.initialize("docstore") -Metrics.mongodb.monitor(Path.resolve(__dirname + "/node_modules/mongojs/node_modules/mongodb"), logger) Metrics.event_loop?.monitor(logger) app = express() diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index fe6f06e8cb..a39c8fb4d9 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -1,4 +1,6 @@ {db, ObjectId} = require "./mongojs" +logger = require 'logger-sharelatex' +metrics = require 'metrics-sharelatex' module.exports = MongoManager = @@ -67,4 +69,41 @@ module.exports = MongoManager = $set: version: version }, { upsert: true - }, callback \ No newline at end of file + }, callback + + +metrics.timeAsyncMethod( + MongoManager, 'findDoc', + 'MongoManager.findDoc', + logger +) +metrics.timeAsyncMethod( + MongoManager, 'getProjectsDocs', + 'MongoManager.getProjectsDocs', + logger +) +metrics.timeAsyncMethod( + MongoManager, 'getArchivedProjectDocs', + 'MongoManager.getArchivedProjectDocs', + logger +) +metrics.timeAsyncMethod( + MongoManager, 'upsertIntoDocCollection', + 'MongoManager.upsertIntoDocCollection', + logger +) +metrics.timeAsyncMethod( + MongoManager, 'markDocAsArchived', + 'MongoManager.markDocAsArchived', + logger +) +metrics.timeAsyncMethod( + MongoManager, 'getDocVersion', + 'MongoManager.getDocVersion', + logger +) +metrics.timeAsyncMethod( + MongoManager, 'setDocVersion', + 'MongoManager.setDocVersion', + logger +) diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index b65de2cde9..29ca1e958b 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -11,6 +11,7 @@ describe "MongoManager", -> "./mongojs": db: @db = { docs: {}, docOps: {} } ObjectId: ObjectId + 'metrics-sharelatex': {timeAsyncMethod: sinon.stub()} @project_id = ObjectId().toString() @doc_id = ObjectId().toString() @callback = sinon.stub() @@ -151,4 +152,4 @@ describe "MongoManager", -> .should.equal true it "should call the callback", -> - @callback.called.should.equal true \ No newline at end of file + @callback.called.should.equal true From bc37c844ea84d385096dac78110236c76edf250c Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Fri, 17 Mar 2017 15:27:36 +0000 Subject: [PATCH 124/349] update to new metrics api --- .../docstore/app/coffee/MongoManager.coffee | 45 +++++-------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index a39c8fb4d9..27d9bd163e 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -72,38 +72,13 @@ module.exports = MongoManager = }, callback -metrics.timeAsyncMethod( - MongoManager, 'findDoc', - 'MongoManager.findDoc', - logger -) -metrics.timeAsyncMethod( - MongoManager, 'getProjectsDocs', - 'MongoManager.getProjectsDocs', - logger -) -metrics.timeAsyncMethod( - MongoManager, 'getArchivedProjectDocs', - 'MongoManager.getArchivedProjectDocs', - logger -) -metrics.timeAsyncMethod( - MongoManager, 'upsertIntoDocCollection', - 'MongoManager.upsertIntoDocCollection', - logger -) -metrics.timeAsyncMethod( - MongoManager, 'markDocAsArchived', - 'MongoManager.markDocAsArchived', - logger -) -metrics.timeAsyncMethod( - MongoManager, 'getDocVersion', - 'MongoManager.getDocVersion', - logger -) -metrics.timeAsyncMethod( - MongoManager, 'setDocVersion', - 'MongoManager.setDocVersion', - logger -) +[ + 'findDoc', + 'getProjectsDocs', + 'getArchivedProjectDocs', + 'upsertIntoDocCollection', + 'markDocAsArchived', + 'getDocVersion', + 'setDocVersion' +].map (method) -> + metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger) From 8b02ba95b61b3c6630ff4c8c90edcee16c84cf8e Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 10 Mar 2017 10:36:48 +0000 Subject: [PATCH 125/349] add missing error handler --- services/docstore/app/coffee/DocManager.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 6cf679c6c1..29677e1dc5 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -33,6 +33,8 @@ module.exports = DocManager = getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> DocArchive.unArchiveAllDocs project_id, (error) -> + if error? + return callback(error) MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> if err? return callback(error) From ce01b39967ee63dab4652c0042827b9ed3713731 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Tue, 21 Mar 2017 13:48:21 +0000 Subject: [PATCH 126/349] Update metrics version to 1.7.0 --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index d603ce0313..27ec9a72c2 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -10,7 +10,7 @@ "dependencies": { "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.1.0", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.0", "mongojs": "0.18.2", "express": "~4.1.1", "underscore": "~1.6.0", From a9ab7b739d9ef3708b735279406fe82ee3feccab Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Thu, 30 Mar 2017 17:13:43 +0100 Subject: [PATCH 127/349] Archive ranges as well as doc lines --- .../app/coffee/DocArchiveManager.coffee | 84 +++- .../docstore/app/coffee/MongoManager.coffee | 1 + .../docstore/app/coffee/RangeManager.coffee | 19 +- .../acceptance/coffee/ArchiveDocsTests.coffee | 466 +++++++++++++----- .../coffee/helpers/DocstoreClient.coffee | 5 +- .../test/unit/coffee/DocArchiveManager.coffee | 14 +- 6 files changed, 436 insertions(+), 153 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 925ad3bfc9..a4ae7c2344 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -6,12 +6,13 @@ async = require "async" settings = require("settings-sharelatex") request = require("request") crypto = require("crypto") +RangeManager = require("./RangeManager") thirtySeconds = 30 * 1000 module.exports = DocArchive = archiveAllDocs: (project_id, callback = (err, docs) ->) -> - MongoManager.getProjectsDocs project_id, {include_deleted: true}, {lines: true, rev: true, inS3: true}, (err, docs) -> + MongoManager.getProjectsDocs project_id, {include_deleted: true}, {lines: true, ranges: true, rev: true, inS3: true}, (err, docs) -> if err? return callback(err) else if !docs? @@ -26,21 +27,26 @@ module.exports = DocArchive = archiveDoc: (project_id, doc, callback)-> logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" try - options = DocArchive.buildS3Options(doc.lines, project_id+"/"+doc._id) + options = DocArchive.buildS3Options(project_id+"/"+doc._id) catch e return callback e - request.put options, (err, res)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, project_id:project_id, doc_id: doc._id, statusCode: res?.statusCode, "something went wrong archiving doc in aws" - return callback new Error("Error in S3 request") - md5lines = crypto.createHash("md5").update(JSON.stringify(doc.lines), "utf8").digest("hex") - md5response = res.headers.etag.toString().replace(/\"/g, '') - if md5lines != md5response - logger.err responseMD5:md5response, linesMD5:md5lines, project_id:project_id, doc_id: doc?._id, "err in response md5 from s3" - return callback new Error("Error in S3 md5 response") - MongoManager.markDocAsArchived doc._id, doc.rev, (err) -> - return callback(err) if err? - callback() + DocArchive._mongoDocToS3Doc doc, (error, json_doc) -> + return callback(error) if error? + options.body = json_doc + options.headers = + 'Content-Type': "application/json" + request.put options, (err, res) -> + if err? || res.statusCode != 200 + logger.err err:err, res:res, project_id:project_id, doc_id: doc._id, statusCode: res?.statusCode, "something went wrong archiving doc in aws" + return callback new Error("Error in S3 request") + md5lines = crypto.createHash("md5").update(json_doc, "utf8").digest("hex") + md5response = res.headers.etag.toString().replace(/\"/g, '') + if md5lines != md5response + logger.err responseMD5:md5response, linesMD5:md5lines, project_id:project_id, doc_id: doc?._id, "err in response md5 from s3" + return callback new Error("Error in S3 md5 response") + MongoManager.markDocAsArchived doc._id, doc.rev, (err) -> + return callback(err) if err? + callback() unArchiveAllDocs: (project_id, callback = (err) ->) -> MongoManager.getArchivedProjectDocs project_id, (err, docs) -> @@ -60,23 +66,50 @@ module.exports = DocArchive = unarchiveDoc: (project_id, doc_id, callback)-> logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" try - options = DocArchive.buildS3Options(true, project_id+"/"+doc_id) + options = DocArchive.buildS3Options(project_id+"/"+doc_id) catch e return callback e - request.get options, (err, res, lines)-> + options.json = true + request.get options, (err, res, doc)-> if err? || res.statusCode != 200 logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong unarchiving doc from aws" return callback new Errors.NotFoundError("Error in S3 request") - MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), {lines}, (err) -> - return callback(err) if err? - logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" - request.del options, (err, res, body)-> - if err? || res.statusCode != 204 - logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong deleting doc from aws" - return callback new Errors.NotFoundError("Error in S3 request") - callback() + DocArchive._s3DocToMongoDoc doc, (error, mongo_doc) -> + return callback(error) if error? + MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), mongo_doc, (err) -> + return callback(err) if err? + logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" + request.del options, (err, res, body)-> + if err? || res.statusCode != 204 + logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong deleting doc from aws" + return callback new Errors.NotFoundError("Error in S3 request") + callback() + + _s3DocToMongoDoc: (doc, callback = (error, mongo_doc) ->) -> + mongo_doc = {} + if doc.schema_v == 1 and doc.lines? + mongo_doc.lines = doc.lines + if doc.ranges? + mongo_doc.ranges = RangeManager.jsonRangesToMongo(doc.ranges) + else if doc instanceof Array + mongo_doc.lines = doc + else + return callback(new Error("I don't understand the doc format in s3")) + return callback null, mongo_doc - buildS3Options: (content, key)-> + _mongoDocToS3Doc: (doc, callback = (error, s3_doc) ->) -> + json = JSON.stringify({ + lines: doc.lines + ranges: doc.ranges + schema_v: 1 + }) + if json.indexOf("\u0000") != -1 + error = new Error("null bytes detected") + logger.error {err: error, project_id, doc_id}, error.message + return callback(error) + return callback null, json + + buildS3Options: (key)-> if !settings.docstore.s3? throw new Error("S3 settings are not configured") return { @@ -85,6 +118,5 @@ module.exports = DocArchive = secret: settings.docstore.s3.secret bucket: settings.docstore.s3.bucket timeout: thirtySeconds - json: content uri:"https://#{settings.docstore.s3.bucket}.s3.amazonaws.com/#{key}" } \ No newline at end of file diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index fe6f06e8cb..0f713e6064 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -42,6 +42,7 @@ module.exports = MongoManager = $unset: {} update.$set["inS3"] = true update.$unset["lines"] = true + update.$unset["ranges"] = true query = _id: doc_id rev: rev diff --git a/services/docstore/app/coffee/RangeManager.coffee b/services/docstore/app/coffee/RangeManager.coffee index 661d6e4b28..61b0a62246 100644 --- a/services/docstore/app/coffee/RangeManager.coffee +++ b/services/docstore/app/coffee/RangeManager.coffee @@ -16,16 +16,21 @@ module.exports = RangeManager = jsonRangesToMongo: (ranges) -> return null if !ranges? + + updateMetadata = (metadata) -> + if metadata?.ts? + metadata.ts = new Date(metadata.ts) + if metadata?.user_id? + metadata.user_id = RangeManager._safeObjectId(metadata.user_id) + for change in ranges.changes or [] - change.id = @_safeObjectId(change.id) - if change.metadata?.ts? - change.metadata.ts = new Date(change.metadata.ts) - if change.metadata?.user_id? - change.metadata.user_id = @_safeObjectId(change.metadata.user_id) + change.id = RangeManager._safeObjectId(change.id) + updateMetadata(change.metadata) for comment in ranges.comments or [] - comment.id = @_safeObjectId(comment.id) + comment.id = RangeManager._safeObjectId(comment.id) if comment.op?.t? - comment.op.t = @_safeObjectId(comment.op.t) + comment.op.t = RangeManager._safeObjectId(comment.op.t) + updateMetadata(comment.metadata) return ranges _safeObjectId: (data) -> diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 7bec662ab2..00d6ade7a4 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -1,152 +1,386 @@ sinon = require "sinon" chai = require("chai") should = chai.should() -{db, ObjectId} = require "../../../app/js/mongojs" +{db, ObjectId, ISODate} = require "../../../app/js/mongojs" async = require "async" Settings = require("settings-sharelatex") +DocArchiveManager = require("../../../app/js/DocArchiveManager.js") +request = require "request" DocstoreClient = require "./helpers/DocstoreClient" describe "Archiving", -> - beforeEach (done) -> - @callback = sinon.stub() - @project_id = ObjectId() - @docs = [{ - _id: ObjectId() - lines: ["one", "two", "three"] - rev: 2 - }, { - _id: ObjectId() - lines: ["aaa", "bbb", "ccc"] - rev: 4 - }, { - _id: ObjectId() - lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] - rev: 6 - }] - @version = 42 - @ranges = [] - jobs = for doc in @docs - do (doc) => - (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, @version, @ranges, (err)=> - doc.lines[0] = doc.lines[0]+" added" - DocstoreClient.updateDoc @project_id, doc._id, doc.lines, @version, @ranges, callback - # Make sure archiving works on deleted docs too - jobs.push (cb) => - DocstoreClient.deleteDoc @project_id, @docs[2]._id, cb - async.series jobs, done - - afterEach (done) -> - db.docs.remove({project_id: @project_id}, done) - - describe "Archiving all docs", -> - beforeEach (done) -> - - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - done() - - it "should archive all the docs", (done) -> - @res.statusCode.should.equal 204 - done() - - it "should set inS3 and unset lines in each doc", (done) -> - - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => - should.not.exist doc.lines - doc.inS3.should.equal true - callback() - async.series jobs, done - - it "should be able get the same docs back", (done) -> - - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() - callback() - async.series jobs, done - - describe "Arching all docs twice", -> - beforeEach (done) -> - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - @res.statusCode.should.equal 204 + describe "multiple docs in a project", -> + before (done) -> + @project_id = ObjectId() + @docs = [{ + _id: ObjectId() + lines: ["one", "two", "three"] + ranges: {} + version: 2 + }, { + _id: ObjectId() + lines: ["aaa", "bbb", "ccc"] + ranges: {} + version: 4 + }] + jobs = for doc in @docs + do (doc) => + (callback) => + DocstoreClient.createDoc @project_id, doc._id, doc.lines, doc.version, doc.ranges, callback + async.series jobs, (error) => + throw error if error? DocstoreClient.archiveAllDoc @project_id, (error, @res) => - @res.statusCode.should.equal 204 done() - + it "should archive all the docs", (done) -> @res.statusCode.should.equal 204 done() - it "should set inS3 and unset lines in each doc", (done) -> - - jobs = for archiveDoc in @docs - do (archiveDoc) => + it "should set inS3 and unset lines and ranges in each doc", (done) -> + jobs = for doc in @docs + do (doc) => (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => + db.docs.findOne _id: doc._id, (error, doc) => should.not.exist doc.lines + should.not.exist doc.ranges doc.inS3.should.equal true callback() async.series jobs, done - it "should be able get the same docs back", (done) -> - - jobs = for archiveDoc in @docs - do (archiveDoc) => + it "should set the docs in s3 correctly", (done) -> + jobs = for doc in @docs + do (doc) => (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() + DocstoreClient.getS3Doc @project_id, doc._id, (error, res, s3_doc) => + s3_doc.lines.should.deep.equal doc.lines + s3_doc.ranges.should.deep.equal doc.ranges callback() async.series jobs, done + + describe "after unarchiving from a request for the project", -> + before (done) -> + DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => + throw error if error? + done() + + it "should return the docs", (done) -> + for doc, i in @fetched_docs + doc.lines.should.deep.equal @docs[i].lines + done() + + it "should restore the docs to mongo", (done) -> + jobs = for doc, i in @docs + do (doc, i) => + (callback) => + db.docs.findOne _id: doc._id, (error, doc) => + doc.lines.should.deep.equal @docs[i].lines + doc.ranges.should.deep.equal @docs[i].ranges + should.not.exist doc.inS3 + callback() + async.series jobs, done + + describe "a deleted doc", -> + before (done) -> + @project_id = ObjectId() + @doc = { + _id: ObjectId() + lines: ["one", "two", "three"] + ranges: {} + version: 2 + } + DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => + throw error if error? + DocstoreClient.deleteDoc @project_id, @doc._id, (error) => + throw error if error? + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + throw error if error? + done() + + it "should successully archive the docs", (done) -> + @res.statusCode.should.equal 204 + done() - describe "Archiving a large document", (done)-> - beforeEach (done)-> + it "should set inS3 and unset lines and ranges in each doc", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + should.not.exist doc.lines + should.not.exist doc.ranges + doc.inS3.should.equal true + doc.deleted.should.equal true + done() + + it "should set the doc in s3 correctly", (done) -> + DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => + throw error if error? + s3_doc.lines.should.deep.equal @doc.lines + s3_doc.ranges.should.deep.equal @doc.ranges + done() + + describe "after unarchiving from a request for the project", -> + before (done) -> + DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => + throw error if error? + done() + + it "should not included the deleted", (done) -> + @fetched_docs.length.should.equal 0 + done() + + it "should restore the doc to mongo", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + doc.lines.should.deep.equal @doc.lines + doc.ranges.should.deep.equal @doc.ranges + should.not.exist doc.inS3 + doc.deleted.should.equal true + done() + + describe "a doc with large lines", -> + before (done) -> + @project_id = ObjectId() @timeout 1000 * 30 quarterMegInBytes = 250000 - lines = require("crypto").randomBytes(quarterMegInBytes).toString("hex") - @docs[1].lines = [lines,lines,lines,lines] - @version = 42 - @ranges = [] - DocstoreClient.updateDoc @project_id, @docs[1]._id, @docs[1].lines, @version, @ranges, () => + big_line = require("crypto").randomBytes(quarterMegInBytes).toString("hex") + @doc = { + _id: ObjectId() + lines: [big_line, big_line, big_line, big_line] + ranges: {} + version: 2 + } + DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => + throw error if error? DocstoreClient.archiveAllDoc @project_id, (error, @res) => + throw error if error? done() - - it "should archive all the docs", (done) -> + + it "should successully archive the docs", (done) -> @res.statusCode.should.equal 204 done() - it "should set inS3 and unset lines in each doc", (done) -> - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - db.docs.findOne _id: archiveDoc._id, (error, doc) => - should.not.exist doc.lines - doc.inS3.should.equal true - callback() - async.series jobs, done + it "should set inS3 and unset lines and ranges in each doc", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + should.not.exist doc.lines + should.not.exist doc.ranges + doc.inS3.should.equal true + done() - it "should be able get the same docs back", (done) -> - jobs = for archiveDoc in @docs - do (archiveDoc) => - (callback) => - DocstoreClient.getS3Doc @project_id, archiveDoc._id, (error, res, doc) => - doc.toString().should.equal archiveDoc.lines.toString() - callback() - async.series jobs, done - - describe "Unarchiving", -> - it "should unarchive all the docs", (done) -> - non_deleted_docs = @docs.slice(0,2) - DocstoreClient.archiveAllDoc @project_id, (error, res) => - DocstoreClient.getAllDocs @project_id, (error, res, docs) => + it "should set the doc in s3 correctly", (done) -> + DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => + throw error if error? + s3_doc.lines.should.deep.equal @doc.lines + s3_doc.ranges.should.deep.equal @doc.ranges + done() + + describe "after unarchiving from a request for the project", -> + before (done) -> + DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => throw error if error? - docs.length.should.equal non_deleted_docs.length - for doc, i in non_deleted_docs - doc.lines.should.deep.equal @docs[i].lines done() + + it "should restore the doc to mongo", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + doc.lines.should.deep.equal @doc.lines + doc.ranges.should.deep.equal @doc.ranges + should.not.exist doc.inS3 + done() + + describe "a doc with naughty strings", -> + before (done) -> + @project_id = ObjectId() + @doc = { + _id: ObjectId() + lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] + ranges: {} + version: 2 + } + DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => + throw error if error? + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + throw error if error? + done() + + it "should successully archive the docs", (done) -> + @res.statusCode.should.equal 204 + done() + + it "should set inS3 and unset lines and ranges in each doc", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + should.not.exist doc.lines + should.not.exist doc.ranges + doc.inS3.should.equal true + done() + + it "should set the doc in s3 correctly", (done) -> + DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => + throw error if error? + s3_doc.lines.should.deep.equal @doc.lines + s3_doc.ranges.should.deep.equal @doc.ranges + done() + + describe "after unarchiving from a request for the project", -> + before (done) -> + DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => + throw error if error? + done() + + it "should restore the doc to mongo", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + doc.lines.should.deep.equal @doc.lines + doc.ranges.should.deep.equal @doc.ranges + should.not.exist doc.inS3 + done() + + describe "a doc with ranges", -> + before (done) -> + @project_id = ObjectId() + @doc = { + _id: ObjectId() + lines: ["one", "two", "three"] + ranges: { + changes: + [{ + id : ObjectId(), + op : { "i" : "foo", "p" : 24 } + metadata : { "user_id" : ObjectId(), "ts" : new Date("2017-01-27T16:10:44.194Z") } + }, { + id : ObjectId(), + op : { "d" : "bar", "p" : 50 } + metadata : { "user_id" : ObjectId(), "ts" : new Date("2017-01-27T18:10:44.194Z") } + }] + comments: [{ + id: ObjectId(), + op: { "c" : "comment", "p" : 284, "t" : ObjectId() }, + metadata: { "user_id" : ObjectId(), "ts" : new Date("2017-01-26T14:22:04.869Z") } + }] + } + version: 2 + } + DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => + throw error if error? + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + throw error if error? + done() + + it "should successully archive the docs", (done) -> + @res.statusCode.should.equal 204 + done() + + it "should set inS3 and unset lines and ranges in each doc", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + should.not.exist doc.lines + should.not.exist doc.ranges + doc.inS3.should.equal true + done() + + it "should set the doc in s3 correctly", (done) -> + DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => + throw error if error? + s3_doc.lines.should.deep.equal @doc.lines + ranges = JSON.parse(JSON.stringify(@doc.ranges)) # ObjectId -> String + s3_doc.ranges.should.deep.equal ranges + done() + + describe "after unarchiving from a request for the project", -> + before (done) -> + DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => + throw error if error? + done() + + it "should restore the doc to mongo", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + doc.lines.should.deep.equal @doc.lines + doc.ranges.should.deep.equal @doc.ranges + should.not.exist doc.inS3 + done() + + describe "a doc that is archived twice", -> + before (done) -> + @project_id = ObjectId() + @doc = { + _id: ObjectId() + lines: ["abc", "def", "ghi"] + ranges: {} + version: 2 + } + DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => + throw error if error? + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + throw error if error? + @res.statusCode.should.equal 204 + DocstoreClient.archiveAllDoc @project_id, (error, @res) => + throw error if error? + @res.statusCode.should.equal 204 + done() + + it "should set inS3 and unset lines and ranges in each doc", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + should.not.exist doc.lines + should.not.exist doc.ranges + doc.inS3.should.equal true + done() + + it "should set the doc in s3 correctly", (done) -> + DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => + throw error if error? + s3_doc.lines.should.deep.equal @doc.lines + s3_doc.ranges.should.deep.equal @doc.ranges + done() + + describe "after unarchiving from a request for the project", -> + before (done) -> + DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => + throw error if error? + done() + + it "should restore the doc to mongo", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + doc.lines.should.deep.equal @doc.lines + doc.ranges.should.deep.equal @doc.ranges + should.not.exist doc.inS3 + done() + + describe "a doc with the old schema (just an array of lines)", -> + before (done) -> + @project_id = ObjectId() + @doc = { + _id: ObjectId() + lines: ["abc", "def", "ghi"] + ranges: {} + version: 2 + } + options = DocArchiveManager.buildS3Options("#{@project_id}/#{@doc._id}") + options.json = @doc.lines + request.put options, (error, res, body) => + throw error if error? + res.statusCode.should.equal 200 + db.docs.insert { + project_id: @project_id + _id: @doc._id + rev: @doc.version + inS3: true + }, (error) => + throw error if error? + DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => + throw error if error? + done() + + it "should restore the doc to mongo", (done) -> + db.docs.findOne _id: @doc._id, (error, doc) => + throw error if error? + doc.lines.should.deep.equal @doc.lines + should.not.exist doc.inS3 + done() + + it "should return the doc", (done) -> + @fetched_docs[0].lines.should.deep.equal @doc.lines + done() diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 05d8069d69..755f12d9b0 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -48,5 +48,6 @@ module.exports = DocstoreClient = getS3Doc: (project_id, doc_id, callback = (error, res, body) ->) -> - options = DocArchiveManager.buildS3Options(true, project_id+"/"+doc_id) - request.get options, callback + options = DocArchiveManager.buildS3Options(project_id+"/"+doc_id) + options.json = true + request.get options, callback diff --git a/services/docstore/test/unit/coffee/DocArchiveManager.coffee b/services/docstore/test/unit/coffee/DocArchiveManager.coffee index cac4594dd2..baa5e57bb1 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManager.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManager.coffee @@ -71,6 +71,7 @@ describe "DocArchiveManager", -> "settings-sharelatex": @settings "./MongoManager": @MongoManager "request": @request + "./RangeManager": @RangeManager = {} "logger-sharelatex": log:-> err:-> @@ -87,13 +88,22 @@ describe "DocArchiveManager", -> @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> opts = @request.put.args[0][0] assert.deepEqual(opts.aws, {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket}) - opts.json.should.equal @mongoDocs[0].lines + opts.body.should.equal JSON.stringify( + lines: @mongoDocs[0].lines + ranges: @mongoDocs[0].ranges + schema_v: 1 + ) opts.timeout.should.equal (30*1000) opts.uri.should.equal "https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{@mongoDocs[0]._id}" done() it "should return no md5 error", (done)-> - @md5 = crypto.createHash("md5").update(JSON.stringify(@mongoDocs[0].lines)).digest("hex") + data = JSON.stringify( + lines: @mongoDocs[0].lines + ranges: @mongoDocs[0].ranges + schema_v: 1 + ) + @md5 = crypto.createHash("md5").update(data).digest("hex") @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:@md5}}) @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> should.not.exist err From f7bc400f225a593441ffe948dcc43e3a84ed4270 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Fri, 31 Mar 2017 11:18:31 +0100 Subject: [PATCH 128/349] upgrade to most recent metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 27ec9a72c2..dacc42948e 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -10,7 +10,7 @@ "dependencies": { "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.0", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.1", "mongojs": "0.18.2", "express": "~4.1.1", "underscore": "~1.6.0", From b14039715f9c265f1c396092b70250f5a9439c03 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Fri, 31 Mar 2017 11:25:23 +0100 Subject: [PATCH 129/349] Stub out logger in tests --- services/docstore/test/unit/coffee/MongoManagerTests.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 29ca1e958b..1a264bf0d2 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -12,6 +12,7 @@ describe "MongoManager", -> db: @db = { docs: {}, docOps: {} } ObjectId: ObjectId 'metrics-sharelatex': {timeAsyncMethod: sinon.stub()} + 'logger-sharelatex': {log: ()->} @project_id = ObjectId().toString() @doc_id = ObjectId().toString() @callback = sinon.stub() From bf187f30ecf6b82b1d4275c6cde66a06dcda3473 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 3 Apr 2017 15:50:33 +0100 Subject: [PATCH 130/349] Add tests for _s3DocToMongo --- .../unit/coffee/DocArchiveManagerTests.coffee | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee index c6c9eacea2..81ed38d177 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee @@ -212,3 +212,45 @@ describe "DocArchiveManager", -> @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> err.should.equal @error done() + + describe "_s3DocToMongoDoc", -> + describe "with the old schema", -> + it "should return the docs lines", (done) -> + @DocArchiveManager._s3DocToMongoDoc ["doc", "lines"], (error, doc) -> + expect(doc).to.deep.equal { + lines: ["doc", "lines"] + } + done() + + describe "with the new schema", -> + it "should return the doc lines and ranges", (done) -> + @RangeManager.jsonRangesToMongo = sinon.stub().returns {"mongo": "ranges"} + @DocArchiveManager._s3DocToMongoDoc { + lines: ["doc", "lines"] + ranges: {"json": "ranges"} + schema_v: 1 + }, (error, doc) -> + expect(doc).to.deep.equal { + lines: ["doc", "lines"] + ranges: {"mongo": "ranges"} + } + done() + + it "should return just the doc lines when there are no ranges", (done) -> + @DocArchiveManager._s3DocToMongoDoc { + lines: ["doc", "lines"] + schema_v: 1 + }, (error, doc) -> + expect(doc).to.deep.equal { + lines: ["doc", "lines"] + } + done() + + describe "with an unrecognised schema", -> + it "should return an error", (done) -> + @DocArchiveManager._s3DocToMongoDoc { + schema_v: 2 + }, (error, doc) -> + expect(error).to.exist + done() + From 7a64f040f196814bd39f3e3e5a7e6df3c52638c8 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Mon, 3 Apr 2017 16:04:54 +0100 Subject: [PATCH 131/349] Test and fix _mongoDocToS3Doc --- .../app/coffee/DocArchiveManager.coffee | 4 +- .../unit/coffee/DocArchiveManagerTests.coffee | 41 ++++++++++++++++++- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 9c16d13d67..12f4b47c82 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -98,6 +98,8 @@ module.exports = DocArchive = return callback null, mongo_doc _mongoDocToS3Doc: (doc, callback = (error, s3_doc) ->) -> + if !doc.lines? + return callback(new Error("doc has no lines")) json = JSON.stringify({ lines: doc.lines ranges: doc.ranges @@ -105,7 +107,7 @@ module.exports = DocArchive = }) if json.indexOf("\u0000") != -1 error = new Error("null bytes detected") - logger.error {err: error, project_id, doc_id}, error.message + logger.err {err: error, doc, json}, error.message return callback(error) return callback null, json diff --git a/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee index 81ed38d177..2b9287d912 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee @@ -75,11 +75,13 @@ describe "DocArchiveManager", -> "logger-sharelatex": log:-> err:-> + @globals = + JSON: JSON @error = "my errror" @project_id = ObjectId().toString() @stubbedError = new Errors.NotFoundError("Error in S3 request") - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires + @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires, globals: @globals describe "archiveDoc", -> @@ -253,4 +255,41 @@ describe "DocArchiveManager", -> }, (error, doc) -> expect(error).to.exist done() + + describe "_mongoDocToS3Doc", -> + describe "with a valid doc", -> + it "should return the json version", (done) -> + @DocArchiveManager._mongoDocToS3Doc doc = { + lines: ["doc", "lines"] + ranges: { "mock": "ranges" } + }, (err, s3_doc) -> + expect(s3_doc).to.equal JSON.stringify({ + lines: ["doc", "lines"] + ranges: { "mock": "ranges" } + schema_v: 1 + }) + done() + + describe "with null bytes in the result", -> + beforeEach -> + @_stringify = JSON.stringify + JSON.stringify = sinon.stub().returns '{"bad": "\u0000"}' + + afterEach -> + JSON.stringify = @_stringify + + it "should return an error", (done) -> + @DocArchiveManager._mongoDocToS3Doc { + lines: ["doc", "lines"] + ranges: { "mock": "ranges" } + }, (err, s3_doc) -> + expect(err).to.exist + done() + + describe "without doc lines", -> + it "should return an error", (done) -> + @DocArchiveManager._mongoDocToS3Doc {}, (err, s3_doc) -> + expect(err).to.exist + done() + From b9b0596d8307e5f576cd2b49133ba39b3fb550cf Mon Sep 17 00:00:00 2001 From: Brian Gough <bjg@network-theory.co.uk> Date: Tue, 27 Jun 2017 16:58:20 +0100 Subject: [PATCH 132/349] optimistically load all docs --- .../docstore/app/coffee/DocManager.coffee | 31 +++++++++++++------ .../test/unit/coffee/DocManagerTests.coffee | 23 ++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index d9f0bd6747..45d2158dbf 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -55,17 +55,28 @@ module.exports = DocManager = return callback(err) callback(err, doc) - getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> - DocArchive.unArchiveAllDocs project_id, (error) -> - if error? + _getAllDocs: (project_id, filter, callback = (error, docs) ->) -> + MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> + if err? return callback(error) - MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> - if err? - return callback(error) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - else - return callback(null, docs) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + else + callback(null, docs) + + getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> + DocManager._getAllDocs project_id, filter, (error, docs) -> + return callback(error) if error? + # check if any docs have been archived + docsInS3 = (doc for doc in docs when doc?.inS3) + if docsInS3.length > 0 + DocArchive.unArchiveAllDocs project_id, (error) -> + if error? + logger.err err:error, project_id:project_id, "error unarchiving docs" + return callback(error) + DocManager._getAllDocs project_id, filter, callback + else + return callback(null, docs) updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) -> if !lines? or !version? or !ranges? diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 082badd0f3..00cf54f04e 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -215,6 +215,29 @@ describe "DocManager", -> .calledWith(new Errors.NotFoundError("No docs for project #{@project_id}")) .should.equal true + describe "when there are some archived docs for the project", -> + beforeEach -> + @stubs = [{ _id: @doc_id, project_id: @project_id, inS3:true }] + @docs = [{ _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] }] + @MongoManager.getProjectsDocs = sinon.stub() + .callsArgWith(3, null, @stubs) # first call + .callsArgWith(3, null, @docs) # second call (after unarchiving) + @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null) + @DocManager.getAllNonDeletedDocs @project_id, @filter, @callback + + it "should get the project from the database", -> + @MongoManager.getProjectsDocs + .calledWith(@project_id, {include_deleted: false}, @filter) + .should.equal true + + it "should unarchive the documents", -> + @DocArchiveManager.unArchiveAllDocs + .calledWith(@project_id) + .should.equal true + + it "should return the docs", -> + @callback.calledWith(null, @docs).should.equal true + describe "deleteDoc", -> describe "when the doc exists", -> beforeEach -> From a2ac37ac99d6f969dbdb6752208df9b3cd31cbdb Mon Sep 17 00:00:00 2001 From: Brian Gough <bjg@network-theory.co.uk> Date: Wed, 28 Jun 2017 10:06:50 +0100 Subject: [PATCH 133/349] comments about optimistic loading --- services/docstore/app/coffee/DocManager.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 45d2158dbf..a6192d083d 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -65,6 +65,7 @@ module.exports = DocManager = callback(null, docs) getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> + # load docs optimistically, only unarchive if results are incomplete DocManager._getAllDocs project_id, filter, (error, docs) -> return callback(error) if error? # check if any docs have been archived @@ -74,8 +75,10 @@ module.exports = DocManager = if error? logger.err err:error, project_id:project_id, "error unarchiving docs" return callback(error) + # now reload the docs after unarchiving DocManager._getAllDocs project_id, filter, callback else + # return docs immediately, nothing in s3 return callback(null, docs) updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) -> From abe90cad101394a5c1ed2f472f05f5700028c27c Mon Sep 17 00:00:00 2001 From: Brian Gough <bjg@network-theory.co.uk> Date: Fri, 30 Jun 2017 14:54:11 +0100 Subject: [PATCH 134/349] Revert "Merge pull request #23 from sharelatex/bg-optimise-get-all-docs" This reverts commit c1337cf23f37bd9ba48419accf1f54c00390e0ea, reversing changes made to fbb2fa15bf4239db006db742f906554d61a0eac4. --- .../docstore/app/coffee/DocManager.coffee | 34 ++++++------------- .../test/unit/coffee/DocManagerTests.coffee | 23 ------------- 2 files changed, 10 insertions(+), 47 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index a6192d083d..d9f0bd6747 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -55,31 +55,17 @@ module.exports = DocManager = return callback(err) callback(err, doc) - _getAllDocs: (project_id, filter, callback = (error, docs) ->) -> - MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> - if err? - return callback(error) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - else - callback(null, docs) - getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> - # load docs optimistically, only unarchive if results are incomplete - DocManager._getAllDocs project_id, filter, (error, docs) -> - return callback(error) if error? - # check if any docs have been archived - docsInS3 = (doc for doc in docs when doc?.inS3) - if docsInS3.length > 0 - DocArchive.unArchiveAllDocs project_id, (error) -> - if error? - logger.err err:error, project_id:project_id, "error unarchiving docs" - return callback(error) - # now reload the docs after unarchiving - DocManager._getAllDocs project_id, filter, callback - else - # return docs immediately, nothing in s3 - return callback(null, docs) + DocArchive.unArchiveAllDocs project_id, (error) -> + if error? + return callback(error) + MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> + if err? + return callback(error) + else if !docs? + return callback new Errors.NotFoundError("No docs for project #{project_id}") + else + return callback(null, docs) updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) -> if !lines? or !version? or !ranges? diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 00cf54f04e..082badd0f3 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -215,29 +215,6 @@ describe "DocManager", -> .calledWith(new Errors.NotFoundError("No docs for project #{@project_id}")) .should.equal true - describe "when there are some archived docs for the project", -> - beforeEach -> - @stubs = [{ _id: @doc_id, project_id: @project_id, inS3:true }] - @docs = [{ _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] }] - @MongoManager.getProjectsDocs = sinon.stub() - .callsArgWith(3, null, @stubs) # first call - .callsArgWith(3, null, @docs) # second call (after unarchiving) - @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null) - @DocManager.getAllNonDeletedDocs @project_id, @filter, @callback - - it "should get the project from the database", -> - @MongoManager.getProjectsDocs - .calledWith(@project_id, {include_deleted: false}, @filter) - .should.equal true - - it "should unarchive the documents", -> - @DocArchiveManager.unArchiveAllDocs - .calledWith(@project_id) - .should.equal true - - it "should return the docs", -> - @callback.calledWith(null, @docs).should.equal true - describe "deleteDoc", -> describe "when the doc exists", -> beforeEach -> From ca42638ab3ee0c19f20ebb8d801ec7195e4790ee Mon Sep 17 00:00:00 2001 From: Joe Green <joe.green0991@gmail.com> Date: Fri, 11 Aug 2017 11:09:41 +0100 Subject: [PATCH 135/349] Create Jenkinsfile --- services/docstore/Jenkinsfile | 83 +++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 services/docstore/Jenkinsfile diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile new file mode 100644 index 0000000000..8fc9e5251b --- /dev/null +++ b/services/docstore/Jenkinsfile @@ -0,0 +1,83 @@ +pipeline { + + agent { + docker { + image 'node:4.2.1' + args "-v /var/lib/jenkins/.npm:/tmp/.npm" + } + } + + environment { + HOME = "/tmp" + } + + triggers { + pollSCM('* * * * *') + cron('@daily') + } + + stages { + stage('Set up') { + steps { + // we need to disable logallrefupdates, else git clones during the npm install will require git to lookup the user id + // which does not exist in the container's /etc/passwd file, causing the clone to fail. + sh 'git config --global core.logallrefupdates false' + } + } + stage('Install') { + steps { + sh 'rm -fr node_modules' + sh 'npm install' + sh 'npm rebuild' + sh 'npm install --quiet grunt-cli' + } + } + stage('Compile') { + steps { + sh 'node_modules/.bin/grunt install' + } + } + stage('Test') { + steps { + sh 'NODE_ENV=development node_modules/.bin/grunt test:unit' + } + } + stage('Acceptance Tests') { + steps { + echo "TODO - Run Acceptance Tests" + //sh 'docker run -v "$(pwd):/app" --rm sl-acceptance-test-runner' + } + } + stage('Package') { + steps { + sh 'touch build.tar.gz' // Avoid tar warning about files changing during read + sh 'tar -czf build.tar.gz --exclude=build.tar.gz --exclude-vcs .' + } + } + stage('Publish') { + steps { + 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") + } + } + } + } + + post { + failure { + mail(from: "${EMAIL_ALERT_FROM}", + to: "${EMAIL_ALERT_TO}", + subject: "Jenkins build failed: ${JOB_NAME}:${BUILD_NUMBER}", + body: "Build: ${BUILD_URL}") + } + } + + // 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') + } +} From 26ab98f04ad23ab5306564a38bc4020111de441f Mon Sep 17 00:00:00 2001 From: Joe Green <joe.green0991@gmail.com> Date: Mon, 14 Aug 2017 15:34:34 +0100 Subject: [PATCH 136/349] run acceptance tests --- services/docstore/Jenkinsfile | 56 ++++++++++++++++------------------- 1 file changed, 26 insertions(+), 30 deletions(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 8fc9e5251b..4e2760b794 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -1,51 +1,47 @@ pipeline { + + agent any - agent { - docker { - image 'node:4.2.1' - args "-v /var/lib/jenkins/.npm:/tmp/.npm" - } - } - - environment { - HOME = "/tmp" - } - triggers { pollSCM('* * * * *') cron('@daily') } stages { - stage('Set up') { + stage('Install') { + agent { + docker { + image 'node:4.2.1' + args "-v /var/lib/jenkins/.npm:/tmp/.npm -e HOME=/tmp" + reuseNode true + } + } steps { // we need to disable logallrefupdates, else git clones during the npm install will require git to lookup the user id // which does not exist in the container's /etc/passwd file, causing the clone to fail. sh 'git config --global core.logallrefupdates false' - } - } - stage('Install') { - steps { sh 'rm -fr node_modules' - sh 'npm install' - sh 'npm rebuild' + sh 'npm install && npm rebuild' sh 'npm install --quiet grunt-cli' } } - stage('Compile') { + stage('Compile and Test') { + agent { + docker { + image 'node:4.2.1' + reuseNode true + } + } steps { sh 'node_modules/.bin/grunt install' - } - } - stage('Test') { - steps { + sh 'node_modules/.bin/grunt compile:acceptance_tests' sh 'NODE_ENV=development node_modules/.bin/grunt test:unit' } } stage('Acceptance Tests') { steps { - echo "TODO - Run Acceptance Tests" - //sh 'docker run -v "$(pwd):/app" --rm sl-acceptance-test-runner' + sh 'docker pull sharelatex/acceptance-test-runner' + sh 'docker run --rm -v $(pwd):/app sharelatex/acceptance-test-runner' } } stage('Package') { @@ -62,21 +58,21 @@ pipeline { } } } - + post { failure { - mail(from: "${EMAIL_ALERT_FROM}", - to: "${EMAIL_ALERT_TO}", + mail(from: "${EMAIL_ALERT_FROM}", + to: "${EMAIL_ALERT_TO}", subject: "Jenkins build failed: ${JOB_NAME}:${BUILD_NUMBER}", body: "Build: ${BUILD_URL}") } } - + // 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') } From 172060c06653bcae82bcdfe5c91f237c64026841 Mon Sep 17 00:00:00 2001 From: Joe Green <joe.green0991@gmail.com> Date: Mon, 14 Aug 2017 15:44:40 +0100 Subject: [PATCH 137/349] Use correct env vars --- services/docstore/Jenkinsfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 4e2760b794..57601daec9 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -41,7 +41,9 @@ pipeline { stage('Acceptance Tests') { steps { sh 'docker pull sharelatex/acceptance-test-runner' - sh 'docker run --rm -v $(pwd):/app sharelatex/acceptance-test-runner' + withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET', usernameVariable: 'AWS_ID')]) { + sh 'docker run --rm -e AWS_BUCKET="sl-doc-archive-testing" -e AWS_ACCESS_KEY_ID=$AWS_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET -v $(pwd):/app sharelatex/acceptance-test-runner' + } } } stage('Package') { From 1f3b0a371316ff12ca392d83be158b0b9fea277b Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Tue, 22 Aug 2017 08:26:30 +0100 Subject: [PATCH 138/349] Upgrade mongojs dependency to version 2.4.0 - Upgrade in package.json - Use new connection syntax - Fix unit tests, issues with object equality --- services/docstore/app/coffee/mongojs.coffee | 2 +- services/docstore/package.json | 2 +- .../test/unit/coffee/MongoManagerTests.coffee | 50 ++++++++----------- 3 files changed, 22 insertions(+), 32 deletions(-) diff --git a/services/docstore/app/coffee/mongojs.coffee b/services/docstore/app/coffee/mongojs.coffee index db3d3c00d8..0153c3cfcd 100644 --- a/services/docstore/app/coffee/mongojs.coffee +++ b/services/docstore/app/coffee/mongojs.coffee @@ -1,6 +1,6 @@ Settings = require "settings-sharelatex" mongojs = require "mongojs" -db = mongojs.connect(Settings.mongo.url, ["docs", "docOps"]) +db = mongojs(Settings.mongo.url, ["docs", "docOps"]) module.exports = db: db ObjectId: mongojs.ObjectId diff --git a/services/docstore/package.json b/services/docstore/package.json index dacc42948e..4d6a7e379a 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -11,7 +11,7 @@ "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.1", - "mongojs": "0.18.2", + "mongojs": "2.4.0", "express": "~4.1.1", "underscore": "~1.6.0", "body-parser": "~1.0.2", diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 1a264bf0d2..8b65402ac3 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -26,12 +26,10 @@ describe "MongoManager", -> @MongoManager.findDoc @project_id, @doc_id, @filter, @callback it "should find the doc", -> - @db.docs.find - .calledWith({ - _id: ObjectId(@doc_id) - project_id: ObjectId(@project_id) - }, @filter) - .should.equal true + @db.docs.find.lastCall.args.slice(0,2).should.deep.equal([ + {_id: ObjectId(@doc_id), project_id: ObjectId(@project_id)}, + @filter + ]) it "should call the callback with the doc", -> @callback.calledWith(null, @doc).should.equal true @@ -50,12 +48,9 @@ describe "MongoManager", -> @MongoManager.getProjectsDocs @project_id, include_deleted: false, @filter, @callback it "should find the non-deleted docs via the project_id", -> - @db.docs.find - .calledWith({ - project_id: ObjectId(@project_id) - deleted: { $ne: true } - }, @filter) - .should.equal true + @db.docs.find.lastCall.args.slice(0,1).should.deep.equal([ + {project_id: ObjectId(@project_id), deleted: {$ne: true}} + ]) it "should call the callback with the docs", -> @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true @@ -65,11 +60,10 @@ describe "MongoManager", -> @MongoManager.getProjectsDocs @project_id, include_deleted: true, @filter, @callback it "should find all via the project_id", -> - @db.docs.find - .calledWith({ - project_id: ObjectId(@project_id) - }, @filter) - .should.equal true + @db.docs.find.lastCall.args.slice(0,2).should.deep.equal([ + {project_id: ObjectId(@project_id)}, + @filter + ]) it "should call the callback with the docs", -> @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true @@ -119,9 +113,10 @@ describe "MongoManager", -> @MongoManager.getDocVersion @doc_id, @callback it "should look for the doc in the database", -> - @db.docOps.find - .calledWith({ doc_id: ObjectId(@doc_id) }, {version: 1}) - .should.equal true + @db.docOps.find.lastCall.args.slice(0,2).should.deep.equal([ + { doc_id: ObjectId(@doc_id) }, + {version: 1} + ]) it "should call the callback with the version", -> @callback.calledWith(null, @version).should.equal true @@ -141,16 +136,11 @@ describe "MongoManager", -> @MongoManager.setDocVersion @doc_id, @version, @callback it "should update the doc version", -> - @db.docOps.update - .calledWith({ - doc_id: ObjectId(@doc_id) - }, { - $set: - version: @version - }, { - upsert: true - }) - .should.equal true + @db.docOps.update.lastCall.args.slice(0,3).should.deep.equal([ + {doc_id: ObjectId(@doc_id)}, + {$set: {version: @version}}, + {upsert: true} + ]) it "should call the callback", -> @callback.called.should.equal true From 65697cb2f6f322882bfbf23e0938ae89ffbb1932 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Tue, 22 Aug 2017 15:20:43 +0100 Subject: [PATCH 139/349] Upgrade sinonjs, and fix unit tests. - use `sinon.match.has` for error matching - restore previous use of `calledWith` --- services/docstore/package.json | 2 +- .../test/unit/coffee/DocManagerTests.coffee | 12 ++--- .../unit/coffee/HttpControllerTests.coffee | 4 +- .../test/unit/coffee/MongoManagerTests.coffee | 50 +++++++++++-------- 4 files changed, 39 insertions(+), 29 deletions(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 4d6a7e379a..40a866c3cb 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "grunt": "~0.4.4", "bunyan": "~0.22.3", "grunt-bunyan": "~0.5.0", - "sinon": "~1.5.2", + "sinon": "~3.2.1", "sandboxed-module": "~0.3.0", "chai": "~1.9.1", "grunt-forever": "~0.4.4", diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.coffee index 082badd0f3..70cea2e2c8 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocManagerTests.coffee @@ -184,7 +184,7 @@ describe "DocManager", -> it "should return a NotFoundError", -> @callback - .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id} in project #{@project_id}")) + .calledWith(sinon.match.has('message', "No such doc: #{@doc_id} in project #{@project_id}")) .should.equal true describe "getAllNonDeletedDocs", -> @@ -212,7 +212,7 @@ describe "DocManager", -> it "should return a NotFoundError", -> @callback - .calledWith(new Errors.NotFoundError("No docs for project #{@project_id}")) + .calledWith(sinon.match.has('message', "No docs for project #{@project_id}")) .should.equal true describe "deleteDoc", -> @@ -244,7 +244,7 @@ describe "DocManager", -> it "should return a NotFoundError", -> @callback - .calledWith(new Errors.NotFoundError("No such doc: #{@doc_id}")) + .calledWith(sinon.match.has('message', "No such project/doc to delete: #{@project_id}/#{@doc_id}")) .should.equal true describe "updateDoc", -> @@ -349,21 +349,21 @@ describe "DocManager", -> @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @originalRanges, @callback it "should return an error", -> - @callback.calledWith(new Error("no lines, version or ranges provided")).should.equal true + @callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal true describe "when the lines are null", -> beforeEach -> @DocManager.updateDoc @project_id, @doc_id, null, @version, @originalRanges, @callback it "should return an error", -> - @callback.calledWith(new Error("no lines, version or ranges provided")).should.equal true + @callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal true describe "when the ranges are null", -> beforeEach -> @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, null, @callback it "should return an error", -> - @callback.calledWith(new Error("no lines, version or ranges provided")).should.equal true + @callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal true describe "when there is a generic error getting the doc", -> beforeEach -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 0f32f4b9e3..80ec0c64fe 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -174,7 +174,7 @@ describe "HttpController", -> it "should log out an error", -> @logger.error .calledWith( - err: new Error("null doc") + err: sinon.match.has('message', "null doc") project_id: @project_id "encountered null doc" ) @@ -325,4 +325,4 @@ describe "HttpController", -> it "should return a 204 (No Content)", -> @res.send .calledWith(204) - .should.equal true \ No newline at end of file + .should.equal true diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 8b65402ac3..1a264bf0d2 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -26,10 +26,12 @@ describe "MongoManager", -> @MongoManager.findDoc @project_id, @doc_id, @filter, @callback it "should find the doc", -> - @db.docs.find.lastCall.args.slice(0,2).should.deep.equal([ - {_id: ObjectId(@doc_id), project_id: ObjectId(@project_id)}, - @filter - ]) + @db.docs.find + .calledWith({ + _id: ObjectId(@doc_id) + project_id: ObjectId(@project_id) + }, @filter) + .should.equal true it "should call the callback with the doc", -> @callback.calledWith(null, @doc).should.equal true @@ -48,9 +50,12 @@ describe "MongoManager", -> @MongoManager.getProjectsDocs @project_id, include_deleted: false, @filter, @callback it "should find the non-deleted docs via the project_id", -> - @db.docs.find.lastCall.args.slice(0,1).should.deep.equal([ - {project_id: ObjectId(@project_id), deleted: {$ne: true}} - ]) + @db.docs.find + .calledWith({ + project_id: ObjectId(@project_id) + deleted: { $ne: true } + }, @filter) + .should.equal true it "should call the callback with the docs", -> @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true @@ -60,10 +65,11 @@ describe "MongoManager", -> @MongoManager.getProjectsDocs @project_id, include_deleted: true, @filter, @callback it "should find all via the project_id", -> - @db.docs.find.lastCall.args.slice(0,2).should.deep.equal([ - {project_id: ObjectId(@project_id)}, - @filter - ]) + @db.docs.find + .calledWith({ + project_id: ObjectId(@project_id) + }, @filter) + .should.equal true it "should call the callback with the docs", -> @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true @@ -113,10 +119,9 @@ describe "MongoManager", -> @MongoManager.getDocVersion @doc_id, @callback it "should look for the doc in the database", -> - @db.docOps.find.lastCall.args.slice(0,2).should.deep.equal([ - { doc_id: ObjectId(@doc_id) }, - {version: 1} - ]) + @db.docOps.find + .calledWith({ doc_id: ObjectId(@doc_id) }, {version: 1}) + .should.equal true it "should call the callback with the version", -> @callback.calledWith(null, @version).should.equal true @@ -136,11 +141,16 @@ describe "MongoManager", -> @MongoManager.setDocVersion @doc_id, @version, @callback it "should update the doc version", -> - @db.docOps.update.lastCall.args.slice(0,3).should.deep.equal([ - {doc_id: ObjectId(@doc_id)}, - {$set: {version: @version}}, - {upsert: true} - ]) + @db.docOps.update + .calledWith({ + doc_id: ObjectId(@doc_id) + }, { + $set: + version: @version + }, { + upsert: true + }) + .should.equal true it "should call the callback", -> @callback.called.should.equal true From a0e33ae1e8f325bde4894e49c0f513697d439a27 Mon Sep 17 00:00:00 2001 From: Joe Green <joe.green0991@gmail.com> Date: Mon, 4 Sep 2017 14:48:21 +0100 Subject: [PATCH 140/349] added build.txt --- services/docstore/Jenkinsfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 57601daec9..ba51da605e 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -48,6 +48,7 @@ pipeline { } stage('Package') { steps { + sh 'echo ${BUILD_NUMBER} > build_number.txt' sh 'touch build.tar.gz' // Avoid tar warning about files changing during read sh 'tar -czf build.tar.gz --exclude=build.tar.gz --exclude-vcs .' } @@ -56,6 +57,8 @@ pipeline { steps { 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") + // 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") } } } From 05a1939547d0fbe0e37cd0a57ffce6fbf035ee47 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Wed, 20 Sep 2017 09:42:08 +0200 Subject: [PATCH 141/349] Don't log out doc lines and ranges --- services/docstore/app/coffee/DocManager.coffee | 2 +- services/docstore/app/coffee/HttpController.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index d9f0bd6747..34626214da 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -98,7 +98,7 @@ module.exports = DocManager = update.lines = lines if updateRanges update.ranges = ranges - logger.log { project_id, doc_id, oldDoc: doc, update: update }, "updating doc lines and ranges" + logger.log { project_id, doc_id, oldDoc: doc }, "updating doc lines and ranges" modified = true rev += 1 # rev will be incremented in mongo by MongoManager.upsertIntoDocCollection diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 75298580b3..7ebcc4fd44 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -12,7 +12,7 @@ module.exports = HttpController = logger.log project_id: project_id, doc_id: doc_id, "getting doc" DocManager.getFullDoc project_id, doc_id, (error, doc) -> return next(error) if error? - logger.log doc: doc, "got doc" + logger.log {doc_id, project_id}, "got doc" if !doc? res.send 404 else if doc.deleted && !include_deleted From d86a964081948b52a284afdc7e4537cc5122540b Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Wed, 20 Sep 2017 09:52:28 +0200 Subject: [PATCH 142/349] Remove another verbose log object --- services/docstore/app/coffee/DocManager.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.coffee index 34626214da..be55a23e44 100644 --- a/services/docstore/app/coffee/DocManager.coffee +++ b/services/docstore/app/coffee/DocManager.coffee @@ -98,7 +98,7 @@ module.exports = DocManager = update.lines = lines if updateRanges update.ranges = ranges - logger.log { project_id, doc_id, oldDoc: doc }, "updating doc lines and ranges" + logger.log { project_id, doc_id }, "updating doc lines and ranges" modified = true rev += 1 # rev will be incremented in mongo by MongoManager.upsertIntoDocCollection From 80eb7a8edadad6e9bcb09b917ee4e5d69ad93120 Mon Sep 17 00:00:00 2001 From: Joe Green <joe.green0991@gmail.com> Date: Thu, 12 Oct 2017 17:07:29 +0100 Subject: [PATCH 143/349] alert only on master --- services/docstore/Jenkinsfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index ba51da605e..80a0b4dbca 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -66,6 +66,10 @@ pipeline { post { failure { + when { + branch 'master' + } + mail(from: "${EMAIL_ALERT_FROM}", to: "${EMAIL_ALERT_TO}", subject: "Jenkins build failed: ${JOB_NAME}:${BUILD_NUMBER}", From c864cd24bf11e9d55594e82ae1aaf1a055ffd96c Mon Sep 17 00:00:00 2001 From: Joe Green <joe.green0991@gmail.com> Date: Mon, 16 Oct 2017 14:09:54 +0100 Subject: [PATCH 144/349] Update Jenkinsfile --- services/docstore/Jenkinsfile | 4 ---- 1 file changed, 4 deletions(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 80a0b4dbca..ba51da605e 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -66,10 +66,6 @@ pipeline { post { failure { - when { - branch 'master' - } - mail(from: "${EMAIL_ALERT_FROM}", to: "${EMAIL_ALERT_TO}", subject: "Jenkins build failed: ${JOB_NAME}:${BUILD_NUMBER}", From a4cc02dbc38a571d9036aaab2a62d058b5afb5a0 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 29 Dec 2017 08:12:31 +0000 Subject: [PATCH 145/349] Provide hosts as environment settings and add npm run start script --- services/docstore/app/coffee/RangeManager.coffee | 2 +- services/docstore/config/settings.defaults.coffee | 4 ++-- services/docstore/package.json | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/services/docstore/app/coffee/RangeManager.coffee b/services/docstore/app/coffee/RangeManager.coffee index 61b0a62246..4867ffbe19 100644 --- a/services/docstore/app/coffee/RangeManager.coffee +++ b/services/docstore/app/coffee/RangeManager.coffee @@ -36,5 +36,5 @@ module.exports = RangeManager = _safeObjectId: (data) -> try return ObjectId(data) - catch + catch error return data \ No newline at end of file diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index e74334d2ad..42356c41db 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -5,10 +5,10 @@ module.exports = Settings = internal: docstore: port: 3016 - host: "localhost" + host: process.env['LISTEN_ADDRESS'] or "localhost" mongo: - url: 'mongodb://127.0.0.1/sharelatex' + url: "mongodb://#{process.env['MONGO_HOST'] or '127.0.0.1'}/sharelatex" docstore: healthCheck: diff --git a/services/docstore/package.json b/services/docstore/package.json index 40a866c3cb..0850ea8368 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -7,6 +7,10 @@ "type": "git", "url": "https://github.com/sharelatex/docstore-sharelatex.git" }, + "scripts": { + "compile:app": "coffee -o app/js -c app/coffee && coffee -c app.coffee", + "start": "npm run compile:app && node app.js" + }, "dependencies": { "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", From f06bd265729bbfc8e1a9463d04facdefff418381 Mon Sep 17 00:00:00 2001 From: James Allen <james@sharelatex.com> Date: Fri, 29 Dec 2017 10:35:40 +0000 Subject: [PATCH 146/349] Add coffee script dependency --- services/docstore/package.json | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 0850ea8368..cdaab61a34 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -12,29 +12,31 @@ "start": "npm run compile:app && node app.js" }, "dependencies": { - "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", + "async": "~0.8.0", + "body-parser": "~1.0.2", + "coffee-script": "^1.7.1", + "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.1", "mongojs": "2.4.0", - "express": "~4.1.1", - "underscore": "~1.6.0", - "body-parser": "~1.0.2", - "async": "~0.8.0" + "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", + "underscore": "~1.6.0" }, "devDependencies": { - "grunt-execute": "~0.2.1", - "grunt-contrib-clean": "~0.5.0", - "grunt-shell": "~0.7.0", - "grunt-contrib-coffee": "~0.10.1", - "grunt-mocha-test": "~0.10.2", - "grunt": "~0.4.4", "bunyan": "~0.22.3", - "grunt-bunyan": "~0.5.0", - "sinon": "~3.2.1", - "sandboxed-module": "~0.3.0", "chai": "~1.9.1", + "grunt": "~0.4.4", + "grunt-bunyan": "~0.5.0", + "grunt-cli": "^1.2.0", + "grunt-contrib-clean": "~0.5.0", + "grunt-contrib-coffee": "~0.10.1", + "grunt-execute": "~0.2.1", "grunt-forever": "~0.4.4", - "request": "~2.34.0" + "grunt-mocha-test": "~0.10.2", + "grunt-shell": "~0.7.0", + "request": "~2.34.0", + "sandboxed-module": "~0.3.0", + "sinon": "~3.2.1" }, "engines": { "node": "~4.2.1" From dd7386bb5444c925b80f530217ad82571c30184b Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Mon, 16 Apr 2018 14:44:59 +0100 Subject: [PATCH 147/349] Upgrade NodeJS to version 8 --- services/docstore/.nvmrc | 2 +- services/docstore/Jenkinsfile | 4 +- services/docstore/package-lock.json | 2007 +++++++++++++++++++++++++++ services/docstore/package.json | 2 +- 4 files changed, 2011 insertions(+), 4 deletions(-) create mode 100644 services/docstore/package-lock.json diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index fae6e3d04b..2f76972966 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -4.2.1 +8.11.1 diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index ba51da605e..f523b18f18 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -11,7 +11,7 @@ pipeline { stage('Install') { agent { docker { - image 'node:4.2.1' + image 'node:8.11.1' args "-v /var/lib/jenkins/.npm:/tmp/.npm -e HOME=/tmp" reuseNode true } @@ -28,7 +28,7 @@ pipeline { stage('Compile and Test') { agent { docker { - image 'node:4.2.1' + image 'node:8.11.1' reuseNode true } } diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json new file mode 100644 index 0000000000..b8e1564f11 --- /dev/null +++ b/services/docstore/package-lock.json @@ -0,0 +1,2007 @@ +{ + "name": "docstore-sharelatex", + "version": "0.1.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz", + "integrity": "sha1-weBtYT5iRrqHRnjW2bkjibfOMQw=", + "requires": { + "mime": "1.2.11", + "negotiator": "0.4.9" + } + }, + "ansi-styles": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", + "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", + "dev": true + }, + "argparse": { + "version": "0.1.16", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", + "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", + "dev": true, + "requires": { + "underscore": "1.7.0", + "underscore.string": "2.4.0" + }, + "dependencies": { + "underscore": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", + "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", + "dev": true + }, + "underscore.string": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", + "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=", + "dev": true + } + } + }, + "asn1": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", + "dev": true, + "optional": true + }, + "assertion-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "dev": true + }, + "async": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz", + "integrity": "sha1-7mXsdymML/FFa8RBigUtDwZDURI=" + }, + "aws-sign2": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", + "dev": true, + "optional": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "body-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz", + "integrity": "sha1-NGFHmjJ4/gD8rr7DMUu1T8T3tHw=", + "requires": { + "qs": "0.6.6", + "raw-body": "1.1.7", + "type-is": "1.1.0" + } + }, + "boom": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", + "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", + "dev": true, + "requires": { + "hoek": "0.9.1" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, + "broadway": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/broadway/-/broadway-0.3.6.tgz", + "integrity": "sha1-fb7waLlUt5B5Jf1USWO1eKkCuno=", + "dev": true, + "requires": { + "cliff": "0.1.9", + "eventemitter2": "0.4.14", + "nconf": "0.6.9", + "utile": "0.2.1", + "winston": "0.8.0" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + }, + "cliff": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.9.tgz", + "integrity": "sha1-ohHgnGo947oa8n0EnTASUNGIErw=", + "dev": true, + "requires": { + "colors": "0.6.2", + "eyes": "0.1.8", + "winston": "0.8.0" + } + }, + "winston": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.0.tgz", + "integrity": "sha1-YdCDD6aZcGISIGsKK1ymmpMENmg=", + "dev": true, + "requires": { + "async": "0.2.10", + "colors": "0.6.2", + "cycle": "1.0.3", + "eyes": "0.1.8", + "pkginfo": "0.3.1", + "stack-trace": "0.0.7" + } + } + } + }, + "bson": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz", + "integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ==" + }, + "buffer-crc32": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz", + "integrity": "sha1-vj5TgvwCttYySVasGvmKqYsIU0w=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "bunyan": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", + "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", + "dev": true, + "requires": { + "dtrace-provider": "0.2.8", + "mv": "2.1.1" + }, + "dependencies": { + "dtrace-provider": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", + "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", + "dev": true, + "optional": true + } + } + }, + "bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=" + }, + "chai": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", + "integrity": "sha1-Pxog+CsLnXQ3V30k1vErGmnTtZA=", + "dev": true, + "requires": { + "assertion-error": "1.0.0", + "deep-eql": "0.1.3" + } + }, + "chalk": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", + "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", + "dev": true, + "requires": { + "ansi-styles": "1.0.0", + "has-color": "0.1.7", + "strip-ansi": "0.1.1" + } + }, + "cliff": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.10.tgz", + "integrity": "sha1-U74z6p9ZvshWCe4wCsQgdgPlIBM=", + "dev": true, + "requires": { + "colors": "1.0.3", + "eyes": "0.1.8", + "winston": "0.8.3" + }, + "dependencies": { + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + } + } + }, + "coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" + }, + "colors": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", + "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", + "dev": true + }, + "combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "dev": true, + "optional": true, + "requires": { + "delayed-stream": "0.0.5" + } + }, + "commander": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz", + "integrity": "sha1-0bhvkB+LZL2UG96tr5JFMDk76Sg=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "cookie": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", + "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" + }, + "cookie-signature": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", + "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", + "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", + "dev": true, + "optional": true, + "requires": { + "boom": "0.4.2" + } + }, + "ctype": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", + "dev": true, + "optional": true + }, + "cycle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", + "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", + "dev": true + }, + "dateformat": { + "version": "1.0.2-1.2.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", + "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=", + "dev": true + }, + "debug": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz", + "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=" + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", + "dev": true + }, + "delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", + "dev": true, + "optional": true + }, + "diff": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.7.tgz", + "integrity": "sha1-JLuwAcSn1VIhaefKvbLCgU7ZHPQ=", + "dev": true + }, + "director": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/director/-/director-1.2.7.tgz", + "integrity": "sha1-v9N0EHX9f7GlsuE2WMX0vsd3NvM=", + "dev": true + }, + "dtrace-provider": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", + "integrity": "sha1-CweNVReTfYcxAUUtkUZzdVe3XlE=", + "optional": true, + "requires": { + "nan": "2.10.0" + } + }, + "each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" + }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "escape-html": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", + "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" + }, + "esprima": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", + "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", + "dev": true + }, + "event-stream": { + "version": "0.5.3", + "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-0.5.3.tgz", + "integrity": "sha1-t3uTCfcQet3+q2PwwOr9jbC9jBw=", + "dev": true, + "requires": { + "optimist": "0.2.8" + }, + "dependencies": { + "optimist": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.2.8.tgz", + "integrity": "sha1-6YGrfiaLRXlIWTtVZ0wJmoFcrDE=", + "dev": true, + "requires": { + "wordwrap": "0.0.3" + } + } + } + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "express": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.1.2.tgz", + "integrity": "sha1-yx0RQlVximWhvNaVgDbvcgxSlIc=", + "requires": { + "accepts": "1.0.1", + "buffer-crc32": "0.2.1", + "cookie": "0.1.2", + "cookie-signature": "1.0.3", + "debug": "0.8.1", + "escape-html": "1.0.1", + "fresh": "0.2.2", + "merge-descriptors": "0.0.2", + "methods": "0.1.0", + "parseurl": "1.0.1", + "path-to-regexp": "0.1.2", + "qs": "0.6.6", + "range-parser": "1.0.0", + "send": "0.3.0", + "serve-static": "1.1.0", + "type-is": "1.1.0", + "utils-merge": "1.0.0" + } + }, + "eyes": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", + "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", + "dev": true + }, + "findup-sync": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", + "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=", + "dev": true, + "requires": { + "glob": "3.2.11", + "lodash": "2.4.2" + }, + "dependencies": { + "glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", + "dev": true, + "requires": { + "inherits": "2.0.3", + "minimatch": "0.3.0" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + } + } + }, + "flatiron": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/flatiron/-/flatiron-0.4.3.tgz", + "integrity": "sha1-JIz3mj2n19w3nioRySonGcu1QPY=", + "dev": true, + "requires": { + "broadway": "0.3.6", + "director": "1.2.7", + "optimist": "0.6.0", + "prompt": "0.2.14" + }, + "dependencies": { + "optimist": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.0.tgz", + "integrity": "sha1-aUJIJvNAX3nxQub8PZrljU27kgA=", + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + } + } + }, + "forever": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/forever/-/forever-0.14.2.tgz", + "integrity": "sha1-6Tsr2UxXBavBmxXlTDEz1puinGs=", + "dev": true, + "requires": { + "cliff": "0.1.10", + "colors": "0.6.2", + "flatiron": "0.4.3", + "forever-monitor": "1.5.2", + "nconf": "0.6.9", + "nssocket": "0.5.3", + "optimist": "0.6.1", + "timespan": "2.3.0", + "utile": "0.2.1", + "winston": "0.8.3" + } + }, + "forever-agent": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", + "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=", + "dev": true + }, + "forever-monitor": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/forever-monitor/-/forever-monitor-1.5.2.tgz", + "integrity": "sha1-J5OI36k7CFNj1rKKgj7wpq7rNdc=", + "dev": true, + "requires": { + "broadway": "0.3.6", + "minimatch": "1.0.0", + "ps-tree": "0.0.3", + "utile": "0.2.1", + "watch": "0.13.0" + }, + "dependencies": { + "minimatch": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz", + "integrity": "sha1-4N0hILSeG3JM6NcUxSCCKpQ4V20=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + } + } + }, + "form-data": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", + "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", + "dev": true, + "optional": true, + "requires": { + "async": "0.9.2", + "combined-stream": "0.0.7", + "mime": "1.2.11" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true, + "optional": true + } + } + }, + "formatio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "fresh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", + "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" + }, + "fs-extra": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.8.1.tgz", + "integrity": "sha1-Dld5/7/t9RG8dVWVx/A8BtS0Po0=", + "dev": true, + "requires": { + "jsonfile": "1.1.1", + "mkdirp": "0.3.5", + "ncp": "0.4.2", + "rimraf": "2.2.8" + }, + "dependencies": { + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + }, + "ncp": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", + "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", + "dev": true + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "dev": true + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", + "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", + "dev": true + }, + "growl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz", + "integrity": "sha1-3i1mE20ALhErpw8/EMMc98NQsto=", + "dev": true + }, + "grunt": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", + "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=", + "dev": true, + "requires": { + "async": "0.1.22", + "coffee-script": "1.3.3", + "colors": "0.6.2", + "dateformat": "1.0.2-1.2.3", + "eventemitter2": "0.4.14", + "exit": "0.1.2", + "findup-sync": "0.1.3", + "getobject": "0.1.0", + "glob": "3.1.21", + "grunt-legacy-log": "0.1.3", + "grunt-legacy-util": "0.2.0", + "hooker": "0.2.3", + "iconv-lite": "0.2.11", + "js-yaml": "2.0.5", + "lodash": "0.9.2", + "minimatch": "0.2.14", + "nopt": "1.0.10", + "rimraf": "2.2.8", + "underscore.string": "2.2.1", + "which": "1.0.9" + }, + "dependencies": { + "async": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", + "dev": true + }, + "coffee-script": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", + "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=", + "dev": true + }, + "glob": { + "version": "3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", + "dev": true, + "requires": { + "graceful-fs": "1.2.3", + "inherits": "1.0.2", + "minimatch": "0.2.14" + } + }, + "inherits": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", + "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", + "dev": true + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + }, + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, + "grunt-bunyan": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/grunt-bunyan/-/grunt-bunyan-0.5.0.tgz", + "integrity": "sha1-aCnXbgGZQ9owQTk2MaNuKsgpsWw=", + "dev": true, + "requires": { + "lodash": "2.4.2" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + } + } + }, + "grunt-cli": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", + "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", + "dev": true, + "requires": { + "findup-sync": "0.3.0", + "grunt-known-options": "1.1.0", + "nopt": "3.0.6", + "resolve": "1.1.7" + }, + "dependencies": { + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "5.0.15" + } + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1.1.1" + } + } + } + }, + "grunt-contrib-clean": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.5.0.tgz", + "integrity": "sha1-9T397ghJsce0Dp67umn0jExgecU=", + "dev": true, + "requires": { + "rimraf": "2.2.8" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, + "grunt-contrib-coffee": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.10.1.tgz", + "integrity": "sha1-7SLGgp9FiqjqR/hnaEM+mBMUAYY=", + "dev": true, + "requires": { + "chalk": "0.4.0", + "coffee-script": "1.7.1", + "lodash": "2.4.2" + }, + "dependencies": { + "coffee-script": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz", + "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", + "dev": true, + "requires": { + "mkdirp": "0.3.5" + } + }, + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + } + } + }, + "grunt-execute": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.2.2.tgz", + "integrity": "sha1-TpRf5XlZzA3neZCDtrQq7ZYWNQo=", + "dev": true + }, + "grunt-forever": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/grunt-forever/-/grunt-forever-0.4.7.tgz", + "integrity": "sha1-dHDb4a2hFFAhZKTCoAOHXfj+EzA=", + "dev": true, + "requires": { + "forever": "0.14.2" + } + }, + "grunt-known-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz", + "integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=", + "dev": true + }, + "grunt-legacy-log": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", + "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=", + "dev": true, + "requires": { + "colors": "0.6.2", + "grunt-legacy-log-utils": "0.1.1", + "hooker": "0.2.3", + "lodash": "2.4.2", + "underscore.string": "2.3.3" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", + "dev": true + } + } + }, + "grunt-legacy-log-utils": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", + "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=", + "dev": true, + "requires": { + "colors": "0.6.2", + "lodash": "2.4.2", + "underscore.string": "2.3.3" + }, + "dependencies": { + "lodash": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", + "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", + "dev": true + }, + "underscore.string": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", + "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", + "dev": true + } + } + }, + "grunt-legacy-util": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", + "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=", + "dev": true, + "requires": { + "async": "0.1.22", + "exit": "0.1.2", + "getobject": "0.1.0", + "hooker": "0.2.3", + "lodash": "0.9.2", + "underscore.string": "2.2.1", + "which": "1.0.9" + }, + "dependencies": { + "async": { + "version": "0.1.22", + "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", + "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", + "dev": true + } + } + }, + "grunt-mocha-test": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/grunt-mocha-test/-/grunt-mocha-test-0.10.2.tgz", + "integrity": "sha1-PeXc+ZPkN1vhrxkfj1u9H1clbUc=", + "dev": true, + "requires": { + "fs-extra": "0.8.1", + "hooker": "0.2.3", + "mocha": "1.18.2" + } + }, + "grunt-shell": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-0.7.0.tgz", + "integrity": "sha1-K3HlTuXlZTfTTsBr+ZfAbOW000s=", + "dev": true, + "requires": { + "chalk": "0.4.0" + } + }, + "has-color": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", + "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", + "dev": true + }, + "hawk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", + "integrity": "sha1-uQuxaYByhUEdp//LjdJZhQLTtS0=", + "dev": true, + "optional": true, + "requires": { + "boom": "0.4.2", + "cryptiles": "0.2.2", + "hoek": "0.9.1", + "sntp": "0.2.4" + } + }, + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", + "dev": true + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "http-signature": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", + "dev": true, + "optional": true, + "requires": { + "asn1": "0.1.11", + "assert-plus": "0.1.5", + "ctype": "0.5.3" + } + }, + "i": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", + "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=", + "dev": true + }, + "iconv-lite": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", + "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", + "dev": true, + "requires": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "dependencies": { + "commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", + "dev": true + }, + "mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", + "dev": true + } + } + }, + "js-yaml": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", + "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=", + "dev": true, + "requires": { + "argparse": "0.1.16", + "esprima": "1.0.4" + } + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsonfile": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.1.1.tgz", + "integrity": "sha1-2k/WrXfxolUgPqY8e8Mtwx72RDM=", + "dev": true + }, + "just-extend": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", + "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "dev": true + }, + "lazy": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", + "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=", + "dev": true + }, + "lodash": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", + "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", + "dev": true + }, + "logger-sharelatex": { + "version": "git+https://github.com/sharelatex/logger-sharelatex.git#9936550cce120809c11ab934adac8e5e62ab9b35", + "requires": { + "bunyan": "1.5.1", + "coffee-script": "1.4.0", + "raven": "0.8.1" + }, + "dependencies": { + "bunyan": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz", + "integrity": "sha1-X259RMQ7lS9WsPQTCeOrEjkbTi0=", + "requires": { + "dtrace-provider": "0.6.0", + "mv": "2.1.1", + "safe-json-stringify": "1.1.0" + } + }, + "coffee-script": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.4.0.tgz", + "integrity": "sha1-XjvIqsJsAajie/EHcixWVfWtfTY=" + } + } + }, + "lolex": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", + "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", + "dev": true + }, + "lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", + "dev": true + }, + "lsmod": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-0.0.3.tgz", + "integrity": "sha1-F+E9ThrpF1DqVlNUjNiecUetAkQ=" + }, + "lynx": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", + "integrity": "sha1-Mxjc7xaQi4KG6Bisz9sxzXQkj50=", + "requires": { + "mersenne": "0.0.4", + "statsd-parser": "0.0.4" + } + }, + "merge-descriptors": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", + "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" + }, + "mersenne": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", + "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" + }, + "methods": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz", + "integrity": "sha1-M11Cnu/SG3us8unJIqjSvRSjDk8=" + }, + "metrics-sharelatex": { + "version": "git+https://github.com/sharelatex/metrics-sharelatex.git#166961924c599b1f9468f2e17846fa2a9d12372d", + "requires": { + "coffee-script": "1.6.0", + "lynx": "0.1.1", + "underscore": "1.6.0" + }, + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + } + } + }, + "mime": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.11" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.18.2.tgz", + "integrity": "sha1-gAhI+PeITGHu/PoqJzBLqeVEbQs=", + "dev": true, + "requires": { + "commander": "2.0.0", + "debug": "0.8.1", + "diff": "1.0.7", + "glob": "3.2.3", + "growl": "1.7.0", + "jade": "0.26.3", + "mkdirp": "0.3.5" + }, + "dependencies": { + "glob": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz", + "integrity": "sha1-4xPusknHr/qlxHUoaw4RW1mDlGc=", + "dev": true, + "requires": { + "graceful-fs": "2.0.3", + "inherits": "2.0.3", + "minimatch": "0.2.14" + } + }, + "graceful-fs": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz", + "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=", + "dev": true + }, + "minimatch": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", + "dev": true, + "requires": { + "lru-cache": "2.7.3", + "sigmund": "1.0.1" + } + }, + "mkdirp": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", + "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", + "dev": true + } + } + }, + "mongodb": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz", + "integrity": "sha512-3HGLucDg/8EeYMin3k+nFWChTA85hcYDCw1lPsWR6yV9A6RgKb24BkLiZ9ySZR+S0nfBjWoIUS7cyV6ceGx5Gg==", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.19", + "readable-stream": "2.2.7" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "1.0.0", + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "mongodb-core": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz", + "integrity": "sha512-Jt4AtWUkpuW03kRdYGxga4O65O1UHlFfvvInslEfLlGi+zDMxbBe3J2NVmN9qPJ957Mn6Iz0UpMtV80cmxCVxw==", + "requires": { + "bson": "1.0.6", + "require_optional": "1.0.1" + } + }, + "mongojs": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", + "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", + "requires": { + "each-series": "1.0.0", + "mongodb": "2.2.35", + "once": "1.4.0", + "parse-mongo-url": "1.1.1", + "readable-stream": "2.3.6", + "thunky": "0.1.0", + "to-mongodb-core": "2.0.0", + "xtend": "4.0.1" + } + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "0.5.1", + "ncp": "2.0.0", + "rimraf": "2.4.5" + } + }, + "nan": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "optional": true + }, + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true + }, + "nconf": { + "version": "0.6.9", + "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.6.9.tgz", + "integrity": "sha1-lXDvFe1vmuays8jV5xtm0xk81mE=", + "dev": true, + "requires": { + "async": "0.2.9", + "ini": "1.3.5", + "optimist": "0.6.0" + }, + "dependencies": { + "async": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.9.tgz", + "integrity": "sha1-32MGD789Myhqdqr21Vophtn/hhk=", + "dev": true + }, + "optimist": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.0.tgz", + "integrity": "sha1-aUJIJvNAX3nxQub8PZrljU27kgA=", + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + } + } + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, + "negotiator": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", + "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" + }, + "nise": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.2.tgz", + "integrity": "sha512-KPKb+wvETBiwb4eTwtR/OsA2+iijXP+VnlSFYJo3EHjm2yjek1NWxHOUQat3i7xNLm1Bm18UA5j5Wor0yO2GtA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "2.0.0", + "just-extend": "1.1.27", + "lolex": "2.3.2", + "path-to-regexp": "1.7.0", + "text-encoding": "0.6.4" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "dev": true, + "requires": { + "abbrev": "1.1.1" + } + }, + "nssocket": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.5.3.tgz", + "integrity": "sha1-iDyi7GBfXtZKTVGQsmJUAZKPj40=", + "dev": true, + "requires": { + "eventemitter2": "0.4.14", + "lazy": "1.0.11" + } + }, + "oauth-sign": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", + "integrity": "sha1-y1QPk7srIqfVlBaRoojWDo6pOG4=", + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "0.0.8", + "wordwrap": "0.0.3" + } + }, + "parse-mongo-url": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" + }, + "parseurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", + "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-to-regexp": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", + "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" + }, + "pkginfo": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", + "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=", + "dev": true + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "prompt": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/prompt/-/prompt-0.2.14.tgz", + "integrity": "sha1-V3VPZPVD/XsIRXB8gY7OYY8F/9w=", + "dev": true, + "requires": { + "pkginfo": "0.3.1", + "read": "1.0.7", + "revalidator": "0.1.8", + "utile": "0.2.1", + "winston": "0.8.3" + } + }, + "ps-tree": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-0.0.3.tgz", + "integrity": "sha1-2/jXUqf+Ivp9WGNWiUmWEOknbdw=", + "dev": true, + "requires": { + "event-stream": "0.5.3" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true, + "optional": true + }, + "qs": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", + "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" + }, + "range-parser": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", + "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" + }, + "raven": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/raven/-/raven-0.8.1.tgz", + "integrity": "sha1-UVk7tlnHcnjc00gitlq+d7dRuvU=", + "requires": { + "cookie": "0.1.0", + "lsmod": "0.0.3", + "node-uuid": "1.4.8", + "stack-trace": "0.0.7" + }, + "dependencies": { + "cookie": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz", + "integrity": "sha1-kOtGndzpBchm3mh+/EMTHYgB+dA=" + } + } + }, + "raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "requires": { + "bytes": "1.0.0", + "string_decoder": "0.10.31" + } + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "0.0.7" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.1", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.1" + } + } + } + }, + "request": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", + "integrity": "sha1-tdi5UmrdSi1GKfTUFxJFc5lkRa4=", + "dev": true, + "requires": { + "aws-sign2": "0.5.0", + "forever-agent": "0.5.2", + "form-data": "0.1.4", + "hawk": "1.0.0", + "http-signature": "0.10.1", + "json-stringify-safe": "5.0.1", + "mime": "1.2.11", + "node-uuid": "1.4.8", + "oauth-sign": "0.3.0", + "qs": "0.6.6", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.3.0" + } + }, + "require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", + "dev": true + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "2.0.0", + "semver": "5.5.0" + } + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "revalidator": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", + "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=", + "dev": true + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "requires": { + "glob": "6.0.4" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "safe-json-stringify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.1.0.tgz", + "integrity": "sha512-EzBtUaFH9bHYPc69wqjp0efJI/DPNHdFbGE3uIMn4sVbO0zx8vZ8cG4WKxQfOpUOKsQyGBiT2mTqnCw+6nLswA==", + "optional": true + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "sandboxed-module": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", + "integrity": "sha1-8fvvvYCaT2kHO9B8rm/H2y6vX2o=", + "dev": true, + "requires": { + "require-like": "0.1.2", + "stack-trace": "0.0.6" + }, + "dependencies": { + "stack-trace": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", + "integrity": "sha1-HnGb1qJin/CcGJ4Xqe+QKpT8XbA=", + "dev": true + } + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "send": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", + "integrity": "sha1-lxgyRjSAb8dbxPj15R9X2dZmBuc=", + "requires": { + "buffer-crc32": "0.2.1", + "debug": "0.8.0", + "fresh": "0.2.2", + "mime": "1.2.11", + "range-parser": "1.0.0" + }, + "dependencies": { + "debug": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz", + "integrity": "sha1-BUHqkfDlA/3wxe7UGKMlUCNJZ/A=" + } + } + }, + "serve-static": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz", + "integrity": "sha1-RU36Bbs93U5wGokVuDoniqkcVkM=", + "requires": { + "parseurl": "1.0.1", + "send": "0.3.0" + } + }, + "settings-sharelatex": { + "version": "git+https://github.com/sharelatex/settings-sharelatex.git#cbc5e41c1dbe6789721a14b3fdae05bf22546559", + "requires": { + "coffee-script": "1.6.0" + }, + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + } + } + }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", + "dev": true + }, + "sinon": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", + "integrity": "sha512-KY3OLOWpek/I4NGAMHetuutVgS2aRgMR5g5/1LSYvPJ3qo2BopIvk3esFztPxF40RWf/NNNJzdFPriSkXUVK3A==", + "dev": true, + "requires": { + "diff": "3.5.0", + "formatio": "1.2.0", + "lolex": "2.3.2", + "native-promise-only": "0.8.1", + "nise": "1.3.2", + "path-to-regexp": "1.7.0", + "samsam": "1.3.0", + "text-encoding": "0.6.4", + "type-detect": "4.0.8" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + } + } + }, + "sntp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", + "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", + "dev": true, + "optional": true, + "requires": { + "hoek": "0.9.1" + } + }, + "stack-trace": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.7.tgz", + "integrity": "sha1-xy4Il0T8Nln1CM3ONiGvVjTsD/8=" + }, + "statsd-parser": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", + "integrity": "sha1-y9JDlTzELv/VSLXSI4jtaJ7GOb0=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-ansi": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", + "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", + "dev": true + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + }, + "timespan": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", + "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", + "dev": true + }, + "to-mongodb-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "optional": true, + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", + "integrity": "sha1-rWgbaPUyGtKCfEz7G31d8s/pQu4=", + "dev": true, + "optional": true + }, + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + }, + "type-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz", + "integrity": "sha1-0CReyLJnZmjVndDPMlUGBnalfbY=", + "requires": { + "mime": "1.2.11" + } + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + }, + "underscore.string": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", + "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utile": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz", + "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=", + "dev": true, + "requires": { + "async": "0.2.10", + "deep-equal": "1.0.1", + "i": "0.3.6", + "mkdirp": "0.5.1", + "ncp": "0.4.2", + "rimraf": "2.4.5" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + }, + "ncp": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", + "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", + "dev": true + } + } + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + }, + "watch": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.13.0.tgz", + "integrity": "sha1-/MbSs/DoxzSC61Qjmhn9W8+adTw=", + "dev": true, + "requires": { + "minimist": "1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "which": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", + "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", + "dev": true + }, + "winston": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz", + "integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=", + "dev": true, + "requires": { + "async": "0.2.10", + "colors": "0.6.2", + "cycle": "1.0.3", + "eyes": "0.1.8", + "isstream": "0.1.2", + "pkginfo": "0.3.1", + "stack-trace": "0.0.7" + }, + "dependencies": { + "async": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", + "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", + "dev": true + } + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/services/docstore/package.json b/services/docstore/package.json index cdaab61a34..c6c422e4ae 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -39,6 +39,6 @@ "sinon": "~3.2.1" }, "engines": { - "node": "~4.2.1" + "node": "~8.11.1" } } From 6757f70daa8caba566db18003b34e82266d4a555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alberto=20Fern=C3=A1ndez=20Capel?= <alberto.fernandez-capel@overleaf.com> Date: Thu, 19 Apr 2018 14:08:41 +0100 Subject: [PATCH 148/349] Do not specify the node version in .travis.yml So travis picks it from .nvmrc --- services/docstore/.travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/services/docstore/.travis.yml b/services/docstore/.travis.yml index 5c181b1569..febdbb55a3 100644 --- a/services/docstore/.travis.yml +++ b/services/docstore/.travis.yml @@ -1,8 +1,5 @@ language: node_js -node_js: - - "0.10" - before_install: - npm install -g grunt-cli From f0495d8ec6fe08da6eed7180af17bc812a188489 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Thu, 26 Apr 2018 10:24:59 +0100 Subject: [PATCH 149/349] Change to Node 6 --- services/docstore/.nvmrc | 2 +- services/docstore/Jenkinsfile | 4 ++-- services/docstore/package.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index 2f76972966..bbf0c5a541 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -8.11.1 +6.14.1 diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index f523b18f18..5eda26c7a3 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -11,7 +11,7 @@ pipeline { stage('Install') { agent { docker { - image 'node:8.11.1' + image 'node:6.14.1' args "-v /var/lib/jenkins/.npm:/tmp/.npm -e HOME=/tmp" reuseNode true } @@ -28,7 +28,7 @@ pipeline { stage('Compile and Test') { agent { docker { - image 'node:8.11.1' + image 'node:6.14.1' reuseNode true } } diff --git a/services/docstore/package.json b/services/docstore/package.json index c6c422e4ae..ab64a7d3a3 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -39,6 +39,6 @@ "sinon": "~3.2.1" }, "engines": { - "node": "~8.11.1" + "node": "~6.14.1" } } From 0433692aec8e87f17da46347ae2beab00cac8710 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Thu, 26 Apr 2018 10:34:05 +0100 Subject: [PATCH 150/349] remove package-lock file --- services/docstore/package-lock.json | 2007 --------------------------- 1 file changed, 2007 deletions(-) delete mode 100644 services/docstore/package-lock.json diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json deleted file mode 100644 index b8e1564f11..0000000000 --- a/services/docstore/package-lock.json +++ /dev/null @@ -1,2007 +0,0 @@ -{ - "name": "docstore-sharelatex", - "version": "0.1.2", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@sinonjs/formatio": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz", - "integrity": "sha1-weBtYT5iRrqHRnjW2bkjibfOMQw=", - "requires": { - "mime": "1.2.11", - "negotiator": "0.4.9" - } - }, - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true - }, - "argparse": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", - "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=", - "dev": true, - "requires": { - "underscore": "1.7.0", - "underscore.string": "2.4.0" - }, - "dependencies": { - "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", - "dev": true - }, - "underscore.string": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz", - "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs=", - "dev": true - } - } - }, - "asn1": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", - "dev": true, - "optional": true - }, - "assertion-error": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", - "dev": true - }, - "async": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz", - "integrity": "sha1-7mXsdymML/FFa8RBigUtDwZDURI=" - }, - "aws-sign2": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", - "dev": true, - "optional": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "body-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz", - "integrity": "sha1-NGFHmjJ4/gD8rr7DMUu1T8T3tHw=", - "requires": { - "qs": "0.6.6", - "raw-body": "1.1.7", - "type-is": "1.1.0" - } - }, - "boom": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", - "dev": true, - "requires": { - "hoek": "0.9.1" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "broadway": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/broadway/-/broadway-0.3.6.tgz", - "integrity": "sha1-fb7waLlUt5B5Jf1USWO1eKkCuno=", - "dev": true, - "requires": { - "cliff": "0.1.9", - "eventemitter2": "0.4.14", - "nconf": "0.6.9", - "utile": "0.2.1", - "winston": "0.8.0" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - }, - "cliff": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.9.tgz", - "integrity": "sha1-ohHgnGo947oa8n0EnTASUNGIErw=", - "dev": true, - "requires": { - "colors": "0.6.2", - "eyes": "0.1.8", - "winston": "0.8.0" - } - }, - "winston": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.0.tgz", - "integrity": "sha1-YdCDD6aZcGISIGsKK1ymmpMENmg=", - "dev": true, - "requires": { - "async": "0.2.10", - "colors": "0.6.2", - "cycle": "1.0.3", - "eyes": "0.1.8", - "pkginfo": "0.3.1", - "stack-trace": "0.0.7" - } - } - } - }, - "bson": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz", - "integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ==" - }, - "buffer-crc32": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz", - "integrity": "sha1-vj5TgvwCttYySVasGvmKqYsIU0w=" - }, - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" - }, - "bunyan": { - "version": "0.22.3", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", - "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", - "dev": true, - "requires": { - "dtrace-provider": "0.2.8", - "mv": "2.1.1" - }, - "dependencies": { - "dtrace-provider": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", - "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", - "dev": true, - "optional": true - } - } - }, - "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=" - }, - "chai": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", - "integrity": "sha1-Pxog+CsLnXQ3V30k1vErGmnTtZA=", - "dev": true, - "requires": { - "assertion-error": "1.0.0", - "deep-eql": "0.1.3" - } - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "dev": true, - "requires": { - "ansi-styles": "1.0.0", - "has-color": "0.1.7", - "strip-ansi": "0.1.1" - } - }, - "cliff": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/cliff/-/cliff-0.1.10.tgz", - "integrity": "sha1-U74z6p9ZvshWCe4wCsQgdgPlIBM=", - "dev": true, - "requires": { - "colors": "1.0.3", - "eyes": "0.1.8", - "winston": "0.8.3" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - } - } - }, - "coffee-script": { - "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" - }, - "colors": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", - "dev": true - }, - "combined-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", - "dev": true, - "optional": true, - "requires": { - "delayed-stream": "0.0.5" - } - }, - "commander": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz", - "integrity": "sha1-0bhvkB+LZL2UG96tr5JFMDk76Sg=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "cookie": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", - "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" - }, - "cookie-signature": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", - "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cryptiles": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", - "dev": true, - "optional": true, - "requires": { - "boom": "0.4.2" - } - }, - "ctype": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", - "dev": true, - "optional": true - }, - "cycle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", - "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI=", - "dev": true - }, - "dateformat": { - "version": "1.0.2-1.2.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz", - "integrity": "sha1-sCIMAt6YYXQztyhRz0fePfLNvuk=", - "dev": true - }, - "debug": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz", - "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=" - }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "dev": true, - "requires": { - "type-detect": "0.1.1" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "delayed-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", - "dev": true, - "optional": true - }, - "diff": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.7.tgz", - "integrity": "sha1-JLuwAcSn1VIhaefKvbLCgU7ZHPQ=", - "dev": true - }, - "director": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/director/-/director-1.2.7.tgz", - "integrity": "sha1-v9N0EHX9f7GlsuE2WMX0vsd3NvM=", - "dev": true - }, - "dtrace-provider": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", - "integrity": "sha1-CweNVReTfYcxAUUtkUZzdVe3XlE=", - "optional": true, - "requires": { - "nan": "2.10.0" - } - }, - "each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" - }, - "es6-promise": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" - }, - "escape-html": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" - }, - "esprima": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz", - "integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0=", - "dev": true - }, - "event-stream": { - "version": "0.5.3", - "resolved": "http://registry.npmjs.org/event-stream/-/event-stream-0.5.3.tgz", - "integrity": "sha1-t3uTCfcQet3+q2PwwOr9jbC9jBw=", - "dev": true, - "requires": { - "optimist": "0.2.8" - }, - "dependencies": { - "optimist": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.2.8.tgz", - "integrity": "sha1-6YGrfiaLRXlIWTtVZ0wJmoFcrDE=", - "dev": true, - "requires": { - "wordwrap": "0.0.3" - } - } - } - }, - "eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "express": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.1.2.tgz", - "integrity": "sha1-yx0RQlVximWhvNaVgDbvcgxSlIc=", - "requires": { - "accepts": "1.0.1", - "buffer-crc32": "0.2.1", - "cookie": "0.1.2", - "cookie-signature": "1.0.3", - "debug": "0.8.1", - "escape-html": "1.0.1", - "fresh": "0.2.2", - "merge-descriptors": "0.0.2", - "methods": "0.1.0", - "parseurl": "1.0.1", - "path-to-regexp": "0.1.2", - "qs": "0.6.6", - "range-parser": "1.0.0", - "send": "0.3.0", - "serve-static": "1.1.0", - "type-is": "1.1.0", - "utils-merge": "1.0.0" - } - }, - "eyes": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz", - "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A=", - "dev": true - }, - "findup-sync": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", - "integrity": "sha1-fz56l7gjksZTvwZYm9hRkOk8NoM=", - "dev": true, - "requires": { - "glob": "3.2.11", - "lodash": "2.4.2" - }, - "dependencies": { - "glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", - "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "minimatch": "0.3.0" - } - }, - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "minimatch": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", - "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - } - } - }, - "flatiron": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/flatiron/-/flatiron-0.4.3.tgz", - "integrity": "sha1-JIz3mj2n19w3nioRySonGcu1QPY=", - "dev": true, - "requires": { - "broadway": "0.3.6", - "director": "1.2.7", - "optimist": "0.6.0", - "prompt": "0.2.14" - }, - "dependencies": { - "optimist": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.0.tgz", - "integrity": "sha1-aUJIJvNAX3nxQub8PZrljU27kgA=", - "dev": true, - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - } - } - } - }, - "forever": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/forever/-/forever-0.14.2.tgz", - "integrity": "sha1-6Tsr2UxXBavBmxXlTDEz1puinGs=", - "dev": true, - "requires": { - "cliff": "0.1.10", - "colors": "0.6.2", - "flatiron": "0.4.3", - "forever-monitor": "1.5.2", - "nconf": "0.6.9", - "nssocket": "0.5.3", - "optimist": "0.6.1", - "timespan": "2.3.0", - "utile": "0.2.1", - "winston": "0.8.3" - } - }, - "forever-agent": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=", - "dev": true - }, - "forever-monitor": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/forever-monitor/-/forever-monitor-1.5.2.tgz", - "integrity": "sha1-J5OI36k7CFNj1rKKgj7wpq7rNdc=", - "dev": true, - "requires": { - "broadway": "0.3.6", - "minimatch": "1.0.0", - "ps-tree": "0.0.3", - "utile": "0.2.1", - "watch": "0.13.0" - }, - "dependencies": { - "minimatch": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-1.0.0.tgz", - "integrity": "sha1-4N0hILSeG3JM6NcUxSCCKpQ4V20=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - } - } - }, - "form-data": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", - "dev": true, - "optional": true, - "requires": { - "async": "0.9.2", - "combined-stream": "0.0.7", - "mime": "1.2.11" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true, - "optional": true - } - } - }, - "formatio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", - "dev": true, - "requires": { - "samsam": "1.3.0" - } - }, - "fresh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", - "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" - }, - "fs-extra": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.8.1.tgz", - "integrity": "sha1-Dld5/7/t9RG8dVWVx/A8BtS0Po0=", - "dev": true, - "requires": { - "jsonfile": "1.1.1", - "mkdirp": "0.3.5", - "ncp": "0.4.2", - "rimraf": "2.2.8" - }, - "dependencies": { - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - }, - "ncp": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", - "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", - "dev": true - }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - } - } - }, - "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", - "dev": true - }, - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "growl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz", - "integrity": "sha1-3i1mE20ALhErpw8/EMMc98NQsto=", - "dev": true - }, - "grunt": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", - "integrity": "sha1-VpN81RlDJK3/bSB2MYMqnWuk5/A=", - "dev": true, - "requires": { - "async": "0.1.22", - "coffee-script": "1.3.3", - "colors": "0.6.2", - "dateformat": "1.0.2-1.2.3", - "eventemitter2": "0.4.14", - "exit": "0.1.2", - "findup-sync": "0.1.3", - "getobject": "0.1.0", - "glob": "3.1.21", - "grunt-legacy-log": "0.1.3", - "grunt-legacy-util": "0.2.0", - "hooker": "0.2.3", - "iconv-lite": "0.2.11", - "js-yaml": "2.0.5", - "lodash": "0.9.2", - "minimatch": "0.2.14", - "nopt": "1.0.10", - "rimraf": "2.2.8", - "underscore.string": "2.2.1", - "which": "1.0.9" - }, - "dependencies": { - "async": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", - "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", - "dev": true - }, - "coffee-script": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz", - "integrity": "sha1-FQ1rTLUiiUNp7+1qIQHCC8f0pPQ=", - "dev": true - }, - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.2", - "minimatch": "0.2.14" - } - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - }, - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - } - } - }, - "grunt-bunyan": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/grunt-bunyan/-/grunt-bunyan-0.5.0.tgz", - "integrity": "sha1-aCnXbgGZQ9owQTk2MaNuKsgpsWw=", - "dev": true, - "requires": { - "lodash": "2.4.2" - }, - "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - } - } - }, - "grunt-cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", - "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", - "dev": true, - "requires": { - "findup-sync": "0.3.0", - "grunt-known-options": "1.1.0", - "nopt": "3.0.6", - "resolve": "1.1.7" - }, - "dependencies": { - "findup-sync": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", - "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", - "dev": true, - "requires": { - "glob": "5.0.15" - } - }, - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1.1.1" - } - } - } - }, - "grunt-contrib-clean": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.5.0.tgz", - "integrity": "sha1-9T397ghJsce0Dp67umn0jExgecU=", - "dev": true, - "requires": { - "rimraf": "2.2.8" - }, - "dependencies": { - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true - } - } - }, - "grunt-contrib-coffee": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.10.1.tgz", - "integrity": "sha1-7SLGgp9FiqjqR/hnaEM+mBMUAYY=", - "dev": true, - "requires": { - "chalk": "0.4.0", - "coffee-script": "1.7.1", - "lodash": "2.4.2" - }, - "dependencies": { - "coffee-script": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz", - "integrity": "sha1-YplqhheAx15tUGnROCJyO3NAS/w=", - "dev": true, - "requires": { - "mkdirp": "0.3.5" - } - }, - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - } - } - }, - "grunt-execute": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.2.2.tgz", - "integrity": "sha1-TpRf5XlZzA3neZCDtrQq7ZYWNQo=", - "dev": true - }, - "grunt-forever": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/grunt-forever/-/grunt-forever-0.4.7.tgz", - "integrity": "sha1-dHDb4a2hFFAhZKTCoAOHXfj+EzA=", - "dev": true, - "requires": { - "forever": "0.14.2" - } - }, - "grunt-known-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.0.tgz", - "integrity": "sha1-pCdO6zL6dl2lp6OxcSYXzjsUQUk=", - "dev": true - }, - "grunt-legacy-log": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", - "integrity": "sha1-7ClCboAwIa9ZAp+H0vnNczWgVTE=", - "dev": true, - "requires": { - "colors": "0.6.2", - "grunt-legacy-log-utils": "0.1.1", - "hooker": "0.2.3", - "lodash": "2.4.2", - "underscore.string": "2.3.3" - }, - "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "underscore.string": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", - "dev": true - } - } - }, - "grunt-legacy-log-utils": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", - "integrity": "sha1-wHBrndkGThFvNvI/5OawSGcsD34=", - "dev": true, - "requires": { - "colors": "0.6.2", - "lodash": "2.4.2", - "underscore.string": "2.3.3" - }, - "dependencies": { - "lodash": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz", - "integrity": "sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4=", - "dev": true - }, - "underscore.string": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz", - "integrity": "sha1-ccCL9rQosRM/N+ePo6Icgvcymw0=", - "dev": true - } - } - }, - "grunt-legacy-util": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", - "integrity": "sha1-kzJIhNv343qf98Am3/RR2UqeVUs=", - "dev": true, - "requires": { - "async": "0.1.22", - "exit": "0.1.2", - "getobject": "0.1.0", - "hooker": "0.2.3", - "lodash": "0.9.2", - "underscore.string": "2.2.1", - "which": "1.0.9" - }, - "dependencies": { - "async": { - "version": "0.1.22", - "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz", - "integrity": "sha1-D8GqoIig4+8Ovi2IMbqw3PiEUGE=", - "dev": true - } - } - }, - "grunt-mocha-test": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/grunt-mocha-test/-/grunt-mocha-test-0.10.2.tgz", - "integrity": "sha1-PeXc+ZPkN1vhrxkfj1u9H1clbUc=", - "dev": true, - "requires": { - "fs-extra": "0.8.1", - "hooker": "0.2.3", - "mocha": "1.18.2" - } - }, - "grunt-shell": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-0.7.0.tgz", - "integrity": "sha1-K3HlTuXlZTfTTsBr+ZfAbOW000s=", - "dev": true, - "requires": { - "chalk": "0.4.0" - } - }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, - "hawk": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", - "integrity": "sha1-uQuxaYByhUEdp//LjdJZhQLTtS0=", - "dev": true, - "optional": true, - "requires": { - "boom": "0.4.2", - "cryptiles": "0.2.2", - "hoek": "0.9.1", - "sntp": "0.2.4" - } - }, - "hoek": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", - "dev": true - }, - "hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true - }, - "http-signature": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", - "dev": true, - "optional": true, - "requires": { - "asn1": "0.1.11", - "assert-plus": "0.1.5", - "ctype": "0.5.3" - } - }, - "i": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", - "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=", - "dev": true - }, - "iconv-lite": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz", - "integrity": "sha1-HOYKOleGSiktEyH/RgnKS7llrcg=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "jade": { - "version": "0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", - "dev": true, - "requires": { - "commander": "0.6.1", - "mkdirp": "0.3.0" - }, - "dependencies": { - "commander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", - "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", - "dev": true - }, - "mkdirp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", - "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", - "dev": true - } - } - }, - "js-yaml": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz", - "integrity": "sha1-olrmUJmZ6X3yeMZxnaEb0Gh3Q6g=", - "dev": true, - "requires": { - "argparse": "0.1.16", - "esprima": "1.0.4" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsonfile": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.1.1.tgz", - "integrity": "sha1-2k/WrXfxolUgPqY8e8Mtwx72RDM=", - "dev": true - }, - "just-extend": { - "version": "1.1.27", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", - "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", - "dev": true - }, - "lazy": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", - "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=", - "dev": true - }, - "lodash": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz", - "integrity": "sha1-jzSZxSRdNG1oLlsNO0B2fgnxqSw=", - "dev": true - }, - "logger-sharelatex": { - "version": "git+https://github.com/sharelatex/logger-sharelatex.git#9936550cce120809c11ab934adac8e5e62ab9b35", - "requires": { - "bunyan": "1.5.1", - "coffee-script": "1.4.0", - "raven": "0.8.1" - }, - "dependencies": { - "bunyan": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz", - "integrity": "sha1-X259RMQ7lS9WsPQTCeOrEjkbTi0=", - "requires": { - "dtrace-provider": "0.6.0", - "mv": "2.1.1", - "safe-json-stringify": "1.1.0" - } - }, - "coffee-script": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.4.0.tgz", - "integrity": "sha1-XjvIqsJsAajie/EHcixWVfWtfTY=" - } - } - }, - "lolex": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", - "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", - "dev": true - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "lsmod": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-0.0.3.tgz", - "integrity": "sha1-F+E9ThrpF1DqVlNUjNiecUetAkQ=" - }, - "lynx": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", - "integrity": "sha1-Mxjc7xaQi4KG6Bisz9sxzXQkj50=", - "requires": { - "mersenne": "0.0.4", - "statsd-parser": "0.0.4" - } - }, - "merge-descriptors": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", - "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" - }, - "mersenne": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", - "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" - }, - "methods": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz", - "integrity": "sha1-M11Cnu/SG3us8unJIqjSvRSjDk8=" - }, - "metrics-sharelatex": { - "version": "git+https://github.com/sharelatex/metrics-sharelatex.git#166961924c599b1f9468f2e17846fa2a9d12372d", - "requires": { - "coffee-script": "1.6.0", - "lynx": "0.1.1", - "underscore": "1.6.0" - }, - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" - } - } - }, - "mime": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.11" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.18.2.tgz", - "integrity": "sha1-gAhI+PeITGHu/PoqJzBLqeVEbQs=", - "dev": true, - "requires": { - "commander": "2.0.0", - "debug": "0.8.1", - "diff": "1.0.7", - "glob": "3.2.3", - "growl": "1.7.0", - "jade": "0.26.3", - "mkdirp": "0.3.5" - }, - "dependencies": { - "glob": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz", - "integrity": "sha1-4xPusknHr/qlxHUoaw4RW1mDlGc=", - "dev": true, - "requires": { - "graceful-fs": "2.0.3", - "inherits": "2.0.3", - "minimatch": "0.2.14" - } - }, - "graceful-fs": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz", - "integrity": "sha1-fNLNsiiko/Nule+mzBQt59GhNtA=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - }, - "mkdirp": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz", - "integrity": "sha1-3j5fiWHIjHh+4TaN+EmsRBPsqNc=", - "dev": true - } - } - }, - "mongodb": { - "version": "2.2.35", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz", - "integrity": "sha512-3HGLucDg/8EeYMin3k+nFWChTA85hcYDCw1lPsWR6yV9A6RgKb24BkLiZ9ySZR+S0nfBjWoIUS7cyV6ceGx5Gg==", - "requires": { - "es6-promise": "3.2.1", - "mongodb-core": "2.1.19", - "readable-stream": "2.2.7" - }, - "dependencies": { - "readable-stream": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "mongodb-core": { - "version": "2.1.19", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz", - "integrity": "sha512-Jt4AtWUkpuW03kRdYGxga4O65O1UHlFfvvInslEfLlGi+zDMxbBe3J2NVmN9qPJ957Mn6Iz0UpMtV80cmxCVxw==", - "requires": { - "bson": "1.0.6", - "require_optional": "1.0.1" - } - }, - "mongojs": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", - "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", - "requires": { - "each-series": "1.0.0", - "mongodb": "2.2.35", - "once": "1.4.0", - "parse-mongo-url": "1.1.1", - "readable-stream": "2.3.6", - "thunky": "0.1.0", - "to-mongodb-core": "2.0.0", - "xtend": "4.0.1" - } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "mv": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "optional": true, - "requires": { - "mkdirp": "0.5.1", - "ncp": "2.0.0", - "rimraf": "2.4.5" - } - }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "optional": true - }, - "native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true - }, - "nconf": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/nconf/-/nconf-0.6.9.tgz", - "integrity": "sha1-lXDvFe1vmuays8jV5xtm0xk81mE=", - "dev": true, - "requires": { - "async": "0.2.9", - "ini": "1.3.5", - "optimist": "0.6.0" - }, - "dependencies": { - "async": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.9.tgz", - "integrity": "sha1-32MGD789Myhqdqr21Vophtn/hhk=", - "dev": true - }, - "optimist": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.0.tgz", - "integrity": "sha1-aUJIJvNAX3nxQub8PZrljU27kgA=", - "dev": true, - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - } - } - } - }, - "ncp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "optional": true - }, - "negotiator": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", - "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" - }, - "nise": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.2.tgz", - "integrity": "sha512-KPKb+wvETBiwb4eTwtR/OsA2+iijXP+VnlSFYJo3EHjm2yjek1NWxHOUQat3i7xNLm1Bm18UA5j5Wor0yO2GtA==", - "dev": true, - "requires": { - "@sinonjs/formatio": "2.0.0", - "just-extend": "1.1.27", - "lolex": "2.3.2", - "path-to-regexp": "1.7.0", - "text-encoding": "0.6.4" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - } - } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" - }, - "nopt": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", - "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", - "dev": true, - "requires": { - "abbrev": "1.1.1" - } - }, - "nssocket": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.5.3.tgz", - "integrity": "sha1-iDyi7GBfXtZKTVGQsmJUAZKPj40=", - "dev": true, - "requires": { - "eventemitter2": "0.4.14", - "lazy": "1.0.11" - } - }, - "oauth-sign": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", - "integrity": "sha1-y1QPk7srIqfVlBaRoojWDo6pOG4=", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" - } - }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.3" - } - }, - "parse-mongo-url": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" - }, - "parseurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", - "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-to-regexp": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", - "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" - }, - "pkginfo": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", - "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, - "prompt": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/prompt/-/prompt-0.2.14.tgz", - "integrity": "sha1-V3VPZPVD/XsIRXB8gY7OYY8F/9w=", - "dev": true, - "requires": { - "pkginfo": "0.3.1", - "read": "1.0.7", - "revalidator": "0.1.8", - "utile": "0.2.1", - "winston": "0.8.3" - } - }, - "ps-tree": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-0.0.3.tgz", - "integrity": "sha1-2/jXUqf+Ivp9WGNWiUmWEOknbdw=", - "dev": true, - "requires": { - "event-stream": "0.5.3" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true, - "optional": true - }, - "qs": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", - "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" - }, - "range-parser": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", - "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" - }, - "raven": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/raven/-/raven-0.8.1.tgz", - "integrity": "sha1-UVk7tlnHcnjc00gitlq+d7dRuvU=", - "requires": { - "cookie": "0.1.0", - "lsmod": "0.0.3", - "node-uuid": "1.4.8", - "stack-trace": "0.0.7" - }, - "dependencies": { - "cookie": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.0.tgz", - "integrity": "sha1-kOtGndzpBchm3mh+/EMTHYgB+dA=" - } - } - }, - "raw-body": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", - "requires": { - "bytes": "1.0.0", - "string_decoder": "0.10.31" - } - }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "dev": true, - "requires": { - "mute-stream": "0.0.7" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - }, - "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "5.1.1" - } - } - } - }, - "request": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", - "integrity": "sha1-tdi5UmrdSi1GKfTUFxJFc5lkRa4=", - "dev": true, - "requires": { - "aws-sign2": "0.5.0", - "forever-agent": "0.5.2", - "form-data": "0.1.4", - "hawk": "1.0.0", - "http-signature": "0.10.1", - "json-stringify-safe": "5.0.1", - "mime": "1.2.11", - "node-uuid": "1.4.8", - "oauth-sign": "0.3.0", - "qs": "0.6.6", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.3.0" - } - }, - "require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", - "dev": true - }, - "require_optional": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", - "requires": { - "resolve-from": "2.0.0", - "semver": "5.5.0" - } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" - }, - "revalidator": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz", - "integrity": "sha1-/s5hv6DBtSoga9axgZgYS91SOjs=", - "dev": true - }, - "rimraf": { - "version": "2.4.5", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "requires": { - "glob": "6.0.4" - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "safe-json-stringify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.1.0.tgz", - "integrity": "sha512-EzBtUaFH9bHYPc69wqjp0efJI/DPNHdFbGE3uIMn4sVbO0zx8vZ8cG4WKxQfOpUOKsQyGBiT2mTqnCw+6nLswA==", - "optional": true - }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", - "dev": true - }, - "sandboxed-module": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", - "integrity": "sha1-8fvvvYCaT2kHO9B8rm/H2y6vX2o=", - "dev": true, - "requires": { - "require-like": "0.1.2", - "stack-trace": "0.0.6" - }, - "dependencies": { - "stack-trace": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", - "integrity": "sha1-HnGb1qJin/CcGJ4Xqe+QKpT8XbA=", - "dev": true - } - } - }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" - }, - "send": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", - "integrity": "sha1-lxgyRjSAb8dbxPj15R9X2dZmBuc=", - "requires": { - "buffer-crc32": "0.2.1", - "debug": "0.8.0", - "fresh": "0.2.2", - "mime": "1.2.11", - "range-parser": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz", - "integrity": "sha1-BUHqkfDlA/3wxe7UGKMlUCNJZ/A=" - } - } - }, - "serve-static": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz", - "integrity": "sha1-RU36Bbs93U5wGokVuDoniqkcVkM=", - "requires": { - "parseurl": "1.0.1", - "send": "0.3.0" - } - }, - "settings-sharelatex": { - "version": "git+https://github.com/sharelatex/settings-sharelatex.git#cbc5e41c1dbe6789721a14b3fdae05bf22546559", - "requires": { - "coffee-script": "1.6.0" - }, - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" - } - } - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "sinon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", - "integrity": "sha512-KY3OLOWpek/I4NGAMHetuutVgS2aRgMR5g5/1LSYvPJ3qo2BopIvk3esFztPxF40RWf/NNNJzdFPriSkXUVK3A==", - "dev": true, - "requires": { - "diff": "3.5.0", - "formatio": "1.2.0", - "lolex": "2.3.2", - "native-promise-only": "0.8.1", - "nise": "1.3.2", - "path-to-regexp": "1.7.0", - "samsam": "1.3.0", - "text-encoding": "0.6.4", - "type-detect": "4.0.8" - }, - "dependencies": { - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - } - } - }, - "sntp": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", - "dev": true, - "optional": true, - "requires": { - "hoek": "0.9.1" - } - }, - "stack-trace": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.7.tgz", - "integrity": "sha1-xy4Il0T8Nln1CM3ONiGvVjTsD/8=" - }, - "statsd-parser": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", - "integrity": "sha1-y9JDlTzELv/VSLXSI4jtaJ7GOb0=" - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true - }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", - "dev": true - }, - "thunky": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", - "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" - }, - "timespan": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", - "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", - "dev": true - }, - "to-mongodb-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", - "integrity": "sha1-rWgbaPUyGtKCfEz7G31d8s/pQu4=", - "dev": true, - "optional": true - }, - "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", - "dev": true - }, - "type-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz", - "integrity": "sha1-0CReyLJnZmjVndDPMlUGBnalfbY=", - "requires": { - "mime": "1.2.11" - } - }, - "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" - }, - "underscore.string": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz", - "integrity": "sha1-18D6KvXVoaZ/QlPa7pgTLnM/Dxk=", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "utile": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/utile/-/utile-0.2.1.tgz", - "integrity": "sha1-kwyI6ZCY1iIINMNWy9mncFItkNc=", - "dev": true, - "requires": { - "async": "0.2.10", - "deep-equal": "1.0.1", - "i": "0.3.6", - "mkdirp": "0.5.1", - "ncp": "0.4.2", - "rimraf": "2.4.5" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - }, - "ncp": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.4.2.tgz", - "integrity": "sha1-q8xsvT7C7Spyn/bnwfqPAXhKhXQ=", - "dev": true - } - } - }, - "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" - }, - "watch": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/watch/-/watch-0.13.0.tgz", - "integrity": "sha1-/MbSs/DoxzSC61Qjmhn9W8+adTw=", - "dev": true, - "requires": { - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "which": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", - "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", - "dev": true - }, - "winston": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/winston/-/winston-0.8.3.tgz", - "integrity": "sha1-ZLar9M0Brcrv1QCTk7HY6L7BnbA=", - "dev": true, - "requires": { - "async": "0.2.10", - "colors": "0.6.2", - "cycle": "1.0.3", - "eyes": "0.1.8", - "isstream": "0.1.2", - "pkginfo": "0.3.1", - "stack-trace": "0.0.7" - }, - "dependencies": { - "async": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", - "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", - "dev": true - } - } - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - } - } -} From c1947c5cbde6cbfc5678bf05a170f6aacd91f8ce Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 11:27:31 +0100 Subject: [PATCH 151/349] dockerise app, 1.1.3 build scripts --- services/docstore/.dockerignore | 9 +++ services/docstore/Dockerfile | 22 +++++++ services/docstore/Jenkinsfile | 58 +++++++------------ services/docstore/Makefile | 42 ++++++++++++++ services/docstore/app.coffee | 10 +++- services/docstore/docker-compose.ci.yml | 32 ++++++++++ services/docstore/docker-compose.yml | 39 +++++++++++++ services/docstore/nodemon.json | 19 ++++++ services/docstore/package.json | 13 ++++- .../acceptance/coffee/ArchiveDocsTests.coffee | 7 ++- .../coffee/DeletingDocsTests.coffee | 8 ++- .../coffee/GettingAllDocsTests.coffee | 3 + .../acceptance/coffee/GettingDocsTests.coffee | 8 ++- .../coffee/UpdatingDocsTests.coffee | 8 ++- .../coffee/helpers/DocstoreApp.coffee | 21 +++++++ 15 files changed, 247 insertions(+), 52 deletions(-) create mode 100644 services/docstore/.dockerignore create mode 100644 services/docstore/Dockerfile create mode 100644 services/docstore/Makefile create mode 100644 services/docstore/docker-compose.ci.yml create mode 100644 services/docstore/docker-compose.yml create mode 100644 services/docstore/nodemon.json create mode 100644 services/docstore/test/acceptance/coffee/helpers/DocstoreApp.coffee diff --git a/services/docstore/.dockerignore b/services/docstore/.dockerignore new file mode 100644 index 0000000000..386f26df30 --- /dev/null +++ b/services/docstore/.dockerignore @@ -0,0 +1,9 @@ +node_modules/* +gitrev +.git +.gitignore +.npm +.nvmrc +nodemon.json +app.js +**/js/* diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile new file mode 100644 index 0000000000..9ead057334 --- /dev/null +++ b/services/docstore/Dockerfile @@ -0,0 +1,22 @@ +FROM node:6.14.1 as app + +WORKDIR /app + +#wildcard as some files may not be in all repos +COPY package*.json npm-shrink*.json /app/ + +RUN npm install --quiet + +COPY . /app + + +RUN npm run compile:all + +FROM node:6.14.1 + +COPY --from=app /app /app + +WORKDIR /app +USER node + +CMD ["node","app.js"] diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 5eda26c7a3..bc9ba0142f 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -1,62 +1,42 @@ -pipeline { +String cron_string = BRANCH_NAME == "master" ? "@daily" : "" +pipeline { agent any - + triggers { pollSCM('* * * * *') - cron('@daily') + cron(cron_string) } stages { - stage('Install') { - agent { - docker { - image 'node:6.14.1' - args "-v /var/lib/jenkins/.npm:/tmp/.npm -e HOME=/tmp" - reuseNode true - } - } + stage('Build') { steps { - // we need to disable logallrefupdates, else git clones during the npm install will require git to lookup the user id - // which does not exist in the container's /etc/passwd file, causing the clone to fail. - sh 'git config --global core.logallrefupdates false' - sh 'rm -fr node_modules' - sh 'npm install && npm rebuild' - sh 'npm install --quiet grunt-cli' + sh 'make build' } } - stage('Compile and Test') { - agent { - docker { - image 'node:6.14.1' - reuseNode true - } - } + + stage('Unit Tests') { steps { - sh 'node_modules/.bin/grunt install' - sh 'node_modules/.bin/grunt compile:acceptance_tests' - sh 'NODE_ENV=development node_modules/.bin/grunt test:unit' + sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_unit' } } + stage('Acceptance Tests') { steps { - sh 'docker pull sharelatex/acceptance-test-runner' - withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET', usernameVariable: 'AWS_ID')]) { - sh 'docker run --rm -e AWS_BUCKET="sl-doc-archive-testing" -e AWS_ACCESS_KEY_ID=$AWS_ID -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET -v $(pwd):/app sharelatex/acceptance-test-runner' - } + sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' } } - stage('Package') { + + stage('Package and publish build') { steps { - sh 'echo ${BUILD_NUMBER} > build_number.txt' - sh 'touch build.tar.gz' // Avoid tar warning about files changing during read - sh 'tar -czf build.tar.gz --exclude=build.tar.gz --exclude-vcs .' + sh 'make publish' } } - stage('Publish') { + + stage('Publish build number') { 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") // 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") } @@ -65,6 +45,10 @@ pipeline { } post { + always { + sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_clean' + } + failure { mail(from: "${EMAIL_ALERT_FROM}", to: "${EMAIL_ALERT_TO}", diff --git a/services/docstore/Makefile b/services/docstore/Makefile new file mode 100644 index 0000000000..b3ba01358c --- /dev/null +++ b/services/docstore/Makefile @@ -0,0 +1,42 @@ +# This file was auto-generated, do not edit it directly. +# Instead run bin/update_build_scripts from +# https://github.com/sharelatex/sharelatex-dev-environment +# Version: 1.1.3 + +BUILD_NUMBER ?= local +BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) +PROJECT_NAME = docstore +DOCKER_COMPOSE_FLAGS ?= -f docker-compose.yml +DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ + BRANCH_NAME=$(BRANCH_NAME) \ + PROJECT_NAME=$(PROJECT_NAME) \ + MOCHA_GREP=${MOCHA_GREP} \ + docker-compose ${DOCKER_COMPOSE_FLAGS} + + +clean: + rm -f app.js + rm -rf app/js + rm -rf test/unit/js + rm -rf test/acceptance/js + +test: test_unit test_acceptance + +test_unit: + @[ ! -d test/unit ] && echo "docstore has no unit tests" || $(DOCKER_COMPOSE) run --rm test_unit + +test_acceptance: test_clean test_acceptance_pre_run # clear the database before each acceptance test run + @[ ! -d test/acceptance ] && echo "docstore has no acceptance tests" || $(DOCKER_COMPOSE) run --rm test_acceptance + +test_clean: + $(DOCKER_COMPOSE) down -v -t 0 + +test_acceptance_pre_run: + @[ ! -f test/acceptance/scripts/pre-run ] && echo "docstore has no pre acceptance tests task" || $(DOCKER_COMPOSE) run --rm test_acceptance test/acceptance/scripts/pre-run +build: + docker build --pull --tag gcr.io/csh-gcdm-test/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) . + +publish: + docker push gcr.io/csh-gcdm-test/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + +.PHONY: clean test test_unit test_acceptance test_clean build publish diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index f81b4f3ea8..eb74016ff3 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -52,6 +52,10 @@ app.use (error, req, res, next) -> port = Settings.internal.docstore.port host = Settings.internal.docstore.host -app.listen port, host, (error) -> - throw error if error? - logger.info "Docstore starting up, listening on #{host}:#{port}" + +if !module.parent # Called directly + app.listen port, host, (error) -> + throw error if error? + logger.info "Docstore starting up, listening on #{host}:#{port}" + +module.exports = app \ No newline at end of file diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml new file mode 100644 index 0000000000..21c006641e --- /dev/null +++ b/services/docstore/docker-compose.ci.yml @@ -0,0 +1,32 @@ +# This file was auto-generated, do not edit it directly. +# Instead run bin/update_build_scripts from +# https://github.com/sharelatex/sharelatex-dev-environment +# Version: 1.1.3 + +version: "2" + +services: + test_unit: + image: gcr.io/csh-gcdm-test/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + user: node + command: npm run test:unit:_run + + test_acceptance: + build: . + image: gcr.io/csh-gcdm-test/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + environment: + REDIS_HOST: redis + MONGO_HOST: mongo + POSTGRES_HOST: postgres + depends_on: + - mongo + - redis + user: node + command: npm run test:acceptance:_run + + redis: + image: redis + + mongo: + image: mongo:3.4 + diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml new file mode 100644 index 0000000000..f24caa8883 --- /dev/null +++ b/services/docstore/docker-compose.yml @@ -0,0 +1,39 @@ +# This file was auto-generated, do not edit it directly. +# Instead run bin/update_build_scripts from +# https://github.com/sharelatex/sharelatex-dev-environment +# Version: 1.1.3 + +version: "2" + +services: + test_unit: + build: . + volumes: + - .:/app + working_dir: /app + environment: + MOCHA_GREP: ${MOCHA_GREP} + command: npm run test:unit + user: node + + test_acceptance: + build: . + volumes: + - .:/app + working_dir: /app + environment: + REDIS_HOST: redis + MONGO_HOST: mongo + POSTGRES_HOST: postgres + MOCHA_GREP: ${MOCHA_GREP} + user: node + depends_on: + - mongo + - redis + command: npm run test:acceptance + redis: + image: redis + + mongo: + image: mongo:3.4 + diff --git a/services/docstore/nodemon.json b/services/docstore/nodemon.json new file mode 100644 index 0000000000..98db38d71b --- /dev/null +++ b/services/docstore/nodemon.json @@ -0,0 +1,19 @@ +{ + "ignore": [ + ".git", + "node_modules/" + ], + "verbose": true, + "legacyWatch": true, + "execMap": { + "js": "npm run start" + }, + + "watch": [ + "app/coffee/", + "app.coffee", + "config/" + ], + "ext": "coffee" + +} diff --git a/services/docstore/package.json b/services/docstore/package.json index ab64a7d3a3..2e9db708a1 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -8,8 +8,16 @@ "url": "https://github.com/sharelatex/docstore-sharelatex.git" }, "scripts": { - "compile:app": "coffee -o app/js -c app/coffee && coffee -c app.coffee", - "start": "npm run compile:app && node app.js" + "compile:app": "([ -e app/coffee ] && coffee $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", + "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", + "test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js", + "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", + "test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js", + "test:unit": "npm run compile:app && npm run compile:unit_tests && npm run test:unit:_run -- --grep=$MOCHA_GREP", + "compile:unit_tests": "[ ! -e test/unit/coffee ] && echo 'No unit tests to compile' || coffee -o test/unit/js -c test/unit/coffee", + "compile:acceptance_tests": "[ ! -e test/acceptance/coffee ] && echo 'No acceptance tests to compile' || coffee -o test/acceptance/js -c test/acceptance/coffee", + "compile:all": "npm run compile:app && npm run compile:unit_tests && npm run compile:acceptance_tests", + "nodemon": "nodemon --config nodemon.json" }, "dependencies": { "async": "~0.8.0", @@ -33,6 +41,7 @@ "grunt-execute": "~0.2.1", "grunt-forever": "~0.4.4", "grunt-mocha-test": "~0.10.2", + "mocha": "^4.0.1", "grunt-shell": "~0.7.0", "request": "~2.34.0", "sandboxed-module": "~0.3.0", diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee index 2c457922c0..0291eef032 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee @@ -6,11 +6,15 @@ async = require "async" Settings = require("settings-sharelatex") DocArchiveManager = require("../../../app/js/DocArchiveManager.js") request = require "request" - +DocstoreApp = require "./helpers/DocstoreApp" DocstoreClient = require "./helpers/DocstoreClient" describe "Archiving", -> + + before (done)-> + DocstoreApp.ensureRunning(done) + describe "multiple docs in a project", -> before (done) -> @project_id = ObjectId() @@ -29,6 +33,7 @@ describe "Archiving", -> do (doc) => (callback) => DocstoreClient.createDoc @project_id, doc._id, doc.lines, doc.version, doc.ranges, callback + async.series jobs, (error) => throw error if error? DocstoreClient.archiveAllDoc @project_id, (error, @res) => diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee index 82dbfb4c66..f97a352c14 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -2,6 +2,7 @@ sinon = require "sinon" chai = require("chai") chai.should() {db, ObjectId} = require "../../../app/js/mongojs" +DocstoreApp = require "./helpers/DocstoreApp" DocstoreClient = require "./helpers/DocstoreClient" @@ -12,9 +13,10 @@ describe "Deleting a doc", -> @lines = ["original", "lines"] @version = 42 @ranges = [] - DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => - throw error if error? - done() + DocstoreApp.ensureRunning => + DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => + throw error if error? + done() describe "when the doc exists", -> beforeEach (done) -> diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee index 7244693888..6a16006044 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee @@ -3,6 +3,7 @@ chai = require("chai") chai.should() {ObjectId} = require "mongojs" async = require "async" +DocstoreApp = require "./helpers/DocstoreApp" DocstoreClient = require "./helpers/DocstoreClient" @@ -39,6 +40,8 @@ describe "Getting all docs", -> jobs.push (cb) => DocstoreClient.createDoc @project_id, @deleted_doc._id, @deleted_doc.lines, version, @deleted_doc.ranges, (err)=> DocstoreClient.deleteDoc @project_id, @deleted_doc._id, cb + jobs.unshift (cb)-> + DocstoreApp.ensureRunning cb async.series jobs, done it "getAllDocs should return all the (non-deleted) docs", (done) -> diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee index b17a294f24..dbdbd31aa2 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee @@ -2,6 +2,7 @@ sinon = require "sinon" chai = require("chai") chai.should() {ObjectId} = require "mongojs" +DocstoreApp = require "./helpers/DocstoreApp" DocstoreClient = require "./helpers/DocstoreClient" @@ -20,9 +21,10 @@ describe "Getting a doc", -> ts: new Date().toString() }] } - DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => - throw error if error? - done() + DocstoreApp.ensureRunning => + DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => + throw error if error? + done() describe "when the doc exists", -> it "should get the doc lines and version", (done) -> diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index f34a4e3e76..4d567e8f4c 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -2,6 +2,7 @@ sinon = require "sinon" chai = require("chai") chai.should() {ObjectId} = require "mongojs" +DocstoreApp = require "./helpers/DocstoreApp" DocstoreClient = require "./helpers/DocstoreClient" @@ -30,9 +31,10 @@ describe "Applying updates to a doc", -> }] } @version = 42 - DocstoreClient.createDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error) => - throw error if error? - done() + DocstoreApp.ensureRunning => + DocstoreClient.createDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error) => + throw error if error? + done() describe "when nothing has been updated", -> beforeEach (done) -> diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.coffee new file mode 100644 index 0000000000..4a916955a9 --- /dev/null +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.coffee @@ -0,0 +1,21 @@ +app = require('../../../../app') +require("logger-sharelatex").logger.level("error") +settings = require("settings-sharelatex") + +module.exports = + running: false + initing: false + callbacks: [] + ensureRunning: (callback = (error) ->) -> + if @running + return callback() + else if @initing + @callbacks.push callback + else + @initing = true + @callbacks.push callback + app.listen settings.internal.docstore.port, "localhost", (error) => + throw error if error? + @running = true + for callback in @callbacks + callback() \ No newline at end of file From 37ef1ba81669e7c56f9aa99415d467255ba5992d Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 11:35:30 +0100 Subject: [PATCH 152/349] add empty env block --- services/docstore/Jenkinsfile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index bc9ba0142f..9cb59ee3cf 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -2,6 +2,8 @@ String cron_string = BRANCH_NAME == "master" ? "@daily" : "" pipeline { agent any + + environment {} triggers { pollSCM('* * * * *') From 352a8d3f1930f6013364b9562b1f774cf055979c Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 11:43:54 +0100 Subject: [PATCH 153/349] try withCredentials --- services/docstore/Jenkinsfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 9cb59ee3cf..cdb7b01d22 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -25,10 +25,13 @@ pipeline { stage('Acceptance Tests') { steps { - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' + withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET', usernameVariable: 'AWS_ID')]) { + sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" AWS_BUCKET="sl-doc-archive-testing" AWS_ACCESS_KEY_ID=$AWS_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET make test_acceptance' + } } } + stage('Package and publish build') { steps { sh 'make publish' From a8f40a4fdaee7da5ba896f2fefd4eb364a11fbe4 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 11:45:50 +0100 Subject: [PATCH 154/349] remove env block --- services/docstore/Jenkinsfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index cdb7b01d22..419d524491 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -3,8 +3,6 @@ String cron_string = BRANCH_NAME == "master" ? "@daily" : "" pipeline { agent any - environment {} - triggers { pollSCM('* * * * *') cron(cron_string) From 984b5a0ca4e8af26c6a4f360e064851e08486498 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 12:17:46 +0100 Subject: [PATCH 155/349] pass env vars all the way through (mvp) --- services/docstore/Makefile | 5 ++++- services/docstore/docker-compose.yml | 3 +++ services/docstore/package.json | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/services/docstore/Makefile b/services/docstore/Makefile index b3ba01358c..bc197fbdee 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -11,7 +11,10 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ BRANCH_NAME=$(BRANCH_NAME) \ PROJECT_NAME=$(PROJECT_NAME) \ MOCHA_GREP=${MOCHA_GREP} \ - docker-compose ${DOCKER_COMPOSE_FLAGS} + AWS_BUCKET=${AWS_BUCKET} \ + AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ + AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ + docker-compose ${DOCKER_COMPOSE_FLAGS} clean: diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index f24caa8883..31fe46d3ed 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -25,6 +25,9 @@ services: REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} user: node depends_on: diff --git a/services/docstore/package.json b/services/docstore/package.json index 2e9db708a1..3249de833a 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -10,7 +10,7 @@ "scripts": { "compile:app": "([ -e app/coffee ] && coffee $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", - "test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js", + "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js", "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", "test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js", "test:unit": "npm run compile:app && npm run compile:unit_tests && npm run test:unit:_run -- --grep=$MOCHA_GREP", From ddae704f88ec7b23938637c4bf9fda036bf82add Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 12:20:37 +0100 Subject: [PATCH 156/349] log settings --- services/docstore/config/settings.defaults.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 42356c41db..70aa470850 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -20,4 +20,6 @@ if process.env['AWS_ACCESS_KEY_ID']? and process.env['AWS_SECRET_ACCESS_KEY']? a Settings.docstore.s3 = key: process.env['AWS_ACCESS_KEY_ID'] secret: process.env['AWS_SECRET_ACCESS_KEY'] - bucket: process.env['AWS_BUCKET'] \ No newline at end of file + bucket: process.env['AWS_BUCKET'] +console.log "SETTINGS" +console.log Settings.docstore.s3 \ No newline at end of file From 833bf67622cd76e7c405f8874a390cabb9b2b0c8 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 12:27:43 +0100 Subject: [PATCH 157/349] rewrite jenkins acceptence line --- services/docstore/Jenkinsfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 419d524491..e0a72eb0e3 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -24,7 +24,8 @@ pipeline { stage('Acceptance Tests') { steps { withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET', usernameVariable: 'AWS_ID')]) { - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" AWS_BUCKET="sl-doc-archive-testing" AWS_ACCESS_KEY_ID=$AWS_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET make test_acceptance' + sh 'echo $AWS_ID | wc' + sh 'AWS_BUCKET="sl-doc-archive-testing" AWS_ACCESS_KEY_ID=$AWS_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' } } } From bff7f96d70d46be64160ec60d55a38be9f079e72 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 12:32:37 +0100 Subject: [PATCH 158/349] standarise env vars --- services/docstore/Jenkinsfile | 4 ++-- services/docstore/docker-compose.ci.yml | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index e0a72eb0e3..c9c22b51e1 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -23,9 +23,9 @@ pipeline { stage('Acceptance Tests') { steps { - withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET', usernameVariable: 'AWS_ID')]) { + withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { sh 'echo $AWS_ID | wc' - sh 'AWS_BUCKET="sl-doc-archive-testing" AWS_ACCESS_KEY_ID=$AWS_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' + sh 'AWS_BUCKET="sl-doc-archive-testing" AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' } } } diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 21c006641e..54e86bd1eb 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -18,6 +18,9 @@ services: REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_BUCKET: ${AWS_BUCKET} + MOCHA_GREP: ${MOCHA_GREP} depends_on: - mongo - redis From c334c224bf36c73bb8948ca457aec2bbabf72e9a Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 23 May 2018 12:35:22 +0100 Subject: [PATCH 159/349] pass missing env var --- services/docstore/Jenkinsfile | 1 - services/docstore/docker-compose.ci.yml | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index c9c22b51e1..0b72053319 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -24,7 +24,6 @@ pipeline { stage('Acceptance Tests') { steps { withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { - sh 'echo $AWS_ID | wc' sh 'AWS_BUCKET="sl-doc-archive-testing" AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' } } diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 54e86bd1eb..4d7273edf7 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -19,6 +19,7 @@ services: MONGO_HOST: mongo POSTGRES_HOST: postgres AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} depends_on: From ff9e67c87d7f3c0b519d7b339d9ba54cf4b17a97 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Tue, 29 May 2018 13:59:19 +0100 Subject: [PATCH 160/349] Update to Build Script 1.1.4 (draft) --- services/docstore/Jenkinsfile | 3 +-- services/docstore/Makefile | 4 ++-- services/docstore/docker-compose.ci.yml | 2 +- services/docstore/docker-compose.yml | 4 ++-- services/docstore/package.json | 2 +- 5 files changed, 7 insertions(+), 8 deletions(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 0b72053319..e8eefc2e9d 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -2,7 +2,7 @@ String cron_string = BRANCH_NAME == "master" ? "@daily" : "" pipeline { agent any - + triggers { pollSCM('* * * * *') cron(cron_string) @@ -29,7 +29,6 @@ pipeline { } } - stage('Package and publish build') { steps { sh 'make publish' diff --git a/services/docstore/Makefile b/services/docstore/Makefile index bc197fbdee..2c1273ffc4 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.3 +# Version: 1.1.4 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) @@ -14,7 +14,7 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ AWS_BUCKET=${AWS_BUCKET} \ AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ - docker-compose ${DOCKER_COMPOSE_FLAGS} + docker-compose ${DOCKER_COMPOSE_FLAGS} clean: diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 4d7273edf7..b82ec852ac 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.3 +# Version: 1.1.4 version: "2" diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 31fe46d3ed..fd540dae99 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.3 +# Version: 1.1.4 version: "2" @@ -25,8 +25,8 @@ services: REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres - AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} user: node diff --git a/services/docstore/package.json b/services/docstore/package.json index 3249de833a..88e56d9d37 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -12,7 +12,7 @@ "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js", "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", - "test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js", + "test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js", "test:unit": "npm run compile:app && npm run compile:unit_tests && npm run test:unit:_run -- --grep=$MOCHA_GREP", "compile:unit_tests": "[ ! -e test/unit/coffee ] && echo 'No unit tests to compile' || coffee -o test/unit/js -c test/unit/coffee", "compile:acceptance_tests": "[ ! -e test/acceptance/coffee ] && echo 'No acceptance tests to compile' || coffee -o test/acceptance/js -c test/acceptance/coffee", From e396b6b79e58e704931c0962673ee601d249b06a Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Tue, 29 May 2018 15:30:45 +0100 Subject: [PATCH 161/349] Update to Build Script 1.1.4 (draft 2) --- services/docstore/Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index e8eefc2e9d..a779f94b6f 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -24,7 +24,7 @@ pipeline { stage('Acceptance Tests') { steps { withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { - sh 'AWS_BUCKET="sl-doc-archive-testing" AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' + sh 'AWS_BUCKET="sl-acceptance-tests" AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' } } } From 3d1e6fb28af013b96d769da6c9c37d2fa21c5e89 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Mon, 6 Aug 2018 12:00:40 +0100 Subject: [PATCH 162/349] increase body parser limit to 64kb the 16kb limit is not enough when the doc has too many escape characters --- services/docstore/app.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index f81b4f3ea8..aa6e9bff15 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -31,8 +31,8 @@ app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/ranges', HttpController.getAllRanges app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc -# Add 16kb overhead for the JSON encoding -app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: Settings.max_doc_length + 16 * 1024), HttpController.updateDoc +# Add 64kb overhead for the JSON encoding +app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: Settings.max_doc_length + 64 * 1024), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.post '/project/:project_id/archive', HttpController.archiveAllDocs From 73171b80cfaf19ed1c73c6568427c29a0c65038e Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 28 Sep 2018 11:50:19 +0100 Subject: [PATCH 163/349] change mongo connection string temporaraly --- services/docstore/config/settings.defaults.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 70aa470850..5b40e0079e 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -8,7 +8,7 @@ module.exports = Settings = host: process.env['LISTEN_ADDRESS'] or "localhost" mongo: - url: "mongodb://#{process.env['MONGO_HOST'] or '127.0.0.1'}/sharelatex" + url: "#{process.env['MONGO_CONNECTION_STRING'] or 'mongodb://127.0.0.1/sharelatex'}" docstore: healthCheck: From 94603f98552631566a9a5ab7527b64771d8983bd Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 28 Sep 2018 12:02:20 +0100 Subject: [PATCH 164/349] use overleaf-ops project --- services/docstore/Makefile | 4 ++-- services/docstore/docker-compose.ci.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 2c1273ffc4..e1f75d1c7a 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -37,9 +37,9 @@ test_clean: test_acceptance_pre_run: @[ ! -f test/acceptance/scripts/pre-run ] && echo "docstore has no pre acceptance tests task" || $(DOCKER_COMPOSE) run --rm test_acceptance test/acceptance/scripts/pre-run build: - docker build --pull --tag gcr.io/csh-gcdm-test/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) . + docker build --pull --tag gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) . publish: - docker push gcr.io/csh-gcdm-test/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + docker push gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) .PHONY: clean test test_unit test_acceptance test_clean build publish diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index b82ec852ac..05333ed694 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -7,13 +7,13 @@ version: "2" services: test_unit: - image: gcr.io/csh-gcdm-test/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + image: gcr.io/overleaf-ops/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER user: node command: npm run test:unit:_run test_acceptance: build: . - image: gcr.io/csh-gcdm-test/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + image: gcr.io/overleaf-ops/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER environment: REDIS_HOST: redis MONGO_HOST: mongo From afc0058b87d1f9784850201b2218175b5b6692f6 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 28 Sep 2018 12:13:53 +0100 Subject: [PATCH 165/349] update buildscripts to 1.1.9 --- services/docstore/.github/ISSUE_TEMPLATE.md | 38 ++++++++++++++ .../docstore/.github/PULL_REQUEST_TEMPLATE.md | 45 ++++++++++++++++ services/docstore/Jenkinsfile | 51 ++++++++++++++++++- services/docstore/Makefile | 11 ++-- services/docstore/buildscript.txt | 9 ++++ services/docstore/docker-compose.ci.yml | 8 +-- services/docstore/docker-compose.yml | 4 +- services/docstore/package.json | 7 +-- 8 files changed, 161 insertions(+), 12 deletions(-) create mode 100644 services/docstore/.github/ISSUE_TEMPLATE.md create mode 100644 services/docstore/.github/PULL_REQUEST_TEMPLATE.md create mode 100644 services/docstore/buildscript.txt diff --git a/services/docstore/.github/ISSUE_TEMPLATE.md b/services/docstore/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..e0093aa90c --- /dev/null +++ b/services/docstore/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,38 @@ +<!-- BUG REPORT TEMPLATE --> + +## Steps to Reproduce +<!-- Describe the steps leading up to when / where you found the bug. --> +<!-- Screenshots may be helpful here. --> + +1. +2. +3. + +## Expected Behaviour +<!-- What should have happened when you completed the steps above? --> + +## Observed Behaviour +<!-- What actually happened when you completed the steps above? --> +<!-- Screenshots may be helpful here. --> + +## Context +<!-- How has this issue affected you? What were you trying to accomplish? --> + +## Technical Info +<!-- Provide any technical details that may be applicable (or N/A if not applicable). --> + +* URL: +* Browser Name and version: +* Operating System and version (desktop or mobile): +* Signed in as: +* Project and/or file: + +## Analysis +<!--- Optionally, document investigation of / suggest a fix for the bug, e.g. 'comes from this line / commit' --> + +## Who Needs to Know? +<!-- If you want to bring this to the attention of particular people, @-mention them below. --> +<!-- If a user reported this bug and should be notified when it is fixed, provide the Front conversation link. --> + +- +- diff --git a/services/docstore/.github/PULL_REQUEST_TEMPLATE.md b/services/docstore/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..ed25ee83c1 --- /dev/null +++ b/services/docstore/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,45 @@ +<!-- Please review https://github.com/overleaf/write_latex/blob/master/.github/CONTRIBUTING.md for guidance on what is expected in each section. --> + +### Description + + + +#### Screenshots + + + +#### Related Issues / PRs + + + +### Review + + + +#### Potential Impact + + + +#### Manual Testing Performed + +- [ ] +- [ ] + +#### Accessibility + + + +### Deployment + + + +#### Deployment Checklist + +- [ ] Update documentation not included in the PR (if any) +- [ ] + +#### Metrics and Monitoring + + + +#### Who Needs to Know? diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index a779f94b6f..99e2bd2691 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -3,12 +3,33 @@ String cron_string = BRANCH_NAME == "master" ? "@daily" : "" pipeline { agent any + environment { + GIT_PROJECT = "docstore-sharelatex" + JENKINS_WORKFLOW = "docstore-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/sharelatex/${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' @@ -31,7 +52,13 @@ pipeline { stage('Package and publish build') { steps { - sh 'make publish' + + 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' + } } @@ -49,6 +76,19 @@ pipeline { 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 { @@ -56,6 +96,15 @@ pipeline { 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" + } } } diff --git a/services/docstore/Makefile b/services/docstore/Makefile index e1f75d1c7a..73123ddd4f 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.4 +# Version: 1.1.9 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) @@ -18,6 +18,8 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ clean: + docker rmi ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + docker rmi gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) rm -f app.js rm -rf app/js rm -rf test/unit/js @@ -37,9 +39,12 @@ test_clean: test_acceptance_pre_run: @[ ! -f test/acceptance/scripts/pre-run ] && echo "docstore has no pre acceptance tests task" || $(DOCKER_COMPOSE) run --rm test_acceptance test/acceptance/scripts/pre-run build: - docker build --pull --tag gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) . + docker build --pull --tag ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ + --tag gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ + . publish: - docker push gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + + docker push $(DOCKER_REPO)/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) .PHONY: clean test test_unit test_acceptance test_clean build publish diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt new file mode 100644 index 0000000000..4c2ef137f1 --- /dev/null +++ b/services/docstore/buildscript.txt @@ -0,0 +1,9 @@ +--script-version=1.1.9 +docstore +--node-version=6.14.1 +--acceptance-creds=aws +--language=coffeescript +--dependencies=mongo,redis +--docker-repos=gcr.io/overleaf-ops +--kube=false +--build-target=docker diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 05333ed694..d93d6270cd 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,20 +1,21 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.4 +# Version: 1.1.9 version: "2" services: test_unit: - image: gcr.io/overleaf-ops/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER user: node command: npm run test:unit:_run test_acceptance: build: . - image: gcr.io/overleaf-ops/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER environment: + ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres @@ -33,4 +34,3 @@ services: mongo: image: mongo:3.4 - diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index fd540dae99..494b565cc7 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.4 +# Version: 1.1.9 version: "2" @@ -22,6 +22,7 @@ services: - .:/app working_dir: /app environment: + ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres @@ -34,6 +35,7 @@ services: - mongo - redis command: npm run test:acceptance + redis: image: redis diff --git a/services/docstore/package.json b/services/docstore/package.json index 88e56d9d37..8250d09606 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -10,14 +10,15 @@ "scripts": { "compile:app": "([ -e app/coffee ] && coffee $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", - "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js", + "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 30000 --exit $@ test/acceptance/js", "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", "test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js", "test:unit": "npm run compile:app && npm run compile:unit_tests && npm run test:unit:_run -- --grep=$MOCHA_GREP", "compile:unit_tests": "[ ! -e test/unit/coffee ] && echo 'No unit tests to compile' || coffee -o test/unit/js -c test/unit/coffee", "compile:acceptance_tests": "[ ! -e test/acceptance/coffee ] && echo 'No acceptance tests to compile' || coffee -o test/acceptance/js -c test/acceptance/coffee", - "compile:all": "npm run compile:app && npm run compile:unit_tests && npm run compile:acceptance_tests", - "nodemon": "nodemon --config nodemon.json" + "compile:all": "npm run compile:app && npm run compile:unit_tests && npm run compile:acceptance_tests && npm run compile:smoke_tests", + "nodemon": "nodemon --config nodemon.json", + "compile:smoke_tests": "[ ! -e test/smoke/coffee ] && echo 'No smoke tests to compile' || coffee -o test/smoke/js -c test/smoke/coffee" }, "dependencies": { "async": "~0.8.0", From 7a90d49f42e1abc6492dcb4e1b2eb6d1859be54c Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 28 Sep 2018 12:39:11 +0100 Subject: [PATCH 166/349] add HEALTH_CHECK_PROJECT_ID --- services/docstore/config/settings.defaults.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index dd45f90aff..8d8b8c74a2 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -11,7 +11,7 @@ Settings = docstore: healthCheck: - project_id: "" + project_id: process.env['HEALTH_CHECK_PROJECT_ID'] max_doc_length: 2 * 1024 * 1024 # 2mb From 68a950a20c78052b7be06909152728f0db71ae86 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 28 Sep 2018 13:20:03 +0100 Subject: [PATCH 167/349] add debug line --- services/docstore/config/settings.defaults.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 8d8b8c74a2..4a5e29fd2f 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -27,5 +27,7 @@ if process.env['AWS_ACCESS_KEY_ID']? and process.env['AWS_SECRET_ACCESS_KEY']? a key: process.env['AWS_ACCESS_KEY_ID'] secret: process.env['AWS_SECRET_ACCESS_KEY'] bucket: process.env['AWS_BUCKET'] + +console.log Settings, process.env['HEALTH_CHECK_PROJECT_ID'] module.exports = Settings \ No newline at end of file From 14073a6544108b8e5e12201dc59f10288d9c3e28 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 28 Sep 2018 13:31:49 +0100 Subject: [PATCH 168/349] remove debug line --- services/docstore/config/settings.defaults.coffee | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 4a5e29fd2f..8d8b8c74a2 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -27,7 +27,5 @@ if process.env['AWS_ACCESS_KEY_ID']? and process.env['AWS_SECRET_ACCESS_KEY']? a key: process.env['AWS_ACCESS_KEY_ID'] secret: process.env['AWS_SECRET_ACCESS_KEY'] bucket: process.env['AWS_BUCKET'] - -console.log Settings, process.env['HEALTH_CHECK_PROJECT_ID'] module.exports = Settings \ No newline at end of file From a756b1a9673ccbd29395b15536075c0615dbc845 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 3 Oct 2018 14:57:01 +0100 Subject: [PATCH 169/349] hard delete a doc on health check --- services/docstore/app/coffee/HealthChecker.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index cb5d053aa1..71e7005f7b 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -1,4 +1,4 @@ -ObjectId = require("mongojs").ObjectId +{db, ObjectId} = require "./mongojs" request = require("request") async = require("async") _ = require("underscore") @@ -40,4 +40,4 @@ module.exports = async.series jobs, (err)-> if err? callback(err) - request.del getOpts(), callback + db.docs.remove {_id: doc_id, project_id: project_id}, callback From 2828df74e5d4ba6373f94a80fbac06cef58619ed Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 3 Oct 2018 14:57:01 +0100 Subject: [PATCH 170/349] hard delete a doc on health check --- services/docstore/app/coffee/HealthChecker.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index cb5d053aa1..71e7005f7b 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -1,4 +1,4 @@ -ObjectId = require("mongojs").ObjectId +{db, ObjectId} = require "./mongojs" request = require("request") async = require("async") _ = require("underscore") @@ -40,4 +40,4 @@ module.exports = async.series jobs, (err)-> if err? callback(err) - request.del getOpts(), callback + db.docs.remove {_id: doc_id, project_id: project_id}, callback From 2ccc4d8d3fa476879e8d39a6166b32077acd60f0 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 19 Oct 2018 11:37:44 +0100 Subject: [PATCH 171/349] also delete doc ops --- services/docstore/app/coffee/HealthChecker.coffee | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index 71e7005f7b..4280f8aa58 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -36,8 +36,9 @@ module.exports = cb() else cb("health check lines not equal #{body.lines} != #{lines}") + (cb)-> + db.docs.remove {_id: doc_id, project_id: project_id}, cb + (cb)-> + db.docOps.remove {doc_id: doc_id}, cb ] - async.series jobs, (err)-> - if err? - callback(err) - db.docs.remove {_id: doc_id, project_id: project_id}, callback + async.series jobs, callback From 7e3c6ddb3f603fa4b999a3816dfc2f77d3c8f1fa Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 19 Oct 2018 11:37:44 +0100 Subject: [PATCH 172/349] also delete doc ops --- services/docstore/app/coffee/HealthChecker.coffee | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.coffee index 71e7005f7b..4280f8aa58 100644 --- a/services/docstore/app/coffee/HealthChecker.coffee +++ b/services/docstore/app/coffee/HealthChecker.coffee @@ -36,8 +36,9 @@ module.exports = cb() else cb("health check lines not equal #{body.lines} != #{lines}") + (cb)-> + db.docs.remove {_id: doc_id, project_id: project_id}, cb + (cb)-> + db.docOps.remove {doc_id: doc_id}, cb ] - async.series jobs, (err)-> - if err? - callback(err) - db.docs.remove {_id: doc_id, project_id: project_id}, callback + async.series jobs, callback From f321341227d5a2847ed91e9d50998af88c505604 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 20 Nov 2018 14:58:19 +0000 Subject: [PATCH 173/349] bump metrics to work with promethious --- services/docstore/app.coffee | 2 ++ services/docstore/package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index eb74016ff3..bd12e11282 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -27,6 +27,8 @@ app.param 'doc_id', (req, res, next, doc_id) -> else next new Error("invalid doc id") +Metrics.injectMetricsRoute(app) + app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/ranges', HttpController.getAllRanges app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc diff --git a/services/docstore/package.json b/services/docstore/package.json index 8250d09606..2d114f2b21 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.7.1", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.9.0", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From ff29557fb441b59e8c419eef77a4b86627cf9ac6 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 20 Nov 2018 16:06:36 +0000 Subject: [PATCH 174/349] bump metrics version --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 2d114f2b21..f259a7b212 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v1.9.0", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#b07cd31f54a64cb8bb4e305b8803f6a582d9d8a9", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 56047f884cf1a0793d425441be8ff2f7c4416506 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 20 Nov 2018 16:14:14 +0000 Subject: [PATCH 175/349] bump metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index f259a7b212..e98d100b01 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#b07cd31f54a64cb8bb4e305b8803f6a582d9d8a9", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#36cee20dc8a74b62545302909849fd3a43eec6ab", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 459d07dd69866d68f0ec484be7d33b0ce1029bc4 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 20 Nov 2018 16:29:02 +0000 Subject: [PATCH 176/349] bump metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index e98d100b01..7db2e4ed69 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#36cee20dc8a74b62545302909849fd3a43eec6ab", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#117a27764ee167cd646d4a30d152a69572f20e88", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 4ea9328099b1ed5b1bd94abd834fad2b56286337 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 20 Nov 2018 17:17:29 +0000 Subject: [PATCH 177/349] bump metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 7db2e4ed69..03aa645604 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#117a27764ee167cd646d4a30d152a69572f20e88", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#e9d0f200ee3ab80c05b9244756eda2a5b50dd529", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 53654b3eaff4711dea4d261ecbe413ae4dd1be27 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 20 Nov 2018 17:21:10 +0000 Subject: [PATCH 178/349] bump metrics --- services/docstore/app.coffee | 2 +- services/docstore/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index bd12e11282..9fe4df66ce 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -1,10 +1,10 @@ +Metrics = require "metrics-sharelatex" Settings = require "settings-sharelatex" logger = require "logger-sharelatex" express = require "express" bodyParser = require "body-parser" Errors = require "./app/js/Errors" HttpController = require "./app/js/HttpController" -Metrics = require "metrics-sharelatex" Path = require "path" Metrics.initialize("docstore") diff --git a/services/docstore/package.json b/services/docstore/package.json index 03aa645604..483b73d5da 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#e9d0f200ee3ab80c05b9244756eda2a5b50dd529", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#98ca80bb991c411b5c38ecc48f8027e1e18529ba", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 04cfb8fa0eab93b52817dcd58f1c9d7869c979c2 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Fri, 23 Nov 2018 16:24:46 +0000 Subject: [PATCH 179/349] use labels metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 483b73d5da..d27790793a 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#98ca80bb991c411b5c38ecc48f8027e1e18529ba", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#9346fe518015c24dcb2847239c62d8d5dd7e2d73", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 30368dd8b9b5df68ce52cc0bdf4b56836ac57d0a Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Mon, 26 Nov 2018 11:08:59 +0000 Subject: [PATCH 180/349] try new mongo metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index d27790793a..48141ea995 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#9346fe518015c24dcb2847239c62d8d5dd7e2d73", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#5d4915723783862cd66b50a4a16667a08283bdd8", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From b8f3fbd1cf5eee61b47a4417a40de4de087cd64c Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Mon, 10 Dec 2018 21:42:14 +0000 Subject: [PATCH 181/349] bump build script --- services/docstore/Dockerfile | 2 +- services/docstore/Makefile | 2 +- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose.ci.yml | 2 +- services/docstore/docker-compose.yml | 2 +- services/docstore/package.json | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 9ead057334..5103947c33 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -19,4 +19,4 @@ COPY --from=app /app /app WORKDIR /app USER node -CMD ["node","app.js"] +CMD ["node", "--expose-gc", "app.js"] diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 73123ddd4f..02623af09b 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.9 +# Version: 1.1.10 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 4c2ef137f1..221569f544 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,4 +1,4 @@ ---script-version=1.1.9 +--script-version=1.1.10 docstore --node-version=6.14.1 --acceptance-creds=aws diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index d93d6270cd..4e17f15673 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.9 +# Version: 1.1.10 version: "2" diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 494b565cc7..a556a008fa 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.9 +# Version: 1.1.10 version: "2" diff --git a/services/docstore/package.json b/services/docstore/package.json index 48141ea995..81ed78fd63 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/sharelatex/docstore-sharelatex.git" }, "scripts": { - "compile:app": "([ -e app/coffee ] && coffee $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", + "compile:app": "([ -e app/coffee ] && coffee -m $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee -m $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 30000 --exit $@ test/acceptance/js", "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", From bd7a764b7e4082a2df8a07b585037a160cef071c Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Mon, 10 Dec 2018 22:04:16 +0000 Subject: [PATCH 182/349] bump metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 81ed78fd63..9b975eda48 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#5d4915723783862cd66b50a4a16667a08283bdd8", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.9", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 3a963c1832f3d36d108941a86d6af2c0fafeceb7 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 11 Dec 2018 14:17:38 +0000 Subject: [PATCH 183/349] bump metrics --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 9b975eda48..7f7c088f58 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.7.1", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.9", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.10", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From 36a0216f441d3e7d81876bb73558c60774805324 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 11 Dec 2018 14:26:06 +0000 Subject: [PATCH 184/349] trying source context --- services/docstore/source-context.json | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 services/docstore/source-context.json diff --git a/services/docstore/source-context.json b/services/docstore/source-context.json new file mode 100644 index 0000000000..e4e13877e1 --- /dev/null +++ b/services/docstore/source-context.json @@ -0,0 +1,6 @@ +{ + "git": { + "revisionId": "a579e7bed4bc66abc091c3cb41057cc88e341d85", + "url": "git@github.com:sharelatex/docstore-sharelatex.git" + } +} \ No newline at end of file From b68d7d46a2f5ebc93c7f313534e0b30f997ee245 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 11 Dec 2018 14:34:39 +0000 Subject: [PATCH 185/349] update coffeescript --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 7f7c088f58..3af823e72a 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -23,7 +23,7 @@ "dependencies": { "async": "~0.8.0", "body-parser": "~1.0.2", - "coffee-script": "^1.7.1", + "coffee-script": "^1.12.7", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.10", From 7358f91ea9aeb32a9ce4a7b54c355ecc64ba5e3a Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 11 Dec 2018 14:43:39 +0000 Subject: [PATCH 186/349] inline source maps, remove grunt, clean dev deps --- services/docstore/package.json | 11 +---------- services/docstore/source-context.json | 6 ------ 2 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 services/docstore/source-context.json diff --git a/services/docstore/package.json b/services/docstore/package.json index 3af823e72a..520215e6ab 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/sharelatex/docstore-sharelatex.git" }, "scripts": { - "compile:app": "([ -e app/coffee ] && coffee -m $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee -m $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", + "compile:app": "([ -e app/coffee ] && coffee -M $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee -M $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 30000 --exit $@ test/acceptance/js", "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", @@ -34,16 +34,7 @@ "devDependencies": { "bunyan": "~0.22.3", "chai": "~1.9.1", - "grunt": "~0.4.4", - "grunt-bunyan": "~0.5.0", - "grunt-cli": "^1.2.0", - "grunt-contrib-clean": "~0.5.0", - "grunt-contrib-coffee": "~0.10.1", - "grunt-execute": "~0.2.1", - "grunt-forever": "~0.4.4", - "grunt-mocha-test": "~0.10.2", "mocha": "^4.0.1", - "grunt-shell": "~0.7.0", "request": "~2.34.0", "sandboxed-module": "~0.3.0", "sinon": "~3.2.1" diff --git a/services/docstore/source-context.json b/services/docstore/source-context.json deleted file mode 100644 index e4e13877e1..0000000000 --- a/services/docstore/source-context.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "git": { - "revisionId": "a579e7bed4bc66abc091c3cb41057cc88e341d85", - "url": "git@github.com:sharelatex/docstore-sharelatex.git" - } -} \ No newline at end of file From 06babdf789d7d28268a16277360617b106847240 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Tue, 11 Dec 2018 14:49:29 +0000 Subject: [PATCH 187/349] remove inline maps --- services/docstore/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 520215e6ab..849157fb33 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -8,7 +8,7 @@ "url": "https://github.com/sharelatex/docstore-sharelatex.git" }, "scripts": { - "compile:app": "([ -e app/coffee ] && coffee -M $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee -M $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", + "compile:app": "([ -e app/coffee ] && coffee -m $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee -m $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 30000 --exit $@ test/acceptance/js", "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", From d1854c1897c8c0734cd4d1ccdca29f62e61f3539 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Wed, 9 Jan 2019 08:49:32 +0000 Subject: [PATCH 188/349] Adapt for metrics v2 --- services/docstore/app.coffee | 7 +++++-- services/docstore/package.json | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 51f928f1cf..67fc7a14c9 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -1,4 +1,5 @@ Metrics = require "metrics-sharelatex" +Metrics.initialize("docstore") Settings = require "settings-sharelatex" logger = require "logger-sharelatex" express = require "express" @@ -7,7 +8,7 @@ Errors = require "./app/js/Errors" HttpController = require "./app/js/HttpController" Path = require "path" -Metrics.initialize("docstore") + logger.initialize("docstore") Metrics.event_loop?.monitor(logger) @@ -15,6 +16,8 @@ app = express() app.use Metrics.http.monitor(logger) +Metrics.injectMetricsRoute(app) + app.param 'project_id', (req, res, next, project_id) -> if project_id?.match /^[0-9a-f]{24}$/ next() @@ -60,4 +63,4 @@ if !module.parent # Called directly throw error if error? logger.info "Docstore starting up, listening on #{host}:#{port}" -module.exports = app \ No newline at end of file +module.exports = app diff --git a/services/docstore/package.json b/services/docstore/package.json index 849157fb33..a0f43c6770 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,7 +26,7 @@ "coffee-script": "^1.12.7", "express": "~4.1.1", "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.10", + "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.12", "mongojs": "2.4.0", "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", "underscore": "~1.6.0" From b563b1b003be736278d9dfce498010e991fbd07b Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Wed, 9 Jan 2019 08:50:53 +0000 Subject: [PATCH 189/349] Bump logger to v1.5.9 and settings to v1.1.0 --- services/docstore/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index a0f43c6770..b2dcc483e1 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -25,10 +25,10 @@ "body-parser": "~1.0.2", "coffee-script": "^1.12.7", "express": "~4.1.1", - "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.4.0", + "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.5.9", "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.12", "mongojs": "2.4.0", - "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.0.0", + "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.1.0", "underscore": "~1.6.0" }, "devDependencies": { From 93443c737f7c767f2b619c21263e615d3f24a82e Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Wed, 9 Jan 2019 10:24:25 +0000 Subject: [PATCH 190/349] Add note on running acceptance tests to README --- services/docstore/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/docstore/README.md b/services/docstore/README.md index 9b6ba5dd83..4058e6cb42 100644 --- a/services/docstore/README.md +++ b/services/docstore/README.md @@ -5,6 +5,13 @@ A CRUD API for storing and updating text documents in projects [![Build Status](https://travis-ci.org/sharelatex/docstore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/docstore-sharelatex) +Acceptance tests can be run with the command +``` +docker run --rm -e AWS_BUCKET="<bucket-name>" -e AWS_ACCESS_KEY_ID=<aws-access-key> -e AWS_SECRET_ACCESS_KEY=<aws-secret-access-key> -v $(pwd):/app sharelatex/acceptance-test-runner +``` +where `bucket-name`, `aws-access-key` and `aws-secret-access-key` are the credentials for an AWS S3 bucket. + + License ------- From 6760dd6ce0d50c908030dc09ce555ca1608c5df9 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Wed, 9 Jan 2019 10:29:24 +0000 Subject: [PATCH 191/349] Shrinkwrap --- services/docstore/npm-shrinkwrap.json | 1825 +++++++++++++++++++++++++ 1 file changed, 1825 insertions(+) create mode 100644 services/docstore/npm-shrinkwrap.json diff --git a/services/docstore/npm-shrinkwrap.json b/services/docstore/npm-shrinkwrap.json new file mode 100644 index 0000000000..384643d621 --- /dev/null +++ b/services/docstore/npm-shrinkwrap.json @@ -0,0 +1,1825 @@ +{ + "name": "docstore-sharelatex", + "version": "0.1.2", + "dependencies": { + "@google-cloud/common": { + "version": "0.27.0", + "from": "@google-cloud/common@>=0.27.0 <0.28.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.27.0.tgz" + }, + "@google-cloud/debug-agent": { + "version": "3.0.1", + "from": "@google-cloud/debug-agent@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-3.0.1.tgz", + "dependencies": { + "coffeescript": { + "version": "2.3.2", + "from": "coffeescript@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.3.2.tgz" + } + } + }, + "@google-cloud/profiler": { + "version": "0.2.3", + "from": "@google-cloud/profiler@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-0.2.3.tgz", + "dependencies": { + "@google-cloud/common": { + "version": "0.26.2", + "from": "@google-cloud/common@>=0.26.0 <0.27.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.26.2.tgz" + }, + "through2": { + "version": "3.0.0", + "from": "through2@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.0.tgz" + } + } + }, + "@google-cloud/projectify": { + "version": "0.3.2", + "from": "@google-cloud/projectify@>=0.3.2 <0.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.2.tgz" + }, + "@google-cloud/promisify": { + "version": "0.3.1", + "from": "@google-cloud/promisify@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz" + }, + "@google-cloud/trace-agent": { + "version": "3.5.0", + "from": "@google-cloud/trace-agent@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.5.0.tgz", + "dependencies": { + "@google-cloud/common": { + "version": "0.28.0", + "from": "@google-cloud/common@>=0.28.0 <0.29.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.28.0.tgz" + }, + "methods": { + "version": "1.1.2", + "from": "methods@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + }, + "uuid": { + "version": "3.3.2", + "from": "uuid@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" + } + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "from": "@protobufjs/aspromise@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "from": "@protobufjs/base64@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "from": "@protobufjs/codegen@>=2.0.4 <3.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "from": "@protobufjs/eventemitter@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "from": "@protobufjs/fetch@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz" + }, + "@protobufjs/float": { + "version": "1.0.2", + "from": "@protobufjs/float@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "from": "@protobufjs/inquire@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz" + }, + "@protobufjs/path": { + "version": "1.1.2", + "from": "@protobufjs/path@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "from": "@protobufjs/pool@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "from": "@protobufjs/utf8@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz" + }, + "@sindresorhus/is": { + "version": "0.13.0", + "from": "@sindresorhus/is@>=0.13.0 <0.14.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.13.0.tgz" + }, + "@sinonjs/commons": { + "version": "1.3.0", + "from": "@sinonjs/commons@^1.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", + "dependencies": { + "type-detect": { + "version": "4.0.8", + "from": "type-detect@4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + } + } + }, + "@sinonjs/formatio": { + "version": "3.1.0", + "from": "@sinonjs/formatio@^3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz" + }, + "@sinonjs/samsam": { + "version": "3.0.2", + "from": "@sinonjs/samsam@^2 || ^3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.0.2.tgz" + }, + "@types/caseless": { + "version": "0.12.1", + "from": "@types/caseless@*", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz" + }, + "@types/console-log-level": { + "version": "1.4.0", + "from": "@types/console-log-level@>=1.4.0 <2.0.0", + "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz" + }, + "@types/duplexify": { + "version": "3.6.0", + "from": "@types/duplexify@>=3.5.0 <4.0.0", + "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz" + }, + "@types/form-data": { + "version": "2.2.1", + "from": "@types/form-data@*", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz" + }, + "@types/long": { + "version": "4.0.0", + "from": "@types/long@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz" + }, + "@types/node": { + "version": "10.12.18", + "from": "@types/node@*", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz" + }, + "@types/request": { + "version": "2.48.1", + "from": "@types/request@>=2.47.0 <3.0.0", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz" + }, + "@types/semver": { + "version": "5.5.0", + "from": "@types/semver@>=5.5.0 <6.0.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz" + }, + "@types/tough-cookie": { + "version": "2.3.4", + "from": "@types/tough-cookie@*", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.4.tgz" + }, + "abbrev": { + "version": "1.1.1", + "from": "abbrev@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + }, + "accepts": { + "version": "1.0.1", + "from": "accepts@1.0.1", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz" + }, + "acorn": { + "version": "5.7.3", + "from": "acorn@>=5.0.3 <6.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz" + }, + "agent-base": { + "version": "4.2.1", + "from": "agent-base@>=4.1.0 <5.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz" + }, + "ansi-regex": { + "version": "0.2.1", + "from": "ansi-regex@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz" + }, + "ansi-styles": { + "version": "1.1.0", + "from": "ansi-styles@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz" + }, + "argparse": { + "version": "0.1.16", + "from": "argparse@>=0.1.11 <0.2.0", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", + "dependencies": { + "underscore": { + "version": "1.7.0", + "from": "underscore@>=1.7.0 <1.8.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz" + }, + "underscore.string": { + "version": "2.4.0", + "from": "underscore.string@>=2.4.0 <2.5.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz" + } + } + }, + "array-from": { + "version": "2.1.1", + "from": "array-from@^2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz" + }, + "arrify": { + "version": "1.0.1", + "from": "arrify@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + }, + "asn1": { + "version": "0.1.11", + "from": "asn1@0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.1.5", + "from": "assert-plus@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "dev": true, + "optional": true + }, + "assertion-error": { + "version": "1.0.0", + "from": "assertion-error@1.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", + "dev": true + }, + "async": { + "version": "0.8.0", + "from": "async@>=0.8.0 <0.9.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz" + }, + "async-listener": { + "version": "0.6.10", + "from": "async-listener@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz" + }, + "aws-sign2": { + "version": "0.5.0", + "from": "aws-sign2@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", + "dev": true, + "optional": true + }, + "axios": { + "version": "0.18.0", + "from": "axios@>=0.18.0 <0.19.0", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz" + }, + "balanced-match": { + "version": "1.0.0", + "from": "balanced-match@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" + }, + "bignumber.js": { + "version": "7.2.1", + "from": "bignumber.js@>=7.0.0 <8.0.0", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz" + }, + "bindings": { + "version": "1.3.1", + "from": "bindings@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz" + }, + "bintrees": { + "version": "1.0.1", + "from": "bintrees@1.0.1", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz" + }, + "body-parser": { + "version": "1.0.2", + "from": "body-parser@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz" + }, + "boom": { + "version": "0.4.2", + "from": "boom@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "from": "brace-expansion@>=1.1.7 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + }, + "browser-stdout": { + "version": "1.3.0", + "from": "browser-stdout@1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "dev": true + }, + "bson": { + "version": "1.0.9", + "from": "bson@>=1.0.4 <1.1.0", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz" + }, + "buffer-crc32": { + "version": "0.2.1", + "from": "buffer-crc32@0.2.1", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz" + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "from": "buffer-equal-constant-time@1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" + }, + "buffer-shims": { + "version": "1.0.0", + "from": "buffer-shims@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" + }, + "builtin-modules": { + "version": "3.0.0", + "from": "builtin-modules@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz" + }, + "bunyan": { + "version": "0.22.3", + "from": "bunyan@>=0.22.3 <0.23.0", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", + "dev": true + }, + "bytes": { + "version": "1.0.0", + "from": "bytes@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz" + }, + "chai": { + "version": "1.9.2", + "from": "chai@>=1.9.1 <1.10.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", + "dev": true + }, + "chalk": { + "version": "0.5.1", + "from": "chalk@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz" + }, + "check-error": { + "version": "1.0.2", + "from": "check-error@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" + }, + "coffee-script": { + "version": "1.12.7", + "from": "coffee-script@>=1.12.7 <2.0.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz" + }, + "colors": { + "version": "0.6.2", + "from": "colors@>=0.6.2 <0.7.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz" + }, + "combined-stream": { + "version": "0.0.7", + "from": "combined-stream@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "dev": true, + "optional": true + }, + "commander": { + "version": "2.11.0", + "from": "commander@2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + }, + "console-log-level": { + "version": "1.4.0", + "from": "console-log-level@>=1.4.0 <2.0.0", + "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.0.tgz" + }, + "continuation-local-storage": { + "version": "3.2.1", + "from": "continuation-local-storage@>=3.2.1 <4.0.0", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz" + }, + "cookie": { + "version": "0.1.2", + "from": "cookie@0.1.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz" + }, + "cookie-signature": { + "version": "1.0.3", + "from": "cookie-signature@1.0.3", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz" + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "cryptiles": { + "version": "0.2.2", + "from": "cryptiles@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", + "dev": true, + "optional": true + }, + "ctype": { + "version": "0.5.3", + "from": "ctype@0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "dev": true, + "optional": true + }, + "dateformat": { + "version": "1.0.2-1.2.3", + "from": "dateformat@1.0.2-1.2.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz" + }, + "debug": { + "version": "0.8.1", + "from": "debug@>=0.7.3 <1.0.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz" + }, + "deep-eql": { + "version": "0.1.3", + "from": "deep-eql@0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "dev": true + }, + "delay": { + "version": "4.1.0", + "from": "delay@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-4.1.0.tgz" + }, + "delayed-stream": { + "version": "0.0.5", + "from": "delayed-stream@0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "dev": true, + "optional": true + }, + "diff": { + "version": "3.3.1", + "from": "diff@3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "dev": true + }, + "dtrace-provider": { + "version": "0.2.8", + "from": "dtrace-provider@0.2.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", + "dev": true, + "optional": true + }, + "duplexify": { + "version": "3.6.1", + "from": "duplexify@>=3.6.0 <4.0.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz" + }, + "each-series": { + "version": "1.0.0", + "from": "each-series@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz" + }, + "ecdsa-sig-formatter": { + "version": "1.0.10", + "from": "ecdsa-sig-formatter@1.0.10", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz" + }, + "emitter-listener": { + "version": "1.1.2", + "from": "emitter-listener@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz" + }, + "end-of-stream": { + "version": "1.4.1", + "from": "end-of-stream@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz" + }, + "ent": { + "version": "2.2.0", + "from": "ent@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz" + }, + "es6-promise": { + "version": "4.2.5", + "from": "es6-promise@>=4.0.3 <5.0.0", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz" + }, + "es6-promisify": { + "version": "5.0.0", + "from": "es6-promisify@>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" + }, + "escape-html": { + "version": "1.0.1", + "from": "escape-html@1.0.1", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz" + }, + "escape-string-regexp": { + "version": "1.0.5", + "from": "escape-string-regexp@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + }, + "esprima": { + "version": "1.0.4", + "from": "esprima@>=1.0.2 <1.1.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" + }, + "eventemitter2": { + "version": "0.4.14", + "from": "eventemitter2@>=0.4.13 <0.5.0", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz" + }, + "exit": { + "version": "0.1.2", + "from": "exit@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + }, + "express": { + "version": "4.1.2", + "from": "express@>=4.1.1 <4.2.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.1.2.tgz" + }, + "extend": { + "version": "3.0.2", + "from": "extend@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" + }, + "findit2": { + "version": "2.2.3", + "from": "findit2@>=2.2.3 <3.0.0", + "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz" + }, + "findup-sync": { + "version": "0.1.3", + "from": "findup-sync@>=0.1.2 <0.2.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", + "dependencies": { + "glob": { + "version": "3.2.11", + "from": "glob@>=3.2.9 <3.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz" + }, + "lodash": { + "version": "2.4.2", + "from": "lodash@>=2.4.1 <2.5.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" + }, + "minimatch": { + "version": "0.3.0", + "from": "minimatch@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" + } + } + }, + "follow-redirects": { + "version": "1.6.1", + "from": "follow-redirects@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", + "dependencies": { + "debug": { + "version": "3.1.0", + "from": "debug@3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz" + } + } + }, + "forever-agent": { + "version": "0.5.2", + "from": "forever-agent@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", + "dev": true + }, + "form-data": { + "version": "0.1.4", + "from": "form-data@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", + "dev": true, + "optional": true, + "dependencies": { + "async": { + "version": "0.9.2", + "from": "async@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "dev": true, + "optional": true + } + } + }, + "formatio": { + "version": "1.2.0", + "from": "formatio@1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "dev": true + }, + "fresh": { + "version": "0.2.2", + "from": "fresh@0.2.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz" + }, + "fs-extra": { + "version": "0.9.1", + "from": "fs-extra@>=0.9.1 <0.10.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.9.1.tgz", + "dependencies": { + "ncp": { + "version": "0.5.1", + "from": "ncp@>=0.5.1 <0.6.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.5.1.tgz" + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "from": "fs.realpath@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "dev": true + }, + "gaxios": { + "version": "1.0.7", + "from": "gaxios@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.0.7.tgz" + }, + "gcp-metadata": { + "version": "0.9.3", + "from": "gcp-metadata@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz" + }, + "get-func-name": { + "version": "2.0.0", + "from": "get-func-name@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" + }, + "getobject": { + "version": "0.1.0", + "from": "getobject@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz" + }, + "glob": { + "version": "6.0.4", + "from": "glob@>=6.0.1 <7.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz" + }, + "google-auth-library": { + "version": "2.0.2", + "from": "google-auth-library@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.2.tgz", + "dependencies": { + "gcp-metadata": { + "version": "0.7.0", + "from": "gcp-metadata@>=0.7.0 <0.8.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz" + }, + "lru-cache": { + "version": "5.1.1", + "from": "lru-cache@>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + } + } + }, + "google-p12-pem": { + "version": "1.0.3", + "from": "google-p12-pem@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.3.tgz" + }, + "graceful-fs": { + "version": "1.2.3", + "from": "graceful-fs@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz" + }, + "growl": { + "version": "1.10.3", + "from": "growl@1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "dev": true + }, + "grunt": { + "version": "0.4.5", + "from": "grunt@>=0.4.5 <0.5.0", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", + "dependencies": { + "async": { + "version": "0.1.22", + "from": "async@>=0.1.22 <0.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz" + }, + "coffee-script": { + "version": "1.3.3", + "from": "coffee-script@>=1.3.3 <1.4.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz" + }, + "glob": { + "version": "3.1.21", + "from": "glob@>=3.1.21 <3.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz" + }, + "inherits": { + "version": "1.0.2", + "from": "inherits@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz" + }, + "minimatch": { + "version": "0.2.14", + "from": "minimatch@>=0.2.12 <0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz" + }, + "rimraf": { + "version": "2.2.8", + "from": "rimraf@>=2.2.8 <2.3.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" + } + } + }, + "grunt-bunyan": { + "version": "0.5.0", + "from": "grunt-bunyan@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/grunt-bunyan/-/grunt-bunyan-0.5.0.tgz", + "dependencies": { + "lodash": { + "version": "2.4.2", + "from": "lodash@>=2.4.1 <2.5.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" + } + } + }, + "grunt-contrib-clean": { + "version": "0.6.0", + "from": "grunt-contrib-clean@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.6.0.tgz", + "dependencies": { + "rimraf": { + "version": "2.2.8", + "from": "rimraf@>=2.2.1 <2.3.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" + } + } + }, + "grunt-contrib-coffee": { + "version": "0.11.1", + "from": "grunt-contrib-coffee@>=0.11.0 <0.12.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.11.1.tgz", + "dependencies": { + "coffee-script": { + "version": "1.7.1", + "from": "coffee-script@>=1.7.0 <1.8.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz" + }, + "lodash": { + "version": "2.4.2", + "from": "lodash@>=2.4.1 <2.5.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" + }, + "mkdirp": { + "version": "0.3.5", + "from": "mkdirp@>=0.3.5 <0.4.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" + } + } + }, + "grunt-execute": { + "version": "0.2.2", + "from": "grunt-execute@>=0.2.2 <0.3.0", + "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.2.2.tgz" + }, + "grunt-legacy-log": { + "version": "0.1.3", + "from": "grunt-legacy-log@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", + "dependencies": { + "lodash": { + "version": "2.4.2", + "from": "lodash@>=2.4.1 <2.5.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" + }, + "underscore.string": { + "version": "2.3.3", + "from": "underscore.string@>=2.3.3 <2.4.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" + } + } + }, + "grunt-legacy-log-utils": { + "version": "0.1.1", + "from": "grunt-legacy-log-utils@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", + "dependencies": { + "lodash": { + "version": "2.4.2", + "from": "lodash@>=2.4.1 <2.5.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" + }, + "underscore.string": { + "version": "2.3.3", + "from": "underscore.string@>=2.3.3 <2.4.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" + } + } + }, + "grunt-legacy-util": { + "version": "0.2.0", + "from": "grunt-legacy-util@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", + "dependencies": { + "async": { + "version": "0.1.22", + "from": "async@>=0.1.22 <0.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz" + } + } + }, + "grunt-mocha-test": { + "version": "0.11.0", + "from": "grunt-mocha-test@>=0.11.0 <0.12.0", + "resolved": "https://registry.npmjs.org/grunt-mocha-test/-/grunt-mocha-test-0.11.0.tgz", + "dependencies": { + "commander": { + "version": "2.0.0", + "from": "commander@2.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz" + }, + "diff": { + "version": "1.0.7", + "from": "diff@1.0.7", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.7.tgz" + }, + "glob": { + "version": "3.2.3", + "from": "glob@3.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz" + }, + "graceful-fs": { + "version": "2.0.3", + "from": "graceful-fs@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" + }, + "growl": { + "version": "1.7.0", + "from": "growl@>=1.7.0 <1.8.0", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz" + }, + "minimatch": { + "version": "0.2.14", + "from": "minimatch@~0.2.11", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz" + }, + "mkdirp": { + "version": "0.3.5", + "from": "mkdirp@0.3.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" + }, + "mocha": { + "version": "1.20.1", + "from": "mocha@>=1.20.0 <1.21.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.20.1.tgz" + } + } + }, + "gtoken": { + "version": "2.3.0", + "from": "gtoken@>=2.3.0 <3.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.0.tgz", + "dependencies": { + "mime": { + "version": "2.4.0", + "from": "mime@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz" + }, + "pify": { + "version": "3.0.0", + "from": "pify@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" + } + } + }, + "has-ansi": { + "version": "0.1.0", + "from": "has-ansi@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz" + }, + "has-flag": { + "version": "2.0.0", + "from": "has-flag@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "dev": true + }, + "hawk": { + "version": "1.0.0", + "from": "hawk@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", + "dev": true, + "optional": true + }, + "he": { + "version": "1.1.1", + "from": "he@1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "dev": true + }, + "hex2dec": { + "version": "1.1.1", + "from": "hex2dec@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.1.tgz" + }, + "hoek": { + "version": "0.9.1", + "from": "hoek@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "dev": true + }, + "hooker": { + "version": "0.2.3", + "from": "hooker@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz" + }, + "http-signature": { + "version": "0.10.1", + "from": "http-signature@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "dev": true, + "optional": true + }, + "https-proxy-agent": { + "version": "2.2.1", + "from": "https-proxy-agent@>=2.2.1 <3.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "dependencies": { + "debug": { + "version": "3.2.6", + "from": "debug@>=3.1.0 <4.0.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz" + }, + "ms": { + "version": "2.1.1", + "from": "ms@>=2.1.1 <3.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz" + } + } + }, + "iconv-lite": { + "version": "0.2.11", + "from": "iconv-lite@>=0.2.11 <0.3.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz" + }, + "inflight": { + "version": "1.0.6", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + }, + "inherits": { + "version": "2.0.3", + "from": "inherits@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" + }, + "ip-regex": { + "version": "3.0.0", + "from": "ip-regex@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-3.0.0.tgz", + "dev": true, + "optional": true + }, + "is": { + "version": "3.3.0", + "from": "is@>=3.2.0 <4.0.0", + "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz" + }, + "is-buffer": { + "version": "1.1.6", + "from": "is-buffer@>=1.1.5 <2.0.0", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "jade": { + "version": "0.26.3", + "from": "jade@0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "dependencies": { + "commander": { + "version": "0.6.1", + "from": "commander@0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz" + }, + "mkdirp": { + "version": "0.3.0", + "from": "mkdirp@0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz" + } + } + }, + "js-yaml": { + "version": "2.0.5", + "from": "js-yaml@>=2.0.5 <2.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz" + }, + "json-bigint": { + "version": "0.3.0", + "from": "json-bigint@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz" + }, + "json-stringify-safe": { + "version": "5.0.1", + "from": "json-stringify-safe@5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" + }, + "jsonfile": { + "version": "1.1.1", + "from": "jsonfile@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.1.1.tgz" + }, + "just-extend": { + "version": "4.0.2", + "from": "just-extend@^4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz" + }, + "jwa": { + "version": "1.1.6", + "from": "jwa@>=1.1.5 <2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz" + }, + "jws": { + "version": "3.1.5", + "from": "jws@>=3.1.5 <4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz" + }, + "lodash": { + "version": "0.9.2", + "from": "lodash@>=0.9.2 <0.10.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz" + }, + "lodash.get": { + "version": "4.4.2", + "from": "lodash.get@^4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" + }, + "lodash.pickby": { + "version": "4.6.0", + "from": "lodash.pickby@>=4.6.0 <5.0.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz" + }, + "logger-sharelatex": { + "version": "1.5.9", + "from": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.5.9", + "resolved": "git+https://github.com/sharelatex/logger-sharelatex.git#e8e1b95052f62e107336053e4a983f81cdbdf589", + "dependencies": { + "assertion-error": { + "version": "1.1.0", + "from": "assertion-error@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" + }, + "bunyan": { + "version": "1.5.1", + "from": "bunyan@1.5.1", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz" + }, + "chai": { + "version": "4.2.0", + "from": "chai@latest", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz" + }, + "coffee-script": { + "version": "1.12.4", + "from": "coffee-script@1.12.4", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.4.tgz" + }, + "deep-eql": { + "version": "3.0.1", + "from": "deep-eql@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" + }, + "diff": { + "version": "3.5.0", + "from": "diff@>=3.5.0 <4.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" + }, + "dtrace-provider": { + "version": "0.6.0", + "from": "dtrace-provider@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", + "optional": true + }, + "has-flag": { + "version": "3.0.0", + "from": "has-flag@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + }, + "lolex": { + "version": "3.0.0", + "from": "lolex@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.0.0.tgz" + }, + "sandboxed-module": { + "version": "2.0.3", + "from": "sandboxed-module@latest", + "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-2.0.3.tgz" + }, + "sinon": { + "version": "7.2.2", + "from": "sinon@latest", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.2.tgz" + }, + "supports-color": { + "version": "5.5.0", + "from": "supports-color@>=5.5.0 <6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + }, + "type-detect": { + "version": "4.0.8", + "from": "type-detect@>=4.0.5 <5.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + } + } + }, + "lolex": { + "version": "2.7.5", + "from": "lolex@>=2.1.2 <3.0.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz" + }, + "long": { + "version": "4.0.0", + "from": "long@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz" + }, + "lru-cache": { + "version": "2.7.3", + "from": "lru-cache@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz" + }, + "lsmod": { + "version": "1.0.0", + "from": "lsmod@1.0.0", + "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz" + }, + "lynx": { + "version": "0.1.1", + "from": "lynx@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz" + }, + "merge-descriptors": { + "version": "0.0.2", + "from": "merge-descriptors@0.0.2", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz" + }, + "mersenne": { + "version": "0.0.4", + "from": "mersenne@>=0.0.3 <0.1.0", + "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz" + }, + "methods": { + "version": "0.1.0", + "from": "methods@0.1.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz" + }, + "metrics-sharelatex": { + "version": "2.0.12", + "from": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.12", + "resolved": "git+https://github.com/sharelatex/metrics-sharelatex.git#3ac1621ef049e2f2d88a83b3a41011333d609662", + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "from": "coffee-script@1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz" + } + } + }, + "mime": { + "version": "1.2.11", + "from": "mime@>=1.2.11 <1.3.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" + }, + "minimatch": { + "version": "3.0.4", + "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" + }, + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + }, + "mkdirp": { + "version": "0.5.1", + "from": "mkdirp@>=0.5.1 <0.6.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" + }, + "mocha": { + "version": "4.1.0", + "from": "mocha@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "dev": true, + "dependencies": { + "debug": { + "version": "3.1.0", + "from": "debug@3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "dev": true + }, + "glob": { + "version": "7.1.2", + "from": "glob@7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "from": "supports-color@4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "dev": true + } + } + }, + "module-details-from-path": { + "version": "1.0.3", + "from": "module-details-from-path@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz" + }, + "mongodb": { + "version": "2.2.36", + "from": "mongodb@>=2.0.45 <3.0.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz", + "dependencies": { + "es6-promise": { + "version": "3.2.1", + "from": "es6-promise@3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" + }, + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" + }, + "readable-stream": { + "version": "2.2.7", + "from": "readable-stream@2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz" + }, + "string_decoder": { + "version": "1.0.3", + "from": "string_decoder@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz" + } + } + }, + "mongodb-core": { + "version": "2.1.20", + "from": "mongodb-core@2.1.20", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz" + }, + "mongojs": { + "version": "2.4.0", + "from": "mongojs@2.4.0", + "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz" + }, + "ms": { + "version": "2.0.0", + "from": "ms@2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + }, + "mv": { + "version": "2.1.1", + "from": "mv@~2", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "optional": true + }, + "nan": { + "version": "2.12.1", + "from": "nan@>=2.0.8 <3.0.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz" + }, + "native-promise-only": { + "version": "0.8.1", + "from": "native-promise-only@>=0.8.1 <0.9.0", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "dev": true + }, + "ncp": { + "version": "2.0.0", + "from": "ncp@~2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "optional": true + }, + "negotiator": { + "version": "0.4.9", + "from": "negotiator@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz" + }, + "nise": { + "version": "1.4.8", + "from": "nise@^1.0.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "dependencies": { + "path-to-regexp": { + "version": "1.7.0", + "from": "path-to-regexp@>=1.7.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz" + } + } + }, + "node-fetch": { + "version": "2.3.0", + "from": "node-fetch@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz" + }, + "node-forge": { + "version": "0.7.6", + "from": "node-forge@>=0.7.5 <0.8.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz" + }, + "nopt": { + "version": "1.0.10", + "from": "nopt@>=1.0.10 <1.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" + }, + "oauth-sign": { + "version": "0.3.0", + "from": "oauth-sign@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + }, + "p-limit": { + "version": "2.1.0", + "from": "p-limit@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz" + }, + "p-try": { + "version": "2.0.0", + "from": "p-try@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz" + }, + "parse-duration": { + "version": "0.1.1", + "from": "parse-duration@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz" + }, + "parse-mongo-url": { + "version": "1.1.1", + "from": "parse-mongo-url@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz" + }, + "parse-ms": { + "version": "2.0.0", + "from": "parse-ms@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.0.0.tgz" + }, + "parseurl": { + "version": "1.0.1", + "from": "parseurl@1.0.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz" + }, + "path-is-absolute": { + "version": "1.0.1", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + }, + "path-parse": { + "version": "1.0.6", + "from": "path-parse@>=1.0.6 <2.0.0", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" + }, + "path-to-regexp": { + "version": "0.1.2", + "from": "path-to-regexp@0.1.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz" + }, + "pathval": { + "version": "1.1.0", + "from": "pathval@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz" + }, + "pify": { + "version": "4.0.1", + "from": "pify@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" + }, + "pretty-ms": { + "version": "4.0.0", + "from": "pretty-ms@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz" + }, + "process-nextick-args": { + "version": "2.0.0", + "from": "process-nextick-args@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz" + }, + "prom-client": { + "version": "11.2.1", + "from": "prom-client@>=11.1.3 <12.0.0", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.2.1.tgz" + }, + "protobufjs": { + "version": "6.8.8", + "from": "protobufjs@>=6.8.6 <6.9.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz" + }, + "psl": { + "version": "1.1.31", + "from": "psl@>=1.1.28 <2.0.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "dev": true, + "optional": true + }, + "punycode": { + "version": "2.1.1", + "from": "punycode@>=2.1.1 <3.0.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "dev": true, + "optional": true + }, + "qs": { + "version": "0.6.6", + "from": "qs@>=0.6.6 <0.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz" + }, + "range-parser": { + "version": "1.0.0", + "from": "range-parser@1.0.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz" + }, + "raven": { + "version": "1.2.1", + "from": "raven@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/raven/-/raven-1.2.1.tgz", + "dependencies": { + "cookie": { + "version": "0.3.1", + "from": "cookie@0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz" + } + } + }, + "raw-body": { + "version": "1.1.7", + "from": "raw-body@>=1.1.2 <1.2.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz" + }, + "readable-stream": { + "version": "2.3.6", + "from": "readable-stream@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "dependencies": { + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + }, + "string_decoder": { + "version": "1.1.1", + "from": "string_decoder@>=1.1.1 <1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + } + } + }, + "request": { + "version": "2.34.0", + "from": "request@>=2.34.0 <2.35.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", + "dev": true, + "dependencies": { + "node-uuid": { + "version": "1.4.8", + "from": "node-uuid@>=1.4.0 <1.5.0", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "dev": true + } + } + }, + "require_optional": { + "version": "1.0.1", + "from": "require_optional@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz" + }, + "require-in-the-middle": { + "version": "3.1.0", + "from": "require-in-the-middle@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-3.1.0.tgz" + }, + "require-like": { + "version": "0.1.2", + "from": "require-like@0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz" + }, + "resolve": { + "version": "1.9.0", + "from": "resolve@>=1.5.0 <2.0.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz" + }, + "resolve-from": { + "version": "2.0.0", + "from": "resolve-from@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" + }, + "retry-axios": { + "version": "0.3.2", + "from": "retry-axios@0.3.2", + "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz" + }, + "retry-request": { + "version": "4.0.0", + "from": "retry-request@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.0.0.tgz" + }, + "rimraf": { + "version": "2.4.5", + "from": "rimraf@>=2.4.0 <2.5.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz" + }, + "safe-buffer": { + "version": "5.1.2", + "from": "safe-buffer@>=5.1.1 <5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + }, + "safe-json-stringify": { + "version": "1.2.0", + "from": "safe-json-stringify@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "optional": true + }, + "samsam": { + "version": "1.3.0", + "from": "samsam@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "dev": true + }, + "sandboxed-module": { + "version": "0.3.0", + "from": "sandboxed-module@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", + "dev": true, + "dependencies": { + "stack-trace": { + "version": "0.0.6", + "from": "stack-trace@0.0.6", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", + "dev": true + } + } + }, + "semver": { + "version": "5.6.0", + "from": "semver@>=5.5.0 <6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz" + }, + "send": { + "version": "0.3.0", + "from": "send@0.3.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", + "dependencies": { + "debug": { + "version": "0.8.0", + "from": "debug@0.8.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz" + } + } + }, + "serve-static": { + "version": "1.1.0", + "from": "serve-static@1.1.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz" + }, + "settings-sharelatex": { + "version": "1.1.0", + "from": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.1.0", + "resolved": "git+https://github.com/sharelatex/settings-sharelatex.git#93f63d029b52fef8825c3a401b2b6a7ba29b4750", + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "from": "coffee-script@1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz" + } + } + }, + "shimmer": { + "version": "1.2.0", + "from": "shimmer@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.0.tgz" + }, + "sigmund": { + "version": "1.0.1", + "from": "sigmund@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + }, + "sinon": { + "version": "3.2.1", + "from": "sinon@>=3.2.1 <3.3.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", + "dev": true, + "dependencies": { + "path-to-regexp": { + "version": "1.7.0", + "from": "path-to-regexp@>=1.7.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "dev": true + }, + "type-detect": { + "version": "4.0.8", + "from": "type-detect@^4.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "dev": true + } + } + }, + "sntp": { + "version": "0.2.4", + "from": "sntp@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", + "dev": true, + "optional": true + }, + "source-map": { + "version": "0.6.1", + "from": "source-map@>=0.6.1 <0.7.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + }, + "split": { + "version": "1.0.1", + "from": "split@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz" + }, + "stack-trace": { + "version": "0.0.9", + "from": "stack-trace@0.0.9", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz" + }, + "statsd-parser": { + "version": "0.0.4", + "from": "statsd-parser@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz" + }, + "stream-shift": { + "version": "1.0.0", + "from": "stream-shift@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "strip-ansi": { + "version": "0.3.0", + "from": "strip-ansi@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz" + }, + "supports-color": { + "version": "0.2.0", + "from": "supports-color@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz" + }, + "symbol-observable": { + "version": "1.2.0", + "from": "symbol-observable@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz" + }, + "tdigest": { + "version": "0.1.1", + "from": "tdigest@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz" + }, + "teeny-request": { + "version": "3.11.3", + "from": "teeny-request@>=3.11.1 <4.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", + "dependencies": { + "uuid": { + "version": "3.3.2", + "from": "uuid@>=3.3.2 <4.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" + } + } + }, + "text-encoding": { + "version": "0.6.4", + "from": "text-encoding@0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz" + }, + "through": { + "version": "2.3.8", + "from": "through@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + }, + "through2": { + "version": "2.0.5", + "from": "through2@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" + }, + "thunky": { + "version": "0.1.0", + "from": "thunky@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz" + }, + "timekeeper": { + "version": "1.0.0", + "from": "timekeeper@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/timekeeper/-/timekeeper-1.0.0.tgz" + }, + "to-mongodb-core": { + "version": "2.0.0", + "from": "to-mongodb-core@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz" + }, + "tough-cookie": { + "version": "3.0.0", + "from": "tough-cookie@>=0.12.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.0.tgz", + "dev": true, + "optional": true + }, + "tunnel-agent": { + "version": "0.3.0", + "from": "tunnel-agent@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", + "dev": true, + "optional": true + }, + "type-detect": { + "version": "0.1.1", + "from": "type-detect@0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "dev": true + }, + "type-is": { + "version": "1.1.0", + "from": "type-is@>=1.1.0 <1.2.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz" + }, + "underscore": { + "version": "1.6.0", + "from": "underscore@>=1.6.0 <1.7.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz" + }, + "underscore.string": { + "version": "2.2.1", + "from": "underscore.string@>=2.2.1 <2.3.0", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz" + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + }, + "utils-merge": { + "version": "1.0.0", + "from": "utils-merge@1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" + }, + "uuid": { + "version": "3.0.0", + "from": "uuid@3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz" + }, + "which": { + "version": "1.0.9", + "from": "which@>=1.0.5 <1.1.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz" + }, + "wrappy": { + "version": "1.0.2", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + }, + "xtend": { + "version": "4.0.1", + "from": "xtend@>=4.0.1 <4.1.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + }, + "yallist": { + "version": "3.0.3", + "from": "yallist@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz" + } + } +} From 27709709f3f8769a6e55a832adc437171e423611 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Wed, 9 Jan 2019 10:31:42 +0000 Subject: [PATCH 192/349] Remove grunt --- services/docstore/Gruntfile.coffee | 102 ----------------------------- 1 file changed, 102 deletions(-) delete mode 100644 services/docstore/Gruntfile.coffee diff --git a/services/docstore/Gruntfile.coffee b/services/docstore/Gruntfile.coffee deleted file mode 100644 index 9e5af27034..0000000000 --- a/services/docstore/Gruntfile.coffee +++ /dev/null @@ -1,102 +0,0 @@ -spawn = require("child_process").spawn - -module.exports = (grunt) -> - grunt.initConfig - forever: - app: - options: - index: "app.js" - - coffee: - app_src: - expand: true, - flatten: true, - cwd: "app" - src: ['coffee/*.coffee'], - dest: 'app/js/', - ext: '.js' - - app: - src: "app.coffee" - dest: "app.js" - - unit_tests: - expand: true - cwd: "test/unit/coffee" - src: ["**/*.coffee"] - dest: "test/unit/js/" - ext: ".js" - - acceptance_tests: - expand: true - cwd: "test/acceptance/coffee" - src: ["**/*.coffee"] - dest: "test/acceptance/js/" - ext: ".js" - - smoke_tests: - expand: true - cwd: "test/smoke/coffee" - src: ["**/*.coffee"] - dest: "test/smoke/js" - ext: ".js" - - clean: - app: ["app/js/"] - unit_tests: ["test/unit/js"] - acceptance_tests: ["test/acceptance/js"] - smoke_tests: ["test/smoke/js"] - - execute: - app: - src: "app.js" - - mochaTest: - unit: - options: - reporter: grunt.option('reporter') or 'spec' - grep: grunt.option("grep") - src: ["test/unit/js/**/*.js"] - acceptance: - options: - reporter: grunt.option('reporter') or 'spec' - timeout: 40000 - grep: grunt.option("grep") - src: ["test/acceptance/js/**/*.js"] - smoke: - options: - reporter: grunt.option('reporter') or 'spec' - timeout: 10000 - src: ["test/smoke/js/**/*.js"] - - shell: - dockerTests: - command: 'docker run -v "$(pwd):/app" -e AWS_ACCESS_KEY_ID="$AWS_ACCESS_KEY_ID" -e AWS_SECRET_ACCESS_KEY="$AWS_SECRET_ACCESS_KEY" -e AWS_BUCKET="$AWS_BUCKET" --rm sl-acceptance-test-runner' - - grunt.loadNpmTasks 'grunt-contrib-coffee' - grunt.loadNpmTasks 'grunt-contrib-clean' - grunt.loadNpmTasks 'grunt-mocha-test' - grunt.loadNpmTasks 'grunt-shell' - grunt.loadNpmTasks 'grunt-execute' - grunt.loadNpmTasks 'grunt-bunyan' - grunt.loadNpmTasks 'grunt-forever' - - grunt.registerTask 'compile:app', ['clean:app', 'coffee:app', 'coffee:app_src'] - grunt.registerTask 'run', ['compile:app', 'bunyan', 'execute'] - - grunt.registerTask 'compile:unit_tests', ['clean:unit_tests', 'coffee:unit_tests'] - grunt.registerTask 'test:unit', ['compile:app', 'compile:unit_tests', 'mochaTest:unit'] - - grunt.registerTask 'compile:acceptance_tests', ['clean:acceptance_tests', 'coffee:acceptance_tests'] - grunt.registerTask 'test:acceptance', ['compile:acceptance_tests', 'mochaTest:acceptance'] - - grunt.registerTask 'compile:smoke_tests', ['clean:smoke_tests', 'coffee:smoke_tests'] - grunt.registerTask 'test:smoke', ['compile:smoke_tests', 'mochaTest:smoke'] - - grunt.registerTask 'install', 'compile:app' - - grunt.registerTask 'test:acceptance:docker', ['compile:acceptance_tests', 'shell:dockerTests'] - - grunt.registerTask 'default', ['run'] - - From 5b705877650f5aa3c7f0d3fd5bc9710c3a19f12e Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Wed, 9 Jan 2019 10:32:59 +0000 Subject: [PATCH 193/349] Add **/*.map to .gitignore --- services/docstore/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/services/docstore/.gitignore b/services/docstore/.gitignore index 99832d28c8..6a355b35a8 100644 --- a/services/docstore/.gitignore +++ b/services/docstore/.gitignore @@ -3,4 +3,5 @@ app/js/ test/unit/js test/acceptance/js app.js +**/*.map forever From cfd6225b1c3a69aeb1493236c1d3a8b5f51338a5 Mon Sep 17 00:00:00 2001 From: Henry Oswald <henry.oswald@sharelatex.com> Date: Wed, 30 Jan 2019 16:03:28 +0000 Subject: [PATCH 194/349] bulk upgrade to 1.1.12, moved to npm rather than git --- services/docstore/Jenkinsfile | 10 +- services/docstore/Makefile | 6 +- services/docstore/buildscript.txt | 5 +- services/docstore/docker-compose.ci.yml | 13 +- services/docstore/docker-compose.yml | 12 +- services/docstore/npm-shrinkwrap.json | 1047 +++++++++-------------- services/docstore/package.json | 6 +- 7 files changed, 465 insertions(+), 634 deletions(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 99e2bd2691..5c8e9bbe38 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -50,8 +50,11 @@ pipeline { } } - stage('Package and publish build') { + 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}' @@ -62,9 +65,12 @@ pipeline { } } - stage('Publish build number') { + 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") diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 02623af09b..ed1d506fd3 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.10 +# Version: 1.1.12 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) @@ -16,7 +16,6 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ docker-compose ${DOCKER_COMPOSE_FLAGS} - clean: docker rmi ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) docker rmi gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) @@ -43,6 +42,9 @@ build: --tag gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ . +tar: + $(DOCKER_COMPOSE) up tar + publish: docker push $(DOCKER_REPO)/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 221569f544..51dc773ffe 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,9 +1,8 @@ ---script-version=1.1.10 docstore +--language=coffeescript --node-version=6.14.1 --acceptance-creds=aws ---language=coffeescript --dependencies=mongo,redis --docker-repos=gcr.io/overleaf-ops ---kube=false --build-target=docker +--script-version=1.1.12 diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 4e17f15673..e05433ac79 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.10 +# Version: 1.1.12 version: "2" @@ -11,6 +11,7 @@ services: user: node command: npm run test:unit:_run + test_acceptance: build: . image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER @@ -29,6 +30,16 @@ services: user: node command: npm run test:acceptance:_run + + + tar: + build: . + image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + volumes: + - ./:/tmp/build/ + command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs . + user: root + redis: image: redis diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index a556a008fa..e7b4d4e6d4 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.10 +# Version: 1.1.12 version: "2" @@ -36,6 +36,16 @@ services: - redis command: npm run test:acceptance + + + tar: + build: . + image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + volumes: + - ./:/tmp/build/ + command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs . + user: root + redis: image: redis diff --git a/services/docstore/npm-shrinkwrap.json b/services/docstore/npm-shrinkwrap.json index 384643d621..4dfa7fe2df 100644 --- a/services/docstore/npm-shrinkwrap.json +++ b/services/docstore/npm-shrinkwrap.json @@ -38,7 +38,7 @@ }, "@google-cloud/projectify": { "version": "0.3.2", - "from": "@google-cloud/projectify@>=0.3.2 <0.4.0", + "from": "@google-cloud/projectify@>=0.3.0 <0.4.0", "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.2.tgz" }, "@google-cloud/promisify": { @@ -47,14 +47,19 @@ "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz" }, "@google-cloud/trace-agent": { - "version": "3.5.0", + "version": "3.5.2", "from": "@google-cloud/trace-agent@>=3.2.0 <4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.5.0.tgz", + "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.5.2.tgz", "dependencies": { "@google-cloud/common": { - "version": "0.28.0", - "from": "@google-cloud/common@>=0.28.0 <0.29.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.28.0.tgz" + "version": "0.30.2", + "from": "@google-cloud/common@>=0.30.0 <0.31.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.30.2.tgz" + }, + "google-auth-library": { + "version": "3.0.1", + "from": "google-auth-library@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.0.1.tgz" }, "methods": { "version": "1.1.2", @@ -63,7 +68,7 @@ }, "uuid": { "version": "3.3.2", - "from": "uuid@>=3.0.1 <4.0.0", + "from": "uuid@^3.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" } } @@ -123,27 +128,11 @@ "from": "@sindresorhus/is@>=0.13.0 <0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.13.0.tgz" }, - "@sinonjs/commons": { - "version": "1.3.0", - "from": "@sinonjs/commons@^1.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", - "dependencies": { - "type-detect": { - "version": "4.0.8", - "from": "type-detect@4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" - } - } - }, "@sinonjs/formatio": { - "version": "3.1.0", - "from": "@sinonjs/formatio@^3.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz" - }, - "@sinonjs/samsam": { - "version": "3.0.2", - "from": "@sinonjs/samsam@^2 || ^3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.0.2.tgz" + "version": "2.0.0", + "from": "@sinonjs/formatio@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "dev": true }, "@types/caseless": { "version": "0.12.1", @@ -171,9 +160,9 @@ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz" }, "@types/node": { - "version": "10.12.18", + "version": "10.12.20", "from": "@types/node@*", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz" + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.20.tgz" }, "@types/request": { "version": "2.48.1", @@ -186,14 +175,9 @@ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz" }, "@types/tough-cookie": { - "version": "2.3.4", + "version": "2.3.5", "from": "@types/tough-cookie@*", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.4.tgz" - }, - "abbrev": { - "version": "1.1.1", - "from": "abbrev@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz" }, "accepts": { "version": "1.0.1", @@ -210,37 +194,10 @@ "from": "agent-base@>=4.1.0 <5.0.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz" }, - "ansi-regex": { - "version": "0.2.1", - "from": "ansi-regex@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz" - }, - "ansi-styles": { - "version": "1.1.0", - "from": "ansi-styles@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz" - }, - "argparse": { - "version": "0.1.16", - "from": "argparse@>=0.1.11 <0.2.0", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz", - "dependencies": { - "underscore": { - "version": "1.7.0", - "from": "underscore@>=1.7.0 <1.8.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz" - }, - "underscore.string": { - "version": "2.4.0", - "from": "underscore.string@>=2.4.0 <2.5.0", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz" - } - } - }, - "array-from": { - "version": "2.1.1", - "from": "array-from@^2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz" + "ajv": { + "version": "6.7.0", + "from": "ajv@>=6.5.5 <7.0.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz" }, "arrify": { "version": "1.0.1", @@ -277,6 +234,11 @@ "from": "async-listener@>=0.6.0 <0.7.0", "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz" }, + "asynckit": { + "version": "0.4.0", + "from": "asynckit@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + }, "aws-sign2": { "version": "0.5.0", "from": "aws-sign2@>=0.5.0 <0.6.0", @@ -284,25 +246,40 @@ "dev": true, "optional": true }, + "aws4": { + "version": "1.8.0", + "from": "aws4@>=1.8.0 <2.0.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz" + }, "axios": { "version": "0.18.0", "from": "axios@>=0.18.0 <0.19.0", - "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz" + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz" }, "balanced-match": { "version": "1.0.0", - "from": "balanced-match@>=1.0.0 <2.0.0", + "from": "balanced-match@^1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" }, + "base64-js": { + "version": "1.3.0", + "from": "base64-js@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" + }, "bignumber.js": { "version": "7.2.1", "from": "bignumber.js@>=7.0.0 <8.0.0", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz" }, "bindings": { - "version": "1.3.1", + "version": "1.4.0", "from": "bindings@>=1.2.1 <2.0.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.1.tgz" + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.4.0.tgz" }, "bintrees": { "version": "1.0.1", @@ -322,7 +299,7 @@ }, "brace-expansion": { "version": "1.1.11", - "from": "brace-expansion@>=1.1.7 <2.0.0", + "from": "brace-expansion@^1.1.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" }, "browser-stdout": { @@ -332,9 +309,9 @@ "dev": true }, "bson": { - "version": "1.0.9", + "version": "1.0.6", "from": "bson@>=1.0.4 <1.1.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.9.tgz" + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz" }, "buffer-crc32": { "version": "0.2.1", @@ -367,32 +344,22 @@ "from": "bytes@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz" }, + "caseless": { + "version": "0.12.0", + "from": "caseless@>=0.12.0 <0.13.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" + }, "chai": { "version": "1.9.2", "from": "chai@>=1.9.1 <1.10.0", "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", "dev": true }, - "chalk": { - "version": "0.5.1", - "from": "chalk@>=0.5.0 <0.6.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz" - }, - "check-error": { - "version": "1.0.2", - "from": "check-error@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz" - }, "coffee-script": { "version": "1.12.7", - "from": "coffee-script@>=1.12.7 <2.0.0", + "from": "coffee-script@>=1.7.1 <2.0.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz" }, - "colors": { - "version": "0.6.2", - "from": "colors@>=0.6.2 <0.7.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz" - }, "combined-stream": { "version": "0.0.7", "from": "combined-stream@>=0.0.4 <0.1.0", @@ -400,12 +367,6 @@ "dev": true, "optional": true }, - "commander": { - "version": "2.11.0", - "from": "commander@2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "dev": true - }, "concat-map": { "version": "0.0.1", "from": "concat-map@0.0.1", @@ -450,10 +411,17 @@ "dev": true, "optional": true }, - "dateformat": { - "version": "1.0.2-1.2.3", - "from": "dateformat@1.0.2-1.2.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.2-1.2.3.tgz" + "dashdash": { + "version": "1.14.1", + "from": "dashdash@>=1.12.0 <2.0.0", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@^1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } }, "debug": { "version": "0.8.1", @@ -478,12 +446,6 @@ "dev": true, "optional": true }, - "diff": { - "version": "3.3.1", - "from": "diff@3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "dev": true - }, "dtrace-provider": { "version": "0.2.8", "from": "dtrace-provider@0.2.8", @@ -501,6 +463,11 @@ "from": "each-series@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz" }, + "ecc-jsbn": { + "version": "0.1.2", + "from": "ecc-jsbn@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" + }, "ecdsa-sig-formatter": { "version": "1.0.10", "from": "ecdsa-sig-formatter@1.0.10", @@ -522,14 +489,21 @@ "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz" }, "es6-promise": { - "version": "4.2.5", - "from": "es6-promise@>=4.0.3 <5.0.0", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz" + "version": "3.2.1", + "from": "es6-promise@3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" }, "es6-promisify": { "version": "5.0.0", "from": "es6-promisify@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz" + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "dependencies": { + "es6-promise": { + "version": "4.2.5", + "from": "es6-promise@>=4.0.3 <5.0.0", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz" + } + } }, "escape-html": { "version": "1.0.1", @@ -538,23 +512,9 @@ }, "escape-string-regexp": { "version": "1.0.5", - "from": "escape-string-regexp@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - }, - "esprima": { - "version": "1.0.4", - "from": "esprima@>=1.0.2 <1.1.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz" - }, - "eventemitter2": { - "version": "0.4.14", - "from": "eventemitter2@>=0.4.13 <0.5.0", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz" - }, - "exit": { - "version": "0.1.2", - "from": "exit@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + "from": "escape-string-regexp@1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "dev": true }, "express": { "version": "4.1.2", @@ -566,33 +526,36 @@ "from": "extend@>=3.0.1 <4.0.0", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" }, + "extsprintf": { + "version": "1.3.0", + "from": "extsprintf@1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" + }, + "fast-deep-equal": { + "version": "2.0.1", + "from": "fast-deep-equal@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "from": "fast-json-stable-stringify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz" + }, + "fast-text-encoding": { + "version": "1.0.0", + "from": "fast-text-encoding@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz" + }, + "file-uri-to-path": { + "version": "1.0.0", + "from": "file-uri-to-path@1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" + }, "findit2": { "version": "2.2.3", "from": "findit2@>=2.2.3 <3.0.0", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz" }, - "findup-sync": { - "version": "0.1.3", - "from": "findup-sync@>=0.1.2 <0.2.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.1.3.tgz", - "dependencies": { - "glob": { - "version": "3.2.11", - "from": "glob@>=3.2.9 <3.3.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz" - }, - "lodash": { - "version": "2.4.2", - "from": "lodash@>=2.4.1 <2.5.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" - }, - "minimatch": { - "version": "0.3.0", - "from": "minimatch@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz" - } - } - }, "follow-redirects": { "version": "1.6.1", "from": "follow-redirects@>=1.3.0 <2.0.0", @@ -638,18 +601,6 @@ "from": "fresh@0.2.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz" }, - "fs-extra": { - "version": "0.9.1", - "from": "fs-extra@>=0.9.1 <0.10.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.9.1.tgz", - "dependencies": { - "ncp": { - "version": "0.5.1", - "from": "ncp@>=0.5.1 <0.6.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-0.5.1.tgz" - } - } - }, "fs.realpath": { "version": "1.0.0", "from": "fs.realpath@>=1.0.0 <2.0.0", @@ -657,29 +608,32 @@ "dev": true }, "gaxios": { - "version": "1.0.7", - "from": "gaxios@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.0.7.tgz" + "version": "1.2.7", + "from": "gaxios@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.2.7.tgz" }, "gcp-metadata": { "version": "0.9.3", "from": "gcp-metadata@>=0.9.0 <0.10.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz" }, - "get-func-name": { - "version": "2.0.0", - "from": "get-func-name@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz" - }, - "getobject": { - "version": "0.1.0", - "from": "getobject@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz" + "getpass": { + "version": "0.1.7", + "from": "getpass@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@^1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } }, "glob": { "version": "6.0.4", - "from": "glob@>=6.0.1 <7.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz" + "from": "glob@^6.0.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "optional": true }, "google-auth-library": { "version": "2.0.2", @@ -690,11 +644,6 @@ "version": "0.7.0", "from": "gcp-metadata@>=0.7.0 <0.8.0", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz" - }, - "lru-cache": { - "version": "5.1.1", - "from": "lru-cache@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" } } }, @@ -703,219 +652,27 @@ "from": "google-p12-pem@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.3.tgz" }, - "graceful-fs": { - "version": "1.2.3", - "from": "graceful-fs@>=1.2.0 <1.3.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz" - }, - "growl": { - "version": "1.10.3", - "from": "growl@1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "dev": true - }, - "grunt": { - "version": "0.4.5", - "from": "grunt@>=0.4.5 <0.5.0", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-0.4.5.tgz", - "dependencies": { - "async": { - "version": "0.1.22", - "from": "async@>=0.1.22 <0.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz" - }, - "coffee-script": { - "version": "1.3.3", - "from": "coffee-script@>=1.3.3 <1.4.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.3.3.tgz" - }, - "glob": { - "version": "3.1.21", - "from": "glob@>=3.1.21 <3.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz" - }, - "inherits": { - "version": "1.0.2", - "from": "inherits@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz" - }, - "minimatch": { - "version": "0.2.14", - "from": "minimatch@>=0.2.12 <0.3.0", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz" - }, - "rimraf": { - "version": "2.2.8", - "from": "rimraf@>=2.2.8 <2.3.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" - } - } - }, - "grunt-bunyan": { - "version": "0.5.0", - "from": "grunt-bunyan@>=0.5.0 <0.6.0", - "resolved": "https://registry.npmjs.org/grunt-bunyan/-/grunt-bunyan-0.5.0.tgz", - "dependencies": { - "lodash": { - "version": "2.4.2", - "from": "lodash@>=2.4.1 <2.5.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" - } - } - }, - "grunt-contrib-clean": { - "version": "0.6.0", - "from": "grunt-contrib-clean@>=0.6.0 <0.7.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-0.6.0.tgz", - "dependencies": { - "rimraf": { - "version": "2.2.8", - "from": "rimraf@>=2.2.1 <2.3.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz" - } - } - }, - "grunt-contrib-coffee": { - "version": "0.11.1", - "from": "grunt-contrib-coffee@>=0.11.0 <0.12.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-0.11.1.tgz", - "dependencies": { - "coffee-script": { - "version": "1.7.1", - "from": "coffee-script@>=1.7.0 <1.8.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.7.1.tgz" - }, - "lodash": { - "version": "2.4.2", - "from": "lodash@>=2.4.1 <2.5.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" - }, - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@>=0.3.5 <0.4.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" - } - } - }, - "grunt-execute": { - "version": "0.2.2", - "from": "grunt-execute@>=0.2.2 <0.3.0", - "resolved": "https://registry.npmjs.org/grunt-execute/-/grunt-execute-0.2.2.tgz" - }, - "grunt-legacy-log": { - "version": "0.1.3", - "from": "grunt-legacy-log@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-0.1.3.tgz", - "dependencies": { - "lodash": { - "version": "2.4.2", - "from": "lodash@>=2.4.1 <2.5.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" - }, - "underscore.string": { - "version": "2.3.3", - "from": "underscore.string@>=2.3.3 <2.4.0", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" - } - } - }, - "grunt-legacy-log-utils": { - "version": "0.1.1", - "from": "grunt-legacy-log-utils@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-0.1.1.tgz", - "dependencies": { - "lodash": { - "version": "2.4.2", - "from": "lodash@>=2.4.1 <2.5.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-2.4.2.tgz" - }, - "underscore.string": { - "version": "2.3.3", - "from": "underscore.string@>=2.3.3 <2.4.0", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.3.3.tgz" - } - } - }, - "grunt-legacy-util": { - "version": "0.2.0", - "from": "grunt-legacy-util@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-0.2.0.tgz", - "dependencies": { - "async": { - "version": "0.1.22", - "from": "async@>=0.1.22 <0.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.1.22.tgz" - } - } - }, - "grunt-mocha-test": { - "version": "0.11.0", - "from": "grunt-mocha-test@>=0.11.0 <0.12.0", - "resolved": "https://registry.npmjs.org/grunt-mocha-test/-/grunt-mocha-test-0.11.0.tgz", - "dependencies": { - "commander": { - "version": "2.0.0", - "from": "commander@2.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.0.0.tgz" - }, - "diff": { - "version": "1.0.7", - "from": "diff@1.0.7", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.7.tgz" - }, - "glob": { - "version": "3.2.3", - "from": "glob@3.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.3.tgz" - }, - "graceful-fs": { - "version": "2.0.3", - "from": "graceful-fs@>=2.0.0 <2.1.0", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-2.0.3.tgz" - }, - "growl": { - "version": "1.7.0", - "from": "growl@>=1.7.0 <1.8.0", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.7.0.tgz" - }, - "minimatch": { - "version": "0.2.14", - "from": "minimatch@~0.2.11", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz" - }, - "mkdirp": { - "version": "0.3.5", - "from": "mkdirp@0.3.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz" - }, - "mocha": { - "version": "1.20.1", - "from": "mocha@>=1.20.0 <1.21.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-1.20.1.tgz" - } - } - }, "gtoken": { - "version": "2.3.0", + "version": "2.3.2", "from": "gtoken@>=2.3.0 <3.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.2.tgz", "dependencies": { "mime": { "version": "2.4.0", "from": "mime@>=2.2.0 <3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz" - }, - "pify": { - "version": "3.0.0", - "from": "pify@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz" } } }, - "has-ansi": { - "version": "0.1.0", - "from": "has-ansi@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz" + "har-schema": { + "version": "2.0.0", + "from": "har-schema@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" + }, + "har-validator": { + "version": "5.1.3", + "from": "har-validator@>=5.1.0 <5.2.0", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz" }, "has-flag": { "version": "2.0.0", @@ -937,9 +694,9 @@ "dev": true }, "hex2dec": { - "version": "1.1.1", + "version": "1.1.2", "from": "hex2dec@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.1.tgz" + "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz" }, "hoek": { "version": "0.9.1", @@ -947,11 +704,6 @@ "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", "dev": true }, - "hooker": { - "version": "0.2.3", - "from": "hooker@>=0.2.3 <0.3.0", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz" - }, "http-signature": { "version": "0.10.1", "from": "http-signature@>=0.10.0 <0.11.0", @@ -976,14 +728,9 @@ } } }, - "iconv-lite": { - "version": "0.2.11", - "from": "iconv-lite@>=0.2.11 <0.3.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.2.11.tgz" - }, "inflight": { "version": "1.0.6", - "from": "inflight@>=1.0.4 <2.0.0", + "from": "inflight@^1.0.4", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" }, "inherits": { @@ -991,13 +738,6 @@ "from": "inherits@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" }, - "ip-regex": { - "version": "3.0.0", - "from": "ip-regex@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-3.0.0.tgz", - "dev": true, - "optional": true - }, "is": { "version": "3.3.0", "from": "is@>=3.2.0 <4.0.0", @@ -1008,72 +748,73 @@ "from": "is-buffer@>=1.1.5 <2.0.0", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" }, + "is-typedarray": { + "version": "1.0.0", + "from": "is-typedarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" + }, "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" }, - "jade": { - "version": "0.26.3", - "from": "jade@0.26.3", - "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", - "dependencies": { - "commander": { - "version": "0.6.1", - "from": "commander@0.6.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz" - }, - "mkdirp": { - "version": "0.3.0", - "from": "mkdirp@0.3.0", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz" - } - } + "isstream": { + "version": "0.1.2", + "from": "isstream@>=0.1.2 <0.2.0", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" }, - "js-yaml": { - "version": "2.0.5", - "from": "js-yaml@>=2.0.5 <2.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-2.0.5.tgz" + "jsbn": { + "version": "0.1.1", + "from": "jsbn@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" }, "json-bigint": { "version": "0.3.0", "from": "json-bigint@>=0.3.0 <0.4.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz" }, + "json-schema": { + "version": "0.2.3", + "from": "json-schema@0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" + }, + "json-schema-traverse": { + "version": "0.4.1", + "from": "json-schema-traverse@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" + }, "json-stringify-safe": { "version": "5.0.1", - "from": "json-stringify-safe@5.0.1", + "from": "json-stringify-safe@>=5.0.0 <5.1.0", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" }, - "jsonfile": { - "version": "1.1.1", - "from": "jsonfile@>=1.1.0 <1.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-1.1.1.tgz" + "jsprim": { + "version": "1.4.1", + "from": "jsprim@>=1.2.2 <2.0.0", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } }, "just-extend": { - "version": "4.0.2", - "from": "just-extend@^4.0.2", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz" + "version": "1.1.27", + "from": "just-extend@>=1.1.27 <2.0.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", + "dev": true }, "jwa": { - "version": "1.1.6", - "from": "jwa@>=1.1.5 <2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz" + "version": "1.2.0", + "from": "jwa@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.2.0.tgz" }, "jws": { - "version": "3.1.5", + "version": "3.2.1", "from": "jws@>=3.1.5 <4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz" - }, - "lodash": { - "version": "0.9.2", - "from": "lodash@>=0.9.2 <0.10.0", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-0.9.2.tgz" - }, - "lodash.get": { - "version": "4.4.2", - "from": "lodash.get@^4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.1.tgz" }, "lodash.pickby": { "version": "4.6.0", @@ -1081,39 +822,39 @@ "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz" }, "logger-sharelatex": { - "version": "1.5.9", - "from": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.5.9", - "resolved": "git+https://github.com/sharelatex/logger-sharelatex.git#e8e1b95052f62e107336053e4a983f81cdbdf589", + "version": "1.6.0", + "from": "logger-sharelatex@1.6.0", + "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.6.0.tgz", "dependencies": { - "assertion-error": { - "version": "1.1.0", - "from": "assertion-error@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz" + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + }, + "aws-sign2": { + "version": "0.7.0", + "from": "aws-sign2@>=0.7.0 <0.8.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" }, "bunyan": { "version": "1.5.1", "from": "bunyan@1.5.1", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz" }, - "chai": { - "version": "4.2.0", - "from": "chai@latest", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz" - }, "coffee-script": { "version": "1.12.4", "from": "coffee-script@1.12.4", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.4.tgz" }, - "deep-eql": { - "version": "3.0.1", - "from": "deep-eql@>=3.0.1 <4.0.0", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz" + "combined-stream": { + "version": "1.0.7", + "from": "combined-stream@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz" }, - "diff": { - "version": "3.5.0", - "from": "diff@>=3.5.0 <4.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" + "delayed-stream": { + "version": "1.0.0", + "from": "delayed-stream@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" }, "dtrace-provider": { "version": "0.6.0", @@ -1121,42 +862,58 @@ "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", "optional": true }, - "has-flag": { - "version": "3.0.0", - "from": "has-flag@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + "forever-agent": { + "version": "0.6.1", + "from": "forever-agent@>=0.6.1 <0.7.0", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" }, - "lolex": { - "version": "3.0.0", - "from": "lolex@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.0.0.tgz" + "form-data": { + "version": "2.3.3", + "from": "form-data@>=2.3.2 <2.4.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" }, - "sandboxed-module": { - "version": "2.0.3", - "from": "sandboxed-module@latest", - "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-2.0.3.tgz" + "http-signature": { + "version": "1.2.0", + "from": "http-signature@>=1.2.0 <1.3.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" }, - "sinon": { - "version": "7.2.2", - "from": "sinon@latest", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.2.tgz" + "oauth-sign": { + "version": "0.9.0", + "from": "oauth-sign@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" }, - "supports-color": { - "version": "5.5.0", - "from": "supports-color@>=5.5.0 <6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + "qs": { + "version": "6.5.2", + "from": "qs@>=6.5.2 <6.6.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz" }, - "type-detect": { - "version": "4.0.8", - "from": "type-detect@>=4.0.5 <5.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + "request": { + "version": "2.88.0", + "from": "request@>=2.88.0 <3.0.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz" + }, + "tough-cookie": { + "version": "2.4.3", + "from": "tough-cookie@>=2.4.3 <2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz" + }, + "tunnel-agent": { + "version": "0.6.0", + "from": "tunnel-agent@>=0.6.0 <0.7.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" + }, + "uuid": { + "version": "3.3.2", + "from": "uuid@>=3.3.2 <4.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" } } }, "lolex": { - "version": "2.7.5", + "version": "2.6.0", "from": "lolex@>=2.1.2 <3.0.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz" + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.6.0.tgz", + "dev": true }, "long": { "version": "4.0.0", @@ -1164,9 +921,9 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz" }, "lru-cache": { - "version": "2.7.3", - "from": "lru-cache@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz" + "version": "5.1.1", + "from": "lru-cache@>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" }, "lsmod": { "version": "1.0.0", @@ -1194,9 +951,9 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz" }, "metrics-sharelatex": { - "version": "2.0.12", - "from": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.12", - "resolved": "git+https://github.com/sharelatex/metrics-sharelatex.git#3ac1621ef049e2f2d88a83b3a41011333d609662", + "version": "2.1.1", + "from": "metrics-sharelatex@2.1.1", + "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.1.1.tgz", "dependencies": { "coffee-script": { "version": "1.6.0", @@ -1210,9 +967,19 @@ "from": "mime@>=1.2.11 <1.3.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" }, + "mime-db": { + "version": "1.37.0", + "from": "mime-db@>=1.37.0 <1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz" + }, + "mime-types": { + "version": "2.1.21", + "from": "mime-types@>=2.1.19 <2.2.0", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz" + }, "minimatch": { "version": "3.0.4", - "from": "minimatch@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0", + "from": "minimatch@2 || 3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" }, "minimist": { @@ -1222,7 +989,7 @@ }, "mkdirp": { "version": "0.5.1", - "from": "mkdirp@>=0.5.1 <0.6.0", + "from": "mkdirp@~0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" }, "mocha": { @@ -1231,22 +998,34 @@ "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", "dev": true, "dependencies": { + "commander": { + "version": "2.11.0", + "from": "commander@2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "dev": true + }, "debug": { "version": "3.1.0", "from": "debug@3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "dev": true }, + "diff": { + "version": "3.3.1", + "from": "diff@3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "dev": true + }, "glob": { "version": "7.1.2", "from": "glob@7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "dev": true }, - "supports-color": { - "version": "4.4.0", - "from": "supports-color@4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "growl": { + "version": "1.10.3", + "from": "growl@1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", "dev": true } } @@ -1257,25 +1036,10 @@ "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz" }, "mongodb": { - "version": "2.2.36", + "version": "2.2.35", "from": "mongodb@>=2.0.45 <3.0.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.36.tgz", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz", "dependencies": { - "es6-promise": { - "version": "3.2.1", - "from": "es6-promise@3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" - }, "readable-stream": { "version": "2.2.7", "from": "readable-stream@2.2.7", @@ -1289,9 +1053,9 @@ } }, "mongodb-core": { - "version": "2.1.20", - "from": "mongodb-core@2.1.20", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.20.tgz" + "version": "2.1.19", + "from": "mongodb-core@2.1.19", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz" }, "mongojs": { "version": "2.4.0", @@ -1332,14 +1096,22 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz" }, "nise": { - "version": "1.4.8", - "from": "nise@^1.0.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "version": "1.3.3", + "from": "nise@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.3.tgz", + "dev": true, "dependencies": { + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "dev": true + }, "path-to-regexp": { "version": "1.7.0", "from": "path-to-regexp@>=1.7.0 <2.0.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz" + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "dev": true } } }, @@ -1350,13 +1122,14 @@ }, "node-forge": { "version": "0.7.6", - "from": "node-forge@>=0.7.5 <0.8.0", + "from": "node-forge@>=0.7.4 <0.8.0", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz" }, - "nopt": { - "version": "1.0.10", - "from": "nopt@>=1.0.10 <1.1.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz" + "node-uuid": { + "version": "1.4.8", + "from": "node-uuid@>=1.4.1 <1.5.0", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "dev": true }, "oauth-sign": { "version": "0.3.0", @@ -1402,12 +1175,12 @@ }, "path-is-absolute": { "version": "1.0.1", - "from": "path-is-absolute@>=1.0.0 <2.0.0", + "from": "path-is-absolute@^1.0.0", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" }, "path-parse": { "version": "1.0.6", - "from": "path-parse@>=1.0.6 <2.0.0", + "from": "path-parse@>=1.0.5 <2.0.0", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" }, "path-to-regexp": { @@ -1415,14 +1188,14 @@ "from": "path-to-regexp@0.1.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz" }, - "pathval": { - "version": "1.1.0", - "from": "pathval@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz" + "performance-now": { + "version": "2.1.0", + "from": "performance-now@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" }, "pify": { "version": "4.0.1", - "from": "pify@>=4.0.1 <5.0.0", + "from": "pify@>=4.0.0 <5.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" }, "pretty-ms": { @@ -1431,9 +1204,9 @@ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz" }, "process-nextick-args": { - "version": "2.0.0", - "from": "process-nextick-args@>=2.0.0 <2.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz" + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" }, "prom-client": { "version": "11.2.1", @@ -1447,17 +1220,13 @@ }, "psl": { "version": "1.1.31", - "from": "psl@>=1.1.28 <2.0.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "dev": true, - "optional": true + "from": "psl@>=1.1.24 <2.0.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz" }, "punycode": { - "version": "2.1.1", - "from": "punycode@>=2.1.1 <3.0.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "dev": true, - "optional": true + "version": "1.4.1", + "from": "punycode@>=1.4.1 <2.0.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" }, "qs": { "version": "0.6.6", @@ -1478,6 +1247,11 @@ "version": "0.3.1", "from": "cookie@0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz" + }, + "uuid": { + "version": "3.0.0", + "from": "uuid@3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz" } } }, @@ -1488,13 +1262,13 @@ }, "readable-stream": { "version": "2.3.6", - "from": "readable-stream@>=2.0.0 <3.0.0", + "from": "readable-stream@>=2.0.2 <3.0.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "dependencies": { - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + "process-nextick-args": { + "version": "2.0.0", + "from": "process-nextick-args@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz" }, "string_decoder": { "version": "1.1.1", @@ -1507,15 +1281,7 @@ "version": "2.34.0", "from": "request@>=2.34.0 <2.35.0", "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", - "dev": true, - "dependencies": { - "node-uuid": { - "version": "1.4.8", - "from": "node-uuid@>=1.4.0 <1.5.0", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "dev": true - } - } + "dev": true }, "require_optional": { "version": "1.0.1", @@ -1530,12 +1296,13 @@ "require-like": { "version": "0.1.2", "from": "require-like@0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz" + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "dev": true }, "resolve": { - "version": "1.9.0", + "version": "1.10.0", "from": "resolve@>=1.5.0 <2.0.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.9.0.tgz" + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz" }, "resolve-from": { "version": "2.0.0", @@ -1544,7 +1311,7 @@ }, "retry-axios": { "version": "0.3.2", - "from": "retry-axios@0.3.2", + "from": "retry-axios@>=0.3.2 <0.4.0", "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz" }, "retry-request": { @@ -1554,12 +1321,13 @@ }, "rimraf": { "version": "2.4.5", - "from": "rimraf@>=2.4.0 <2.5.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz" + "from": "rimraf@~2.4.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "optional": true }, "safe-buffer": { "version": "5.1.2", - "from": "safe-buffer@>=5.1.1 <5.2.0", + "from": "safe-buffer@>=5.1.0 <5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" }, "safe-json-stringify": { @@ -1568,6 +1336,11 @@ "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", "optional": true }, + "safer-buffer": { + "version": "2.1.2", + "from": "safer-buffer@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + }, "samsam": { "version": "1.3.0", "from": "samsam@>=1.1.3 <2.0.0", @@ -1589,9 +1362,9 @@ } }, "semver": { - "version": "5.6.0", - "from": "semver@>=5.5.0 <6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz" + "version": "5.5.0", + "from": "semver@>=5.1.0 <6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz" }, "send": { "version": "0.3.0", @@ -1612,8 +1385,8 @@ }, "settings-sharelatex": { "version": "1.1.0", - "from": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.1.0", - "resolved": "git+https://github.com/sharelatex/settings-sharelatex.git#93f63d029b52fef8825c3a401b2b6a7ba29b4750", + "from": "settings-sharelatex@1.1.0", + "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", "dependencies": { "coffee-script": { "version": "1.6.0", @@ -1623,14 +1396,9 @@ } }, "shimmer": { - "version": "1.2.0", + "version": "1.2.1", "from": "shimmer@>=1.2.0 <2.0.0", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.0.tgz" - }, - "sigmund": { - "version": "1.0.1", - "from": "sigmund@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz" }, "sinon": { "version": "3.2.1", @@ -1638,6 +1406,18 @@ "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", "dev": true, "dependencies": { + "diff": { + "version": "3.5.0", + "from": "diff@>=3.1.0 <4.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "dev": true + }, "path-to-regexp": { "version": "1.7.0", "from": "path-to-regexp@>=1.7.0 <2.0.0", @@ -1646,7 +1426,7 @@ }, "type-detect": { "version": "4.0.8", - "from": "type-detect@^4.0.0", + "from": "type-detect@>=4.0.0 <5.0.0", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "dev": true } @@ -1669,6 +1449,23 @@ "from": "split@>=1.0.0 <2.0.0", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz" }, + "sshpk": { + "version": "1.16.1", + "from": "sshpk@>=1.7.0 <2.0.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "dependencies": { + "asn1": { + "version": "0.2.4", + "from": "asn1@>=0.2.3 <0.3.0", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz" + }, + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@^1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } + }, "stack-trace": { "version": "0.0.9", "from": "stack-trace@0.0.9", @@ -1689,15 +1486,11 @@ "from": "string_decoder@>=0.10.0 <0.11.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" }, - "strip-ansi": { - "version": "0.3.0", - "from": "strip-ansi@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz" - }, "supports-color": { - "version": "0.2.0", - "from": "supports-color@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz" + "version": "4.4.0", + "from": "supports-color@4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "dev": true }, "symbol-observable": { "version": "1.2.0", @@ -1706,12 +1499,12 @@ }, "tdigest": { "version": "0.1.1", - "from": "tdigest@>=0.1.1 <0.2.0", + "from": "tdigest@^0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz" }, "teeny-request": { "version": "3.11.3", - "from": "teeny-request@>=3.11.1 <4.0.0", + "from": "teeny-request@>=3.6.0 <4.0.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", "dependencies": { "uuid": { @@ -1724,7 +1517,8 @@ "text-encoding": { "version": "0.6.4", "from": "text-encoding@0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz" + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "dev": true }, "through": { "version": "2.3.8", @@ -1733,7 +1527,7 @@ }, "through2": { "version": "2.0.5", - "from": "through2@>=2.0.0 <3.0.0", + "from": "through2@>=2.0.3 <3.0.0", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" }, "thunky": { @@ -1741,20 +1535,15 @@ "from": "thunky@>=0.1.0 <0.2.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz" }, - "timekeeper": { - "version": "1.0.0", - "from": "timekeeper@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/timekeeper/-/timekeeper-1.0.0.tgz" - }, "to-mongodb-core": { "version": "2.0.0", "from": "to-mongodb-core@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz" }, "tough-cookie": { - "version": "3.0.0", + "version": "2.3.4", "from": "tough-cookie@>=0.12.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", "dev": true, "optional": true }, @@ -1765,6 +1554,11 @@ "dev": true, "optional": true }, + "tweetnacl": { + "version": "0.14.5", + "from": "tweetnacl@>=0.14.0 <0.15.0", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" + }, "type-detect": { "version": "0.1.1", "from": "type-detect@0.1.1", @@ -1781,10 +1575,17 @@ "from": "underscore@>=1.6.0 <1.7.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz" }, - "underscore.string": { - "version": "2.2.1", - "from": "underscore.string@>=2.2.1 <2.3.0", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.2.1.tgz" + "uri-js": { + "version": "4.2.2", + "from": "uri-js@>=4.2.2 <5.0.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "dependencies": { + "punycode": { + "version": "2.1.1", + "from": "punycode@>=2.1.0 <3.0.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" + } + } }, "util-deprecate": { "version": "1.0.2", @@ -1796,15 +1597,17 @@ "from": "utils-merge@1.0.0", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" }, - "uuid": { - "version": "3.0.0", - "from": "uuid@3.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz" - }, - "which": { - "version": "1.0.9", - "from": "which@>=1.0.5 <1.1.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz" + "verror": { + "version": "1.10.0", + "from": "verror@1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "from": "assert-plus@^1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" + } + } }, "wrappy": { "version": "1.0.2", @@ -1813,7 +1616,7 @@ }, "xtend": { "version": "4.0.1", - "from": "xtend@>=4.0.1 <4.1.0", + "from": "xtend@>=4.0.0 <5.0.0", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" }, "yallist": { diff --git a/services/docstore/package.json b/services/docstore/package.json index b2dcc483e1..5897772d4b 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -25,10 +25,10 @@ "body-parser": "~1.0.2", "coffee-script": "^1.12.7", "express": "~4.1.1", - "logger-sharelatex": "git+https://github.com/sharelatex/logger-sharelatex.git#v1.5.9", - "metrics-sharelatex": "git+https://github.com/sharelatex/metrics-sharelatex.git#v2.0.12", + "logger-sharelatex": "^1.6.0", + "metrics-sharelatex": "^2.1.1", "mongojs": "2.4.0", - "settings-sharelatex": "git+https://github.com/sharelatex/settings-sharelatex.git#v1.1.0", + "settings-sharelatex": "^1.1.0", "underscore": "~1.6.0" }, "devDependencies": { From 0ee7a81a02f2e00d3ef1de5790a7b08ef4ce647d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Alby?= <tim.alby@overleaf.com> Date: Tue, 7 May 2019 16:25:59 +0100 Subject: [PATCH 195/349] Update README.md --- services/docstore/README.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/services/docstore/README.md b/services/docstore/README.md index 4058e6cb42..4fccec8d9c 100644 --- a/services/docstore/README.md +++ b/services/docstore/README.md @@ -1,20 +1,12 @@ -docstore-sharelatex +overleaf/docstore =================== A CRUD API for storing and updating text documents in projects -[![Build Status](https://travis-ci.org/sharelatex/docstore-sharelatex.png?branch=master)](https://travis-ci.org/sharelatex/docstore-sharelatex) - -Acceptance tests can be run with the command -``` -docker run --rm -e AWS_BUCKET="<bucket-name>" -e AWS_ACCESS_KEY_ID=<aws-access-key> -e AWS_SECRET_ACCESS_KEY=<aws-secret-access-key> -v $(pwd):/app sharelatex/acceptance-test-runner -``` -where `bucket-name`, `aws-access-key` and `aws-secret-access-key` are the credentials for an AWS S3 bucket. - License ------- The code in this repository is released under the GNU AFFERO GENERAL PUBLIC LICENSE, version 3. A copy can be found in the `LICENSE` file. -Copyright (c) ShareLaTeX, 2014. +Copyright (c) Overleaf, 2014-2019. From 3de8e938152528f34389b0f125db55220d1b231a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Alby?= <tim.alby@overleaf.com> Date: Tue, 7 May 2019 18:39:09 +0200 Subject: [PATCH 196/349] update Git URL in Jenkinsfile --- services/docstore/Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 5c8e9bbe38..02d67a77d7 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -4,10 +4,10 @@ pipeline { agent any environment { - GIT_PROJECT = "docstore-sharelatex" + GIT_PROJECT = "docstore" JENKINS_WORKFLOW = "docstore-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/sharelatex/${GIT_PROJECT}/statuses/$GIT_COMMIT" + GIT_API_URL = "https://api.github.com/repos/overleaf/${GIT_PROJECT}/statuses/$GIT_COMMIT" } triggers { From a9b35dde008605073f436cf739ed09d20bf91348 Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane@kilkelly.me> Date: Wed, 19 Jun 2019 09:37:54 +0100 Subject: [PATCH 197/349] update logger and metrics --- services/docstore/Makefile | 6 +- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose.ci.yml | 5 +- services/docstore/docker-compose.yml | 8 +- services/docstore/npm-shrinkwrap.json | 351 +++++++++++++----------- services/docstore/package.json | 4 +- 6 files changed, 215 insertions(+), 161 deletions(-) diff --git a/services/docstore/Makefile b/services/docstore/Makefile index ed1d506fd3..93bd3d3991 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.12 +# Version: 1.1.21 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) @@ -29,7 +29,9 @@ test: test_unit test_acceptance test_unit: @[ ! -d test/unit ] && echo "docstore has no unit tests" || $(DOCKER_COMPOSE) run --rm test_unit -test_acceptance: test_clean test_acceptance_pre_run # clear the database before each acceptance test run +test_acceptance: test_clean test_acceptance_pre_run test_acceptance_run + +test_acceptance_run: @[ ! -d test/acceptance ] && echo "docstore has no acceptance tests" || $(DOCKER_COMPOSE) run --rm test_acceptance test_clean: diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 51dc773ffe..d4c500e1bd 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -5,4 +5,4 @@ docstore --dependencies=mongo,redis --docker-repos=gcr.io/overleaf-ops --build-target=docker ---script-version=1.1.12 +--script-version=1.1.21 diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index e05433ac79..baac7bccae 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.12 +# Version: 1.1.21 version: "2" @@ -10,6 +10,8 @@ services: image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER user: node command: npm run test:unit:_run + environment: + NODE_ENV: test test_acceptance: @@ -24,6 +26,7 @@ services: AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} + NODE_ENV: test depends_on: - mongo - redis diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index e7b4d4e6d4..ed252891e8 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,18 +1,19 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.12 +# Version: 1.1.21 version: "2" services: test_unit: - build: . + image: node:6.14.1 volumes: - .:/app working_dir: /app environment: MOCHA_GREP: ${MOCHA_GREP} + NODE_ENV: test command: npm run test:unit user: node @@ -30,6 +31,8 @@ services: AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} + LOG_LEVEL: ERROR + NODE_ENV: test user: node depends_on: - mongo @@ -52,3 +55,4 @@ services: mongo: image: mongo:3.4 + diff --git a/services/docstore/npm-shrinkwrap.json b/services/docstore/npm-shrinkwrap.json index 4dfa7fe2df..41b289b9c5 100644 --- a/services/docstore/npm-shrinkwrap.json +++ b/services/docstore/npm-shrinkwrap.json @@ -3,19 +3,24 @@ "version": "0.1.2", "dependencies": { "@google-cloud/common": { - "version": "0.27.0", - "from": "@google-cloud/common@>=0.27.0 <0.28.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.27.0.tgz" + "version": "0.32.1", + "from": "@google-cloud/common@>=0.32.0 <0.33.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz" }, "@google-cloud/debug-agent": { - "version": "3.0.1", + "version": "3.2.0", "from": "@google-cloud/debug-agent@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-3.2.0.tgz", "dependencies": { "coffeescript": { - "version": "2.3.2", + "version": "2.4.1", "from": "coffeescript@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.3.2.tgz" + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.4.1.tgz" + }, + "semver": { + "version": "6.1.1", + "from": "semver@>=6.0.0 <7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz" } } }, @@ -29,43 +34,65 @@ "from": "@google-cloud/common@>=0.26.0 <0.27.0", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.26.2.tgz" }, + "@google-cloud/promisify": { + "version": "0.3.1", + "from": "@google-cloud/promisify@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz" + }, + "arrify": { + "version": "1.0.1", + "from": "arrify@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + }, + "gcp-metadata": { + "version": "0.9.3", + "from": "gcp-metadata@>=0.9.0 <0.10.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz" + }, + "google-auth-library": { + "version": "2.0.2", + "from": "google-auth-library@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.2.tgz", + "dependencies": { + "gcp-metadata": { + "version": "0.7.0", + "from": "gcp-metadata@>=0.7.0 <0.8.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz" + } + } + }, "through2": { - "version": "3.0.0", + "version": "3.0.1", "from": "through2@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.0.tgz" + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz" } } }, "@google-cloud/projectify": { - "version": "0.3.2", - "from": "@google-cloud/projectify@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.2.tgz" + "version": "0.3.3", + "from": "@google-cloud/projectify@>=0.3.3 <0.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz" }, "@google-cloud/promisify": { - "version": "0.3.1", - "from": "@google-cloud/promisify@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz" + "version": "0.4.0", + "from": "@google-cloud/promisify@>=0.4.0 <0.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz" }, "@google-cloud/trace-agent": { - "version": "3.5.2", + "version": "3.6.1", "from": "@google-cloud/trace-agent@>=3.2.0 <4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.5.2.tgz", + "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.6.1.tgz", "dependencies": { - "@google-cloud/common": { - "version": "0.30.2", - "from": "@google-cloud/common@>=0.30.0 <0.31.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.30.2.tgz" - }, - "google-auth-library": { - "version": "3.0.1", - "from": "google-auth-library@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.0.1.tgz" - }, "methods": { "version": "1.1.2", "from": "methods@>=1.1.1 <2.0.0", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" }, + "semver": { + "version": "6.1.1", + "from": "semver@^6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz" + }, "uuid": { "version": "3.3.2", "from": "uuid@^3.0.1", @@ -124,9 +151,9 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz" }, "@sindresorhus/is": { - "version": "0.13.0", - "from": "@sindresorhus/is@>=0.13.0 <0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.13.0.tgz" + "version": "0.15.0", + "from": "@sindresorhus/is@>=0.15.0 <0.16.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.15.0.tgz" }, "@sinonjs/formatio": { "version": "2.0.0", @@ -135,9 +162,9 @@ "dev": true }, "@types/caseless": { - "version": "0.12.1", + "version": "0.12.2", "from": "@types/caseless@*", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.1.tgz" + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz" }, "@types/console-log-level": { "version": "1.4.0", @@ -160,9 +187,9 @@ "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz" }, "@types/node": { - "version": "10.12.20", + "version": "12.0.8", "from": "@types/node@*", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.20.tgz" + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz" }, "@types/request": { "version": "2.48.1", @@ -179,30 +206,35 @@ "from": "@types/tough-cookie@*", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz" }, + "abort-controller": { + "version": "3.0.0", + "from": "abort-controller@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" + }, "accepts": { "version": "1.0.1", "from": "accepts@1.0.1", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz" }, "acorn": { - "version": "5.7.3", - "from": "acorn@>=5.0.3 <6.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz" + "version": "6.1.1", + "from": "acorn@>=6.0.0 <7.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz" }, "agent-base": { - "version": "4.2.1", + "version": "4.3.0", "from": "agent-base@>=4.1.0 <5.0.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz" + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz" }, "ajv": { - "version": "6.7.0", + "version": "6.10.0", "from": "ajv@>=6.5.5 <7.0.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.7.0.tgz" + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz" }, "arrify": { - "version": "1.0.1", - "from": "arrify@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" + "version": "2.0.1", + "from": "arrify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz" }, "asn1": { "version": "0.1.11", @@ -252,9 +284,9 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz" }, "axios": { - "version": "0.18.0", + "version": "0.18.1", "from": "axios@>=0.18.0 <0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz" + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz" }, "balanced-match": { "version": "1.0.0", @@ -277,9 +309,9 @@ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz" }, "bindings": { - "version": "1.4.0", + "version": "1.5.0", "from": "bindings@>=1.2.1 <2.0.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.4.0.tgz" + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" }, "bintrees": { "version": "1.0.1", @@ -329,9 +361,9 @@ "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" }, "builtin-modules": { - "version": "3.0.0", + "version": "3.1.0", "from": "builtin-modules@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.0.0.tgz" + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz" }, "bunyan": { "version": "0.22.3", @@ -373,9 +405,9 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" }, "console-log-level": { - "version": "1.4.0", + "version": "1.4.1", "from": "console-log-level@>=1.4.0 <2.0.0", - "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.0.tgz" + "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz" }, "continuation-local-storage": { "version": "3.2.1", @@ -435,9 +467,9 @@ "dev": true }, "delay": { - "version": "4.1.0", + "version": "4.3.0", "from": "delay@>=4.0.1 <5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-4.1.0.tgz" + "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz" }, "delayed-stream": { "version": "0.0.5", @@ -454,9 +486,9 @@ "optional": true }, "duplexify": { - "version": "3.6.1", + "version": "3.7.1", "from": "duplexify@>=3.6.0 <4.0.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz" + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz" }, "each-series": { "version": "1.0.0", @@ -469,9 +501,9 @@ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" }, "ecdsa-sig-formatter": { - "version": "1.0.10", - "from": "ecdsa-sig-formatter@1.0.10", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz" + "version": "1.0.11", + "from": "ecdsa-sig-formatter@1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" }, "emitter-listener": { "version": "1.1.2", @@ -499,9 +531,9 @@ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "dependencies": { "es6-promise": { - "version": "4.2.5", + "version": "4.2.8", "from": "es6-promise@>=4.0.3 <5.0.0", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz" + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" } } }, @@ -516,6 +548,11 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "dev": true }, + "event-target-shim": { + "version": "5.0.1", + "from": "event-target-shim@>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" + }, "express": { "version": "4.1.2", "from": "express@>=4.1.1 <4.2.0", @@ -557,9 +594,9 @@ "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz" }, "follow-redirects": { - "version": "1.6.1", - "from": "follow-redirects@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.6.1.tgz", + "version": "1.5.10", + "from": "follow-redirects@1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", "dependencies": { "debug": { "version": "3.1.0", @@ -608,14 +645,14 @@ "dev": true }, "gaxios": { - "version": "1.2.7", - "from": "gaxios@>=1.0.4 <2.0.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.2.7.tgz" + "version": "1.8.4", + "from": "gaxios@>=1.2.1 <2.0.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz" }, "gcp-metadata": { - "version": "0.9.3", - "from": "gcp-metadata@>=0.9.0 <0.10.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz" + "version": "1.0.0", + "from": "gcp-metadata@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz" }, "getpass": { "version": "0.1.7", @@ -636,31 +673,24 @@ "optional": true }, "google-auth-library": { - "version": "2.0.2", - "from": "google-auth-library@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.2.tgz", - "dependencies": { - "gcp-metadata": { - "version": "0.7.0", - "from": "gcp-metadata@>=0.7.0 <0.8.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz" - } - } + "version": "3.1.2", + "from": "google-auth-library@>=3.1.1 <4.0.0", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz" }, "google-p12-pem": { - "version": "1.0.3", + "version": "1.0.4", "from": "google-p12-pem@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.3.tgz" + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz" }, "gtoken": { - "version": "2.3.2", - "from": "gtoken@>=2.3.0 <3.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.2.tgz", + "version": "2.3.3", + "from": "gtoken@>=2.3.2 <3.0.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", "dependencies": { "mime": { - "version": "2.4.0", + "version": "2.4.4", "from": "mime@>=2.2.0 <3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.0.tgz" + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz" } } }, @@ -722,9 +752,9 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz" }, "ms": { - "version": "2.1.1", + "version": "2.1.2", "from": "ms@>=2.1.1 <3.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz" + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" } } }, @@ -744,9 +774,9 @@ "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz" }, "is-buffer": { - "version": "1.1.6", - "from": "is-buffer@>=1.1.5 <2.0.0", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz" + "version": "2.0.3", + "from": "is-buffer@>=2.0.2 <3.0.0", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz" }, "is-typedarray": { "version": "1.0.0", @@ -807,14 +837,14 @@ "dev": true }, "jwa": { - "version": "1.2.0", - "from": "jwa@>=1.2.0 <2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.2.0.tgz" + "version": "1.4.1", + "from": "jwa@>=1.4.1 <2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz" }, "jws": { - "version": "3.2.1", + "version": "3.2.2", "from": "jws@>=3.1.5 <4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.1.tgz" + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz" }, "lodash.pickby": { "version": "4.6.0", @@ -822,9 +852,9 @@ "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz" }, "logger-sharelatex": { - "version": "1.6.0", - "from": "logger-sharelatex@1.6.0", - "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.6.0.tgz", + "version": "1.7.0", + "from": "logger-sharelatex@1.7.0", + "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.7.0.tgz", "dependencies": { "assert-plus": { "version": "1.0.0", @@ -837,19 +867,14 @@ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" }, "bunyan": { - "version": "1.5.1", - "from": "bunyan@1.5.1", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.5.1.tgz" - }, - "coffee-script": { - "version": "1.12.4", - "from": "coffee-script@1.12.4", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.4.tgz" + "version": "1.8.12", + "from": "bunyan@1.8.12", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz" }, "combined-stream": { - "version": "1.0.7", + "version": "1.0.8", "from": "combined-stream@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz" + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" }, "delayed-stream": { "version": "1.0.0", @@ -857,9 +882,9 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" }, "dtrace-provider": { - "version": "0.6.0", - "from": "dtrace-provider@>=0.6.0 <0.7.0", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.6.0.tgz", + "version": "0.8.7", + "from": "dtrace-provider@>=0.8.0 <0.9.0", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz", "optional": true }, "forever-agent": { @@ -951,9 +976,9 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz" }, "metrics-sharelatex": { - "version": "2.1.1", - "from": "metrics-sharelatex@2.1.1", - "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.1.1.tgz", + "version": "2.2.0", + "from": "metrics-sharelatex@2.2.0", + "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.2.0.tgz", "dependencies": { "coffee-script": { "version": "1.6.0", @@ -968,14 +993,14 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" }, "mime-db": { - "version": "1.37.0", - "from": "mime-db@>=1.37.0 <1.38.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz" + "version": "1.40.0", + "from": "mime-db@1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz" }, "mime-types": { - "version": "2.1.21", + "version": "2.1.24", "from": "mime-types@>=2.1.19 <2.2.0", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz" + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz" }, "minimatch": { "version": "3.0.4", @@ -1035,6 +1060,12 @@ "from": "module-details-from-path@>=1.0.3 <2.0.0", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz" }, + "moment": { + "version": "2.24.0", + "from": "moment@>=2.10.6 <3.0.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "optional": true + }, "mongodb": { "version": "2.2.35", "from": "mongodb@>=2.0.45 <3.0.0", @@ -1116,14 +1147,14 @@ } }, "node-fetch": { - "version": "2.3.0", - "from": "node-fetch@>=2.2.0 <3.0.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz" + "version": "2.6.0", + "from": "node-fetch@>=2.3.0 <3.0.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz" }, "node-forge": { - "version": "0.7.6", - "from": "node-forge@>=0.7.4 <0.8.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.6.tgz" + "version": "0.8.4", + "from": "node-forge@>=0.8.0 <0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.4.tgz" }, "node-uuid": { "version": "1.4.8", @@ -1144,14 +1175,14 @@ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" }, "p-limit": { - "version": "2.1.0", - "from": "p-limit@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz" + "version": "2.2.0", + "from": "p-limit@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz" }, "p-try": { - "version": "2.0.0", + "version": "2.2.0", "from": "p-try@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz" + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" }, "parse-duration": { "version": "0.1.1", @@ -1164,9 +1195,9 @@ "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz" }, "parse-ms": { - "version": "2.0.0", + "version": "2.1.0", "from": "parse-ms@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.0.0.tgz" + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz" }, "parseurl": { "version": "1.0.1", @@ -1209,19 +1240,26 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" }, "prom-client": { - "version": "11.2.1", + "version": "11.5.1", "from": "prom-client@>=11.1.3 <12.0.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.2.1.tgz" + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.1.tgz" }, "protobufjs": { "version": "6.8.8", "from": "protobufjs@>=6.8.6 <6.9.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz" + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "dependencies": { + "@types/node": { + "version": "10.14.9", + "from": "@types/node@>=10.1.0 <11.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.9.tgz" + } + } }, "psl": { - "version": "1.1.31", + "version": "1.1.32", "from": "psl@>=1.1.24 <2.0.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz" + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz" }, "punycode": { "version": "1.4.1", @@ -1239,9 +1277,9 @@ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz" }, "raven": { - "version": "1.2.1", - "from": "raven@>=1.1.3 <2.0.0", - "resolved": "https://registry.npmjs.org/raven/-/raven-1.2.1.tgz", + "version": "1.1.3", + "from": "raven@1.1.3", + "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", "dependencies": { "cookie": { "version": "0.3.1", @@ -1289,9 +1327,21 @@ "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz" }, "require-in-the-middle": { - "version": "3.1.0", - "from": "require-in-the-middle@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-3.1.0.tgz" + "version": "4.0.0", + "from": "require-in-the-middle@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.0.tgz", + "dependencies": { + "debug": { + "version": "4.1.1", + "from": "debug@>=4.1.1 <5.0.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz" + }, + "ms": { + "version": "2.1.2", + "from": "ms@^2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + } + } }, "require-like": { "version": "0.1.2", @@ -1300,9 +1350,9 @@ "dev": true }, "resolve": { - "version": "1.10.0", - "from": "resolve@>=1.5.0 <2.0.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz" + "version": "1.11.0", + "from": "resolve@>=1.10.0 <2.0.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz" }, "resolve-from": { "version": "2.0.0", @@ -1492,11 +1542,6 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", "dev": true }, - "symbol-observable": { - "version": "1.2.0", - "from": "symbol-observable@>=1.2.0 <2.0.0", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz" - }, "tdigest": { "version": "0.1.1", "from": "tdigest@^0.1.1", diff --git a/services/docstore/package.json b/services/docstore/package.json index 5897772d4b..b0b24ce551 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -25,8 +25,8 @@ "body-parser": "~1.0.2", "coffee-script": "^1.12.7", "express": "~4.1.1", - "logger-sharelatex": "^1.6.0", - "metrics-sharelatex": "^2.1.1", + "logger-sharelatex": "^1.7.0", + "metrics-sharelatex": "^2.2.0", "mongojs": "2.4.0", "settings-sharelatex": "^1.1.0", "underscore": "~1.6.0" From 5261e1b0be80103b2f3e00fc7447699d5d37d77e Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Tue, 2 Jul 2019 12:45:54 +0100 Subject: [PATCH 198/349] Add endpoint to completely purge a document --- services/docstore/app.coffee | 1 + .../app/coffee/DocArchiveManager.coffee | 42 +++++++++++-- .../docstore/app/coffee/HttpController.coffee | 7 +++ .../docstore/app/coffee/MongoManager.coffee | 8 +++ .../coffee/DeletingDocsTests.coffee | 43 +++++++++++++ .../coffee/helpers/DocstoreClient.coffee | 6 +- .../unit/coffee/DocArchiveManagerTests.coffee | 61 +++++++++++++++++++ .../unit/coffee/HttpControllerTests.coffee | 14 +++++ .../test/unit/coffee/MongoManagerTests.coffee | 12 ++++ 9 files changed, 188 insertions(+), 6 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 67fc7a14c9..e75cb1547f 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -42,6 +42,7 @@ app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.post '/project/:project_id/archive', HttpController.archiveAllDocs app.post '/project/:project_id/unarchive', HttpController.unArchiveAllDocs +app.post '/project/:project_id/destroy', HttpController.destroyAllDocs app.get "/health_check", HttpController.healthCheck diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.coffee index 12f4b47c82..1fb6fb2657 100644 --- a/services/docstore/app/coffee/DocArchiveManager.coffee +++ b/services/docstore/app/coffee/DocArchiveManager.coffee @@ -79,11 +79,43 @@ module.exports = DocArchive = MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), mongo_doc, (err) -> return callback(err) if err? logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" - request.del options, (err, res, body)-> - if err? || res.statusCode != 204 - logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong deleting doc from aws" - return callback new Errors.NotFoundError("Error in S3 request") - callback() + DocArchive._deleteDocFromS3 project_id, doc_id, callback + + destroyAllDocs: (project_id, callback = (err) ->) -> + MongoManager.getProjectsDocs project_id, {include_deleted: true}, {_id: 1}, (err, docs) -> + if err? + logger.err err:err, project_id:project_id, "error getting project's docs" + return callback(err) + else if !docs? + return callback() + jobs = _.map docs, (doc) -> + (cb)-> + DocArchive.destroyDoc(project_id, doc._id, cb) + async.parallelLimit jobs, 5, callback + + destroyDoc: (project_id, doc_id, callback)-> + logger.log project_id: project_id, doc_id: doc_id, "removing doc from mongo and s3" + MongoManager.findDoc project_id, doc_id, {inS3: 1}, (error, doc) -> + return callback error if error? + return callback new Errors.NotFoundError("Doc not found in Mongo") unless doc? + if doc.inS3 == true + DocArchive._deleteDocFromS3 project_id, doc_id, (err) -> + return err if err? + MongoManager.destroyDoc doc_id, callback + else + MongoManager.destroyDoc doc_id, callback + + _deleteDocFromS3: (project_id, doc_id, callback) -> + try + options = DocArchive.buildS3Options(project_id+"/"+doc_id) + catch e + return callback e + options.json = true + request.del options, (err, res, body)-> + if err? || res.statusCode != 204 + logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong deleting doc from aws" + return callback new Error("Error in S3 request") + callback() _s3DocToMongoDoc: (doc, callback = (error, mongo_doc) ->) -> mongo_doc = {} diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index 7ebcc4fd44..ae2ce1670f 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -117,6 +117,13 @@ module.exports = HttpController = return next(error) if error? res.send 200 + destroyAllDocs: (req, res, next = (error) ->) -> + project_id = req.params.project_id + logger.log project_id: project_id, "destroying all docs" + DocArchive.destroyAllDocs project_id, (error) -> + return next(error) if error? + res.send 204 + healthCheck: (req, res)-> HealthChecker.check (err)-> if err? diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.coffee index 1d3d4b4a3c..3bd9eb34c5 100644 --- a/services/docstore/app/coffee/MongoManager.coffee +++ b/services/docstore/app/coffee/MongoManager.coffee @@ -72,6 +72,14 @@ module.exports = MongoManager = upsert: true }, callback + destroyDoc: (doc_id, callback) -> + db.docs.remove { + _id: ObjectId(doc_id) + }, (err) -> + return callback(err) if err? + db.docOps.remove { + doc_id: ObjectId(doc_id) + }, callback [ 'findDoc', diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee index f97a352c14..4aac25902e 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee @@ -2,6 +2,7 @@ sinon = require "sinon" chai = require("chai") chai.should() {db, ObjectId} = require "../../../app/js/mongojs" +expect = chai.expect DocstoreApp = require "./helpers/DocstoreApp" DocstoreClient = require "./helpers/DocstoreClient" @@ -40,3 +41,45 @@ describe "Deleting a doc", -> res.statusCode.should.equal 404 done() +describe "Destroying a project's documents", -> + describe "when the doc exists", -> + beforeEach (done) -> + db.docOps.insert {doc_id: ObjectId(@doc_id), version: 1}, (err) -> + return done(err) if err? + DocstoreClient.destroyAllDoc @project_id, done + + it "should remove the doc from the docs collection", (done) -> + db.docs.find _id: @doc_id, (err, docs) -> + expect(err).not.to.exist + expect(docs).to.deep.equal [] + done() + + it "should remove the docOps from the docOps collection", (done) -> + db.docOps.find doc_id: @doc_id, (err, docOps) -> + expect(err).not.to.exist + expect(docOps).to.deep.equal [] + done() + + describe "when the doc is archived", -> + beforeEach (done) -> + DocstoreClient.archiveAllDoc @project_id, (err) -> + return done(err) if err? + DocstoreClient.destroyAllDoc @project_id, done + + it "should remove the doc from the docs collection", (done) -> + db.docs.find _id: @doc_id, (err, docs) -> + expect(err).not.to.exist + expect(docs).to.deep.equal [] + done() + + it "should remove the docOps from the docOps collection", (done) -> + db.docOps.find doc_id: @doc_id, (err, docOps) -> + expect(err).not.to.exist + expect(docOps).to.deep.equal [] + done() + + it "should remove the doc contents from s3", (done) -> + DocstoreClient.getS3Doc @project_id, @doc_id, (error, res, s3_doc) => + throw error if error? + expect(res.statusCode).to.equal 404 + done() diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee index 755f12d9b0..446f99ad58 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee @@ -44,8 +44,12 @@ module.exports = DocstoreClient = archiveAllDoc: (project_id, callback = (error, res, body) ->) -> request.post { url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/archive" - }, callback + }, callback + destroyAllDoc: (project_id, callback = (error, res, body) ->) -> + request.post { + url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/destroy" + }, callback getS3Doc: (project_id, doc_id, callback = (error, res, body) ->) -> options = DocArchiveManager.buildS3Options(project_id+"/"+doc_id) diff --git a/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee index 2b9287d912..70196a4b86 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee +++ b/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee @@ -61,6 +61,22 @@ describe "DocArchiveManager", -> rev: 6 }] + @unarchivedDocs = [{ + _id: ObjectId() + lines: ["wombat", "potato", "banana"] + rev: 2 + }, { + _id: ObjectId() + lines: ["llama", "turnip", "apple"] + rev: 4 + }, { + _id: ObjectId() + lines: ["elephant", "swede", "nectarine"] + rev: 6 + }] + + @mixedDocs = @archivedDocs.concat(@unarchivedDocs) + @MongoManager = markDocAsArchived: sinon.stub().callsArgWith(2, null) upsertIntoDocCollection: sinon.stub().callsArgWith(3, null) @@ -214,6 +230,51 @@ describe "DocArchiveManager", -> @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> err.should.equal @error done() + + describe "destroyAllDocs", -> + beforeEach -> + @request.del = sinon.stub().callsArgWith(1, null, statusCode:204, {}) + @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @mixedDocs) + @MongoManager.findDoc = sinon.stub().callsArgWith(3, null, null) + @MongoManager.destroyDoc = sinon.stub().yields() + for doc in @mixedDocs + @MongoManager.findDoc.withArgs(@project_id, doc._id).callsArgWith(3, null, doc) + + it "should destroy all the docs", (done)-> + @DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null) + @DocArchiveManager.destroyAllDocs @project_id, (err)=> + for doc in @mixedDocs + @DocArchiveManager.destroyDoc.calledWith(@project_id, doc._id).should.equal true + should.not.exist err + done() + + it "should only the s3 docs from s3", (done)-> + docOpts = (doc) => + JSON.parse(JSON.stringify({ + aws: {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket}, + json: true, + timeout: 30 * 1000 + uri:"https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{doc._id}" + })) + + @DocArchiveManager.destroyAllDocs @project_id, (err)=> + expect(err).not.to.exist + + for doc in @archivedDocs + sinon.assert.calledWith(@request.del, docOpts(doc)) + for doc in @unarchivedDocs + expect(@request.del.calledWith(docOpts(doc))).to.equal false # no notCalledWith + + done() + + it "should remove the docs from mongo", (done)-> + @DocArchiveManager.destroyAllDocs @project_id, (err)=> + expect(err).not.to.exist + + for doc in @mixedDocs + sinon.assert.calledWith(@MongoManager.destroyDoc, doc._id) + + done() describe "_s3DocToMongoDoc", -> describe "with the old schema", -> diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 80ec0c64fe..362325845d 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -326,3 +326,17 @@ describe "HttpController", -> @res.send .calledWith(204) .should.equal true + + describe "destroyAllDocs", -> + beforeEach -> + @req.params = + project_id: @project_id + @DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1) + @HttpController.destroyAllDocs @req, @res, @next + + it "should destroy the docs", -> + sinon.assert.calledWith(@DocArchiveManager.destroyAllDocs, @project_id) + + it "should return 204", -> + sinon.assert.calledWith(@res.send, 204) + diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.coffee index 1a264bf0d2..842a3c8884 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.coffee +++ b/services/docstore/test/unit/coffee/MongoManagerTests.coffee @@ -110,6 +110,18 @@ describe "MongoManager", -> err.should.equal @stubbedErr done() + describe "destroyDoc", -> + beforeEach (done) -> + @db.docs.remove = sinon.stub().yields() + @db.docOps.remove = sinon.stub().yields() + @MongoManager.destroyDoc '123456789012', done + + it "should destroy the doc", -> + sinon.assert.calledWith(@db.docs.remove, {_id: ObjectId('123456789012')}) + + it "should destroy the docOps", -> + sinon.assert.calledWith(@db.docOps.remove, {doc_id: ObjectId('123456789012')}) + describe "getDocVersion", -> describe "when the doc exists", -> beforeEach -> From e1868e2b54bedd76846a20bbd43fc056b6e93437 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Wed, 31 Jul 2019 12:40:59 +0100 Subject: [PATCH 199/349] Log request on error --- services/docstore/app.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index e75cb1547f..7038c53ed7 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -50,7 +50,7 @@ app.get '/status', (req, res)-> res.send('docstore is alive') app.use (error, req, res, next) -> - logger.error err: error, "request errored" + logger.error err: error, req:req, "request errored" if error instanceof Errors.NotFoundError res.send 404 else From 03b8a1901db6438e331ac330ecd3f0dec621e4f7 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 2 Aug 2019 14:09:48 +0100 Subject: [PATCH 200/349] Account for ranges in large json payloads and add line-count limit --- services/docstore/app.coffee | 4 +- .../docstore/app/coffee/HttpController.coffee | 10 ++++ .../docstore/config/settings.defaults.coffee | 2 +- .../coffee/UpdatingDocsTests.coffee | 47 +++++++++++++++++++ .../unit/coffee/HttpControllerTests.coffee | 15 ++++++ 5 files changed, 75 insertions(+), 3 deletions(-) diff --git a/services/docstore/app.coffee b/services/docstore/app.coffee index 7038c53ed7..c32e3a6b19 100644 --- a/services/docstore/app.coffee +++ b/services/docstore/app.coffee @@ -36,8 +36,8 @@ app.get '/project/:project_id/doc', HttpController.getAllDocs app.get '/project/:project_id/ranges', HttpController.getAllRanges app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc -# Add 64kb overhead for the JSON encoding -app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: Settings.max_doc_length + 64 * 1024), HttpController.updateDoc +# Add 64kb overhead for the JSON encoding, and double the size to allow for ranges in the json payload +app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: (Settings.max_doc_length + 64 * 1024) * 2), HttpController.updateDoc app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc app.post '/project/:project_id/archive', HttpController.archiveAllDocs diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.coffee index ae2ce1670f..cec535e1cd 100644 --- a/services/docstore/app/coffee/HttpController.coffee +++ b/services/docstore/app/coffee/HttpController.coffee @@ -2,6 +2,7 @@ DocManager = require "./DocManager" logger = require "logger-sharelatex" DocArchive = require "./DocArchiveManager" HealthChecker = require "./HealthChecker" +Settings = require "settings-sharelatex" module.exports = HttpController = @@ -68,6 +69,15 @@ module.exports = HttpController = res.send 400 # Bad Request return + bodyLength = lines.reduce( + (len, line) => line.length + len + 0 + ) + if bodyLength > Settings.max_doc_length + logger.error project_id: project_id, doc_id: doc_id, bodyLength: bodyLength, "document body too large" + res.status(413).send("document body too large") + return + logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc" DocManager.updateDoc project_id, doc_id, lines, version, ranges, (error, modified, rev) -> return next(error) if error? diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.coffee index 8d8b8c74a2..e45570d3fe 100644 --- a/services/docstore/config/settings.defaults.coffee +++ b/services/docstore/config/settings.defaults.coffee @@ -28,4 +28,4 @@ if process.env['AWS_ACCESS_KEY_ID']? and process.env['AWS_SECRET_ACCESS_KEY']? a secret: process.env['AWS_SECRET_ACCESS_KEY'] bucket: process.env['AWS_BUCKET'] -module.exports = Settings \ No newline at end of file +module.exports = Settings diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee index 4d567e8f4c..2b916a3a83 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee @@ -176,3 +176,50 @@ describe "Applying updates to a doc", -> DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => doc.lines.should.deep.equal @largeLines done() + + describe "when there is a large json payload", -> + beforeEach (done) -> + line = new Array(1025).join("x") # 1kb + @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1kb + @originalRanges.padding = Array.apply(null, Array(2049)).map(() -> line) # 2mb + 1kb + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, @res, @body) => + done() + + it "should return modified = true", -> + @body.modified.should.equal true + + it "should update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @largeLines + done() + + describe "when the document body is too large", -> + beforeEach (done) -> + line = new Array(1025).join("x") # 1kb + @largeLines = Array.apply(null, Array(2049)).map(() -> line) # 2mb + 1kb + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, @res, @body) => + done() + + it "should return 413", -> + @res.statusCode.should.equal 413 + + it "should report body too large", -> + @res.body.should.equal 'document body too large' + + it "should not update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + done() + + describe "when the json payload is too large", -> + beforeEach (done) -> + line = new Array(1025).join("x") # 1kb + @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1kb + @originalRanges.padding = Array.apply(null, Array(4096)).map(() -> line) # 4mb + DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, @res, @body) => + done() + + it "should not update the doc in the API", (done) -> + DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => + doc.lines.should.deep.equal @originalLines + done() diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.coffee index 362325845d..3b7ffbbe8d 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.coffee +++ b/services/docstore/test/unit/coffee/HttpControllerTests.coffee @@ -15,6 +15,7 @@ describe "HttpController", -> "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } "./HealthChecker": {} @res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() } + @res.status = sinon.stub().returns(@res) @req = { query:{}} @next = sinon.stub() @project_id = "mock-project-id" @@ -292,6 +293,20 @@ describe "HttpController", -> .calledWith(400) .should.equal true + describe "when the doc body is too large", -> + beforeEach -> + @req.body = + lines: @lines = Array(2049).fill('a'.repeat(1024)) + version: @version = 42 + ranges: @ranges = { changes: "mock" } + @HttpController.updateDoc @req, @res, @next + + it "should return a 413 (too large) response", -> + sinon.assert.calledWith(@res.status, 413) + + it "should report that the document body is too large", -> + sinon.assert.calledWith(@res.send, "document body too large") + describe "deleteDoc", -> beforeEach -> @req.params = From 67735bb2db0b39bf8deada98a63421c0b4aec62a Mon Sep 17 00:00:00 2001 From: Shane Kilkelly <shane.kilkelly@overleaf.com> Date: Fri, 27 Sep 2019 16:22:15 +0100 Subject: [PATCH 201/349] Update to node 10, and move to package-lock.json In this case, the npm-shrinkwrap file was using the old v0 format, and npm needed to effectively re-write the entire file. --- services/docstore/Dockerfile | 4 +- services/docstore/docker-compose.yml | 4 +- services/docstore/npm-shrinkwrap.json | 1673 ------------------ services/docstore/package-lock.json | 2315 +++++++++++++++++++++++++ 4 files changed, 2318 insertions(+), 1678 deletions(-) delete mode 100644 services/docstore/npm-shrinkwrap.json create mode 100644 services/docstore/package-lock.json diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 5103947c33..7656cf4526 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -1,4 +1,4 @@ -FROM node:6.14.1 as app +FROM node:10.16.3 as app WORKDIR /app @@ -12,7 +12,7 @@ COPY . /app RUN npm run compile:all -FROM node:6.14.1 +FROM node:10.16.3 COPY --from=app /app /app diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index ed252891e8..5e5edbd4ff 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -7,7 +7,7 @@ version: "2" services: test_unit: - image: node:6.14.1 + image: node:10.16.3 volumes: - .:/app working_dir: /app @@ -54,5 +54,3 @@ services: mongo: image: mongo:3.4 - - diff --git a/services/docstore/npm-shrinkwrap.json b/services/docstore/npm-shrinkwrap.json deleted file mode 100644 index 41b289b9c5..0000000000 --- a/services/docstore/npm-shrinkwrap.json +++ /dev/null @@ -1,1673 +0,0 @@ -{ - "name": "docstore-sharelatex", - "version": "0.1.2", - "dependencies": { - "@google-cloud/common": { - "version": "0.32.1", - "from": "@google-cloud/common@>=0.32.0 <0.33.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz" - }, - "@google-cloud/debug-agent": { - "version": "3.2.0", - "from": "@google-cloud/debug-agent@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-3.2.0.tgz", - "dependencies": { - "coffeescript": { - "version": "2.4.1", - "from": "coffeescript@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.4.1.tgz" - }, - "semver": { - "version": "6.1.1", - "from": "semver@>=6.0.0 <7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz" - } - } - }, - "@google-cloud/profiler": { - "version": "0.2.3", - "from": "@google-cloud/profiler@>=0.2.3 <0.3.0", - "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-0.2.3.tgz", - "dependencies": { - "@google-cloud/common": { - "version": "0.26.2", - "from": "@google-cloud/common@>=0.26.0 <0.27.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.26.2.tgz" - }, - "@google-cloud/promisify": { - "version": "0.3.1", - "from": "@google-cloud/promisify@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz" - }, - "arrify": { - "version": "1.0.1", - "from": "arrify@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz" - }, - "gcp-metadata": { - "version": "0.9.3", - "from": "gcp-metadata@>=0.9.0 <0.10.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz" - }, - "google-auth-library": { - "version": "2.0.2", - "from": "google-auth-library@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.2.tgz", - "dependencies": { - "gcp-metadata": { - "version": "0.7.0", - "from": "gcp-metadata@>=0.7.0 <0.8.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz" - } - } - }, - "through2": { - "version": "3.0.1", - "from": "through2@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz" - } - } - }, - "@google-cloud/projectify": { - "version": "0.3.3", - "from": "@google-cloud/projectify@>=0.3.3 <0.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz" - }, - "@google-cloud/promisify": { - "version": "0.4.0", - "from": "@google-cloud/promisify@>=0.4.0 <0.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz" - }, - "@google-cloud/trace-agent": { - "version": "3.6.1", - "from": "@google-cloud/trace-agent@>=3.2.0 <4.0.0", - "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.6.1.tgz", - "dependencies": { - "methods": { - "version": "1.1.2", - "from": "methods@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" - }, - "semver": { - "version": "6.1.1", - "from": "semver@^6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz" - }, - "uuid": { - "version": "3.3.2", - "from": "uuid@^3.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" - } - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "from": "@protobufjs/aspromise@>=1.1.2 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "from": "@protobufjs/base64@>=1.1.2 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "from": "@protobufjs/codegen@>=2.0.4 <3.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "from": "@protobufjs/eventemitter@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "from": "@protobufjs/fetch@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz" - }, - "@protobufjs/float": { - "version": "1.0.2", - "from": "@protobufjs/float@>=1.0.2 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "from": "@protobufjs/inquire@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz" - }, - "@protobufjs/path": { - "version": "1.1.2", - "from": "@protobufjs/path@>=1.1.2 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "from": "@protobufjs/pool@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "from": "@protobufjs/utf8@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz" - }, - "@sindresorhus/is": { - "version": "0.15.0", - "from": "@sindresorhus/is@>=0.15.0 <0.16.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.15.0.tgz" - }, - "@sinonjs/formatio": { - "version": "2.0.0", - "from": "@sinonjs/formatio@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "dev": true - }, - "@types/caseless": { - "version": "0.12.2", - "from": "@types/caseless@*", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz" - }, - "@types/console-log-level": { - "version": "1.4.0", - "from": "@types/console-log-level@>=1.4.0 <2.0.0", - "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz" - }, - "@types/duplexify": { - "version": "3.6.0", - "from": "@types/duplexify@>=3.5.0 <4.0.0", - "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz" - }, - "@types/form-data": { - "version": "2.2.1", - "from": "@types/form-data@*", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz" - }, - "@types/long": { - "version": "4.0.0", - "from": "@types/long@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz" - }, - "@types/node": { - "version": "12.0.8", - "from": "@types/node@*", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz" - }, - "@types/request": { - "version": "2.48.1", - "from": "@types/request@>=2.47.0 <3.0.0", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz" - }, - "@types/semver": { - "version": "5.5.0", - "from": "@types/semver@>=5.5.0 <6.0.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz" - }, - "@types/tough-cookie": { - "version": "2.3.5", - "from": "@types/tough-cookie@*", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz" - }, - "abort-controller": { - "version": "3.0.0", - "from": "abort-controller@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" - }, - "accepts": { - "version": "1.0.1", - "from": "accepts@1.0.1", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz" - }, - "acorn": { - "version": "6.1.1", - "from": "acorn@>=6.0.0 <7.0.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz" - }, - "agent-base": { - "version": "4.3.0", - "from": "agent-base@>=4.1.0 <5.0.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz" - }, - "ajv": { - "version": "6.10.0", - "from": "ajv@>=6.5.5 <7.0.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz" - }, - "arrify": { - "version": "2.0.1", - "from": "arrify@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz" - }, - "asn1": { - "version": "0.1.11", - "from": "asn1@0.1.11", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.1.5", - "from": "assert-plus@>=0.1.5 <0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "dev": true, - "optional": true - }, - "assertion-error": { - "version": "1.0.0", - "from": "assertion-error@1.0.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "dev": true - }, - "async": { - "version": "0.8.0", - "from": "async@>=0.8.0 <0.9.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz" - }, - "async-listener": { - "version": "0.6.10", - "from": "async-listener@>=0.6.0 <0.7.0", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz" - }, - "asynckit": { - "version": "0.4.0", - "from": "asynckit@>=0.4.0 <0.5.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" - }, - "aws-sign2": { - "version": "0.5.0", - "from": "aws-sign2@>=0.5.0 <0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.8.0", - "from": "aws4@>=1.8.0 <2.0.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz" - }, - "axios": { - "version": "0.18.1", - "from": "axios@>=0.18.0 <0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz" - }, - "balanced-match": { - "version": "1.0.0", - "from": "balanced-match@^1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz" - }, - "base64-js": { - "version": "1.3.0", - "from": "base64-js@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz" - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "from": "bcrypt-pbkdf@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" - }, - "bignumber.js": { - "version": "7.2.1", - "from": "bignumber.js@>=7.0.0 <8.0.0", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz" - }, - "bindings": { - "version": "1.5.0", - "from": "bindings@>=1.2.1 <2.0.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz" - }, - "bintrees": { - "version": "1.0.1", - "from": "bintrees@1.0.1", - "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz" - }, - "body-parser": { - "version": "1.0.2", - "from": "body-parser@>=1.0.2 <1.1.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz" - }, - "boom": { - "version": "0.4.2", - "from": "boom@>=0.4.0 <0.5.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "from": "brace-expansion@^1.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - }, - "browser-stdout": { - "version": "1.3.0", - "from": "browser-stdout@1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "dev": true - }, - "bson": { - "version": "1.0.6", - "from": "bson@>=1.0.4 <1.1.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz" - }, - "buffer-crc32": { - "version": "0.2.1", - "from": "buffer-crc32@0.2.1", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz" - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "from": "buffer-equal-constant-time@1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" - }, - "buffer-shims": { - "version": "1.0.0", - "from": "buffer-shims@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz" - }, - "builtin-modules": { - "version": "3.1.0", - "from": "builtin-modules@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz" - }, - "bunyan": { - "version": "0.22.3", - "from": "bunyan@>=0.22.3 <0.23.0", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", - "dev": true - }, - "bytes": { - "version": "1.0.0", - "from": "bytes@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz" - }, - "caseless": { - "version": "0.12.0", - "from": "caseless@>=0.12.0 <0.13.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" - }, - "chai": { - "version": "1.9.2", - "from": "chai@>=1.9.1 <1.10.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", - "dev": true - }, - "coffee-script": { - "version": "1.12.7", - "from": "coffee-script@>=1.7.1 <2.0.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz" - }, - "combined-stream": { - "version": "0.0.7", - "from": "combined-stream@>=0.0.4 <0.1.0", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "from": "concat-map@0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - }, - "console-log-level": { - "version": "1.4.1", - "from": "console-log-level@>=1.4.0 <2.0.0", - "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz" - }, - "continuation-local-storage": { - "version": "3.2.1", - "from": "continuation-local-storage@>=3.2.1 <4.0.0", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz" - }, - "cookie": { - "version": "0.1.2", - "from": "cookie@0.1.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz" - }, - "cookie-signature": { - "version": "1.0.3", - "from": "cookie-signature@1.0.3", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz" - }, - "core-util-is": { - "version": "1.0.2", - "from": "core-util-is@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" - }, - "cryptiles": { - "version": "0.2.2", - "from": "cryptiles@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "dev": true, - "optional": true - }, - "ctype": { - "version": "0.5.3", - "from": "ctype@0.5.3", - "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "dev": true, - "optional": true - }, - "dashdash": { - "version": "1.14.1", - "from": "dashdash@>=1.12.0 <2.0.0", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@^1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "debug": { - "version": "0.8.1", - "from": "debug@>=0.7.3 <1.0.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz" - }, - "deep-eql": { - "version": "0.1.3", - "from": "deep-eql@0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "dev": true - }, - "delay": { - "version": "4.3.0", - "from": "delay@>=4.0.1 <5.0.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz" - }, - "delayed-stream": { - "version": "0.0.5", - "from": "delayed-stream@0.0.5", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "dev": true, - "optional": true - }, - "dtrace-provider": { - "version": "0.2.8", - "from": "dtrace-provider@0.2.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", - "dev": true, - "optional": true - }, - "duplexify": { - "version": "3.7.1", - "from": "duplexify@>=3.6.0 <4.0.0", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz" - }, - "each-series": { - "version": "1.0.0", - "from": "each-series@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz" - }, - "ecc-jsbn": { - "version": "0.1.2", - "from": "ecc-jsbn@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "from": "ecdsa-sig-formatter@1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" - }, - "emitter-listener": { - "version": "1.1.2", - "from": "emitter-listener@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz" - }, - "end-of-stream": { - "version": "1.4.1", - "from": "end-of-stream@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz" - }, - "ent": { - "version": "2.2.0", - "from": "ent@>=2.2.0 <3.0.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz" - }, - "es6-promise": { - "version": "3.2.1", - "from": "es6-promise@3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz" - }, - "es6-promisify": { - "version": "5.0.0", - "from": "es6-promisify@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "dependencies": { - "es6-promise": { - "version": "4.2.8", - "from": "es6-promise@>=4.0.3 <5.0.0", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz" - } - } - }, - "escape-html": { - "version": "1.0.1", - "from": "escape-html@1.0.1", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz" - }, - "escape-string-regexp": { - "version": "1.0.5", - "from": "escape-string-regexp@1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "from": "event-target-shim@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" - }, - "express": { - "version": "4.1.2", - "from": "express@>=4.1.1 <4.2.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.1.2.tgz" - }, - "extend": { - "version": "3.0.2", - "from": "extend@>=3.0.1 <4.0.0", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" - }, - "extsprintf": { - "version": "1.3.0", - "from": "extsprintf@1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" - }, - "fast-deep-equal": { - "version": "2.0.1", - "from": "fast-deep-equal@>=2.0.1 <3.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz" - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "from": "fast-json-stable-stringify@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz" - }, - "fast-text-encoding": { - "version": "1.0.0", - "from": "fast-text-encoding@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz" - }, - "file-uri-to-path": { - "version": "1.0.0", - "from": "file-uri-to-path@1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz" - }, - "findit2": { - "version": "2.2.3", - "from": "findit2@>=2.2.3 <3.0.0", - "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz" - }, - "follow-redirects": { - "version": "1.5.10", - "from": "follow-redirects@1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "dependencies": { - "debug": { - "version": "3.1.0", - "from": "debug@3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz" - } - } - }, - "forever-agent": { - "version": "0.5.2", - "from": "forever-agent@>=0.5.0 <0.6.0", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "dev": true - }, - "form-data": { - "version": "0.1.4", - "from": "form-data@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "dev": true, - "optional": true, - "dependencies": { - "async": { - "version": "0.9.2", - "from": "async@>=0.9.0 <0.10.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "dev": true, - "optional": true - } - } - }, - "formatio": { - "version": "1.2.0", - "from": "formatio@1.2.0", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "dev": true - }, - "fresh": { - "version": "0.2.2", - "from": "fresh@0.2.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz" - }, - "fs.realpath": { - "version": "1.0.0", - "from": "fs.realpath@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "dev": true - }, - "gaxios": { - "version": "1.8.4", - "from": "gaxios@>=1.2.1 <2.0.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz" - }, - "gcp-metadata": { - "version": "1.0.0", - "from": "gcp-metadata@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz" - }, - "getpass": { - "version": "0.1.7", - "from": "getpass@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@^1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "glob": { - "version": "6.0.4", - "from": "glob@^6.0.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "optional": true - }, - "google-auth-library": { - "version": "3.1.2", - "from": "google-auth-library@>=3.1.1 <4.0.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz" - }, - "google-p12-pem": { - "version": "1.0.4", - "from": "google-p12-pem@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz" - }, - "gtoken": { - "version": "2.3.3", - "from": "gtoken@>=2.3.2 <3.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", - "dependencies": { - "mime": { - "version": "2.4.4", - "from": "mime@>=2.2.0 <3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz" - } - } - }, - "har-schema": { - "version": "2.0.0", - "from": "har-schema@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" - }, - "har-validator": { - "version": "5.1.3", - "from": "har-validator@>=5.1.0 <5.2.0", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz" - }, - "has-flag": { - "version": "2.0.0", - "from": "has-flag@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "dev": true - }, - "hawk": { - "version": "1.0.0", - "from": "hawk@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", - "dev": true, - "optional": true - }, - "he": { - "version": "1.1.1", - "from": "he@1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "dev": true - }, - "hex2dec": { - "version": "1.1.2", - "from": "hex2dec@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz" - }, - "hoek": { - "version": "0.9.1", - "from": "hoek@>=0.9.0 <0.10.0", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "dev": true - }, - "http-signature": { - "version": "0.10.1", - "from": "http-signature@>=0.10.0 <0.11.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "dev": true, - "optional": true - }, - "https-proxy-agent": { - "version": "2.2.1", - "from": "https-proxy-agent@>=2.2.1 <3.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "dependencies": { - "debug": { - "version": "3.2.6", - "from": "debug@>=3.1.0 <4.0.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz" - }, - "ms": { - "version": "2.1.2", - "from": "ms@>=2.1.1 <3.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - } - } - }, - "inflight": { - "version": "1.0.6", - "from": "inflight@^1.0.4", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - }, - "inherits": { - "version": "2.0.3", - "from": "inherits@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz" - }, - "is": { - "version": "3.3.0", - "from": "is@>=3.2.0 <4.0.0", - "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz" - }, - "is-buffer": { - "version": "2.0.3", - "from": "is-buffer@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz" - }, - "is-typedarray": { - "version": "1.0.0", - "from": "is-typedarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" - }, - "isarray": { - "version": "1.0.0", - "from": "isarray@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - }, - "isstream": { - "version": "0.1.2", - "from": "isstream@>=0.1.2 <0.2.0", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" - }, - "jsbn": { - "version": "0.1.1", - "from": "jsbn@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" - }, - "json-bigint": { - "version": "0.3.0", - "from": "json-bigint@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz" - }, - "json-schema": { - "version": "0.2.3", - "from": "json-schema@0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz" - }, - "json-schema-traverse": { - "version": "0.4.1", - "from": "json-schema-traverse@>=0.4.1 <0.5.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" - }, - "json-stringify-safe": { - "version": "5.0.1", - "from": "json-stringify-safe@>=5.0.0 <5.1.0", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" - }, - "jsprim": { - "version": "1.4.1", - "from": "jsprim@>=1.2.2 <2.0.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "just-extend": { - "version": "1.1.27", - "from": "just-extend@>=1.1.27 <2.0.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", - "dev": true - }, - "jwa": { - "version": "1.4.1", - "from": "jwa@>=1.4.1 <2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz" - }, - "jws": { - "version": "3.2.2", - "from": "jws@>=3.1.5 <4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz" - }, - "lodash.pickby": { - "version": "4.6.0", - "from": "lodash.pickby@>=4.6.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz" - }, - "logger-sharelatex": { - "version": "1.7.0", - "from": "logger-sharelatex@1.7.0", - "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.7.0.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - }, - "aws-sign2": { - "version": "0.7.0", - "from": "aws-sign2@>=0.7.0 <0.8.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" - }, - "bunyan": { - "version": "1.8.12", - "from": "bunyan@1.8.12", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz" - }, - "combined-stream": { - "version": "1.0.8", - "from": "combined-stream@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" - }, - "delayed-stream": { - "version": "1.0.0", - "from": "delayed-stream@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" - }, - "dtrace-provider": { - "version": "0.8.7", - "from": "dtrace-provider@>=0.8.0 <0.9.0", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz", - "optional": true - }, - "forever-agent": { - "version": "0.6.1", - "from": "forever-agent@>=0.6.1 <0.7.0", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" - }, - "form-data": { - "version": "2.3.3", - "from": "form-data@>=2.3.2 <2.4.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" - }, - "http-signature": { - "version": "1.2.0", - "from": "http-signature@>=1.2.0 <1.3.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" - }, - "oauth-sign": { - "version": "0.9.0", - "from": "oauth-sign@>=0.9.0 <0.10.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" - }, - "qs": { - "version": "6.5.2", - "from": "qs@>=6.5.2 <6.6.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz" - }, - "request": { - "version": "2.88.0", - "from": "request@>=2.88.0 <3.0.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz" - }, - "tough-cookie": { - "version": "2.4.3", - "from": "tough-cookie@>=2.4.3 <2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz" - }, - "tunnel-agent": { - "version": "0.6.0", - "from": "tunnel-agent@>=0.6.0 <0.7.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" - }, - "uuid": { - "version": "3.3.2", - "from": "uuid@>=3.3.2 <4.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" - } - } - }, - "lolex": { - "version": "2.6.0", - "from": "lolex@>=2.1.2 <3.0.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.6.0.tgz", - "dev": true - }, - "long": { - "version": "4.0.0", - "from": "long@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz" - }, - "lru-cache": { - "version": "5.1.1", - "from": "lru-cache@>=5.0.0 <6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" - }, - "lsmod": { - "version": "1.0.0", - "from": "lsmod@1.0.0", - "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz" - }, - "lynx": { - "version": "0.1.1", - "from": "lynx@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz" - }, - "merge-descriptors": { - "version": "0.0.2", - "from": "merge-descriptors@0.0.2", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz" - }, - "mersenne": { - "version": "0.0.4", - "from": "mersenne@>=0.0.3 <0.1.0", - "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz" - }, - "methods": { - "version": "0.1.0", - "from": "methods@0.1.0", - "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz" - }, - "metrics-sharelatex": { - "version": "2.2.0", - "from": "metrics-sharelatex@2.2.0", - "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.2.0.tgz", - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "from": "coffee-script@1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz" - } - } - }, - "mime": { - "version": "1.2.11", - "from": "mime@>=1.2.11 <1.3.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" - }, - "mime-db": { - "version": "1.40.0", - "from": "mime-db@1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz" - }, - "mime-types": { - "version": "2.1.24", - "from": "mime-types@>=2.1.19 <2.2.0", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz" - }, - "minimatch": { - "version": "3.0.4", - "from": "minimatch@2 || 3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz" - }, - "minimist": { - "version": "0.0.8", - "from": "minimist@0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" - }, - "mkdirp": { - "version": "0.5.1", - "from": "mkdirp@~0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz" - }, - "mocha": { - "version": "4.1.0", - "from": "mocha@>=4.0.1 <5.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "dev": true, - "dependencies": { - "commander": { - "version": "2.11.0", - "from": "commander@2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "dev": true - }, - "debug": { - "version": "3.1.0", - "from": "debug@3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "dev": true - }, - "diff": { - "version": "3.3.1", - "from": "diff@3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "dev": true - }, - "glob": { - "version": "7.1.2", - "from": "glob@7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "dev": true - }, - "growl": { - "version": "1.10.3", - "from": "growl@1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "dev": true - } - } - }, - "module-details-from-path": { - "version": "1.0.3", - "from": "module-details-from-path@>=1.0.3 <2.0.0", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz" - }, - "moment": { - "version": "2.24.0", - "from": "moment@>=2.10.6 <3.0.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "optional": true - }, - "mongodb": { - "version": "2.2.35", - "from": "mongodb@>=2.0.45 <3.0.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz", - "dependencies": { - "readable-stream": { - "version": "2.2.7", - "from": "readable-stream@2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz" - }, - "string_decoder": { - "version": "1.0.3", - "from": "string_decoder@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz" - } - } - }, - "mongodb-core": { - "version": "2.1.19", - "from": "mongodb-core@2.1.19", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz" - }, - "mongojs": { - "version": "2.4.0", - "from": "mongojs@2.4.0", - "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz" - }, - "ms": { - "version": "2.0.0", - "from": "ms@2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - }, - "mv": { - "version": "2.1.1", - "from": "mv@~2", - "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "optional": true - }, - "nan": { - "version": "2.12.1", - "from": "nan@>=2.0.8 <3.0.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz" - }, - "native-promise-only": { - "version": "0.8.1", - "from": "native-promise-only@>=0.8.1 <0.9.0", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "dev": true - }, - "ncp": { - "version": "2.0.0", - "from": "ncp@~2.0.0", - "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "optional": true - }, - "negotiator": { - "version": "0.4.9", - "from": "negotiator@>=0.4.0 <0.5.0", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz" - }, - "nise": { - "version": "1.3.3", - "from": "nise@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.3.tgz", - "dev": true, - "dependencies": { - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "from": "path-to-regexp@>=1.7.0 <2.0.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "dev": true - } - } - }, - "node-fetch": { - "version": "2.6.0", - "from": "node-fetch@>=2.3.0 <3.0.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz" - }, - "node-forge": { - "version": "0.8.4", - "from": "node-forge@>=0.8.0 <0.9.0", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.4.tgz" - }, - "node-uuid": { - "version": "1.4.8", - "from": "node-uuid@>=1.4.1 <1.5.0", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "dev": true - }, - "oauth-sign": { - "version": "0.3.0", - "from": "oauth-sign@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "from": "once@>=1.3.0 <2.0.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - }, - "p-limit": { - "version": "2.2.0", - "from": "p-limit@>=2.2.0 <3.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz" - }, - "p-try": { - "version": "2.2.0", - "from": "p-try@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" - }, - "parse-duration": { - "version": "0.1.1", - "from": "parse-duration@>=0.1.1 <0.2.0", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz" - }, - "parse-mongo-url": { - "version": "1.1.1", - "from": "parse-mongo-url@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz" - }, - "parse-ms": { - "version": "2.1.0", - "from": "parse-ms@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz" - }, - "parseurl": { - "version": "1.0.1", - "from": "parseurl@1.0.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz" - }, - "path-is-absolute": { - "version": "1.0.1", - "from": "path-is-absolute@^1.0.0", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - }, - "path-parse": { - "version": "1.0.6", - "from": "path-parse@>=1.0.5 <2.0.0", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz" - }, - "path-to-regexp": { - "version": "0.1.2", - "from": "path-to-regexp@0.1.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz" - }, - "performance-now": { - "version": "2.1.0", - "from": "performance-now@>=2.1.0 <3.0.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" - }, - "pify": { - "version": "4.0.1", - "from": "pify@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz" - }, - "pretty-ms": { - "version": "4.0.0", - "from": "pretty-ms@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz" - }, - "process-nextick-args": { - "version": "1.0.7", - "from": "process-nextick-args@>=1.0.6 <1.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz" - }, - "prom-client": { - "version": "11.5.1", - "from": "prom-client@>=11.1.3 <12.0.0", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.1.tgz" - }, - "protobufjs": { - "version": "6.8.8", - "from": "protobufjs@>=6.8.6 <6.9.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "dependencies": { - "@types/node": { - "version": "10.14.9", - "from": "@types/node@>=10.1.0 <11.0.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.9.tgz" - } - } - }, - "psl": { - "version": "1.1.32", - "from": "psl@>=1.1.24 <2.0.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz" - }, - "punycode": { - "version": "1.4.1", - "from": "punycode@>=1.4.1 <2.0.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz" - }, - "qs": { - "version": "0.6.6", - "from": "qs@>=0.6.6 <0.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz" - }, - "range-parser": { - "version": "1.0.0", - "from": "range-parser@1.0.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz" - }, - "raven": { - "version": "1.1.3", - "from": "raven@1.1.3", - "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", - "dependencies": { - "cookie": { - "version": "0.3.1", - "from": "cookie@0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz" - }, - "uuid": { - "version": "3.0.0", - "from": "uuid@3.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz" - } - } - }, - "raw-body": { - "version": "1.1.7", - "from": "raw-body@>=1.1.2 <1.2.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz" - }, - "readable-stream": { - "version": "2.3.6", - "from": "readable-stream@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "from": "process-nextick-args@>=2.0.0 <2.1.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz" - }, - "string_decoder": { - "version": "1.1.1", - "from": "string_decoder@>=1.1.1 <1.2.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - } - } - }, - "request": { - "version": "2.34.0", - "from": "request@>=2.34.0 <2.35.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", - "dev": true - }, - "require_optional": { - "version": "1.0.1", - "from": "require_optional@>=1.0.0 <1.1.0", - "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz" - }, - "require-in-the-middle": { - "version": "4.0.0", - "from": "require-in-the-middle@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.0.tgz", - "dependencies": { - "debug": { - "version": "4.1.1", - "from": "debug@>=4.1.1 <5.0.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz" - }, - "ms": { - "version": "2.1.2", - "from": "ms@^2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - } - } - }, - "require-like": { - "version": "0.1.2", - "from": "require-like@0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "dev": true - }, - "resolve": { - "version": "1.11.0", - "from": "resolve@>=1.10.0 <2.0.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz" - }, - "resolve-from": { - "version": "2.0.0", - "from": "resolve-from@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz" - }, - "retry-axios": { - "version": "0.3.2", - "from": "retry-axios@>=0.3.2 <0.4.0", - "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz" - }, - "retry-request": { - "version": "4.0.0", - "from": "retry-request@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.0.0.tgz" - }, - "rimraf": { - "version": "2.4.5", - "from": "rimraf@~2.4.0", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "optional": true - }, - "safe-buffer": { - "version": "5.1.2", - "from": "safe-buffer@>=5.1.0 <5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - }, - "safe-json-stringify": { - "version": "1.2.0", - "from": "safe-json-stringify@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "from": "safer-buffer@>=2.0.2 <3.0.0", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - }, - "samsam": { - "version": "1.3.0", - "from": "samsam@>=1.1.3 <2.0.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "dev": true - }, - "sandboxed-module": { - "version": "0.3.0", - "from": "sandboxed-module@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", - "dev": true, - "dependencies": { - "stack-trace": { - "version": "0.0.6", - "from": "stack-trace@0.0.6", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", - "dev": true - } - } - }, - "semver": { - "version": "5.5.0", - "from": "semver@>=5.1.0 <6.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz" - }, - "send": { - "version": "0.3.0", - "from": "send@0.3.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", - "dependencies": { - "debug": { - "version": "0.8.0", - "from": "debug@0.8.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz" - } - } - }, - "serve-static": { - "version": "1.1.0", - "from": "serve-static@1.1.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz" - }, - "settings-sharelatex": { - "version": "1.1.0", - "from": "settings-sharelatex@1.1.0", - "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "from": "coffee-script@1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz" - } - } - }, - "shimmer": { - "version": "1.2.1", - "from": "shimmer@>=1.2.0 <2.0.0", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz" - }, - "sinon": { - "version": "3.2.1", - "from": "sinon@>=3.2.1 <3.3.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", - "dev": true, - "dependencies": { - "diff": { - "version": "3.5.0", - "from": "diff@>=3.1.0 <4.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "from": "isarray@0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "dev": true - }, - "path-to-regexp": { - "version": "1.7.0", - "from": "path-to-regexp@>=1.7.0 <2.0.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "dev": true - }, - "type-detect": { - "version": "4.0.8", - "from": "type-detect@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "dev": true - } - } - }, - "sntp": { - "version": "0.2.4", - "from": "sntp@>=0.2.0 <0.3.0", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "dev": true, - "optional": true - }, - "source-map": { - "version": "0.6.1", - "from": "source-map@>=0.6.1 <0.7.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - }, - "split": { - "version": "1.0.1", - "from": "split@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz" - }, - "sshpk": { - "version": "1.16.1", - "from": "sshpk@>=1.7.0 <2.0.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "dependencies": { - "asn1": { - "version": "0.2.4", - "from": "asn1@>=0.2.3 <0.3.0", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz" - }, - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@^1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "stack-trace": { - "version": "0.0.9", - "from": "stack-trace@0.0.9", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz" - }, - "statsd-parser": { - "version": "0.0.4", - "from": "statsd-parser@>=0.0.4 <0.1.0", - "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz" - }, - "stream-shift": { - "version": "1.0.0", - "from": "stream-shift@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz" - }, - "string_decoder": { - "version": "0.10.31", - "from": "string_decoder@>=0.10.0 <0.11.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - }, - "supports-color": { - "version": "4.4.0", - "from": "supports-color@4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "dev": true - }, - "tdigest": { - "version": "0.1.1", - "from": "tdigest@^0.1.1", - "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz" - }, - "teeny-request": { - "version": "3.11.3", - "from": "teeny-request@>=3.6.0 <4.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "dependencies": { - "uuid": { - "version": "3.3.2", - "from": "uuid@>=3.3.2 <4.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz" - } - } - }, - "text-encoding": { - "version": "0.6.4", - "from": "text-encoding@0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "dev": true - }, - "through": { - "version": "2.3.8", - "from": "through@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - }, - "through2": { - "version": "2.0.5", - "from": "through2@>=2.0.3 <3.0.0", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz" - }, - "thunky": { - "version": "0.1.0", - "from": "thunky@>=0.1.0 <0.2.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz" - }, - "to-mongodb-core": { - "version": "2.0.0", - "from": "to-mongodb-core@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz" - }, - "tough-cookie": { - "version": "2.3.4", - "from": "tough-cookie@>=0.12.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "dev": true, - "optional": true - }, - "tunnel-agent": { - "version": "0.3.0", - "from": "tunnel-agent@>=0.3.0 <0.4.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", - "dev": true, - "optional": true - }, - "tweetnacl": { - "version": "0.14.5", - "from": "tweetnacl@>=0.14.0 <0.15.0", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" - }, - "type-detect": { - "version": "0.1.1", - "from": "type-detect@0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "dev": true - }, - "type-is": { - "version": "1.1.0", - "from": "type-is@>=1.1.0 <1.2.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz" - }, - "underscore": { - "version": "1.6.0", - "from": "underscore@>=1.6.0 <1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz" - }, - "uri-js": { - "version": "4.2.2", - "from": "uri-js@>=4.2.2 <5.0.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "dependencies": { - "punycode": { - "version": "2.1.1", - "from": "punycode@>=2.1.0 <3.0.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "from": "util-deprecate@>=1.0.1 <1.1.0", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - }, - "utils-merge": { - "version": "1.0.0", - "from": "utils-merge@1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz" - }, - "verror": { - "version": "1.10.0", - "from": "verror@1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "from": "assert-plus@^1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" - } - } - }, - "wrappy": { - "version": "1.0.2", - "from": "wrappy@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - }, - "xtend": { - "version": "4.0.1", - "from": "xtend@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" - }, - "yallist": { - "version": "3.0.3", - "from": "yallist@>=3.0.2 <4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz" - } - } -} diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json new file mode 100644 index 0000000000..9eab5b1bd3 --- /dev/null +++ b/services/docstore/package-lock.json @@ -0,0 +1,2315 @@ +{ + "name": "docstore-sharelatex", + "version": "0.1.2", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@google-cloud/common": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz", + "integrity": "sha512-bLdPzFvvBMtVkwsoBtygE9oUm3yrNmPa71gvOgucYI/GqvNP2tb6RYsDHPq98kvignhcgHGDI5wyNgxaCo8bKQ==", + "requires": { + "@google-cloud/projectify": "^0.3.3", + "@google-cloud/promisify": "^0.4.0", + "@types/request": "^2.48.1", + "arrify": "^2.0.0", + "duplexify": "^3.6.0", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^3.1.1", + "pify": "^4.0.1", + "retry-request": "^4.0.0", + "teeny-request": "^3.11.3" + } + }, + "@google-cloud/debug-agent": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-3.2.0.tgz", + "integrity": "sha512-fP87kYbS6aeDna08BivwQ1J260mwJGchRi99XdWCgqbRwuFac8ul0OT5i2wEeDSc5QaDX8ZuWQQ0igZvh1rTyQ==", + "requires": { + "@google-cloud/common": "^0.32.0", + "@sindresorhus/is": "^0.15.0", + "acorn": "^6.0.0", + "coffeescript": "^2.0.0", + "console-log-level": "^1.4.0", + "extend": "^3.0.1", + "findit2": "^2.2.3", + "gcp-metadata": "^1.0.0", + "lodash.pickby": "^4.6.0", + "p-limit": "^2.2.0", + "pify": "^4.0.1", + "semver": "^6.0.0", + "source-map": "^0.6.1", + "split": "^1.0.0" + }, + "dependencies": { + "coffeescript": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.4.1.tgz", + "integrity": "sha512-34GV1aHrsMpTaO3KfMJL40ZNuvKDR/g98THHnE9bQj8HjMaZvSrLik99WWqyMhRtbe8V5hpx5iLgdcSvM/S2wg==" + }, + "semver": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", + "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==" + } + } + }, + "@google-cloud/profiler": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-0.2.3.tgz", + "integrity": "sha512-rNvtrFtIebIxZEJ/O0t8n7HciZGIXBo8DvHxWqAmsCaeLvkTtsaL6HmPkwxrNQ1IhbYWAxF+E/DwCiHyhKmgTg==", + "requires": { + "@google-cloud/common": "^0.26.0", + "@types/console-log-level": "^1.4.0", + "@types/semver": "^5.5.0", + "bindings": "^1.2.1", + "console-log-level": "^1.4.0", + "delay": "^4.0.1", + "extend": "^3.0.1", + "gcp-metadata": "^0.9.0", + "nan": "^2.11.1", + "parse-duration": "^0.1.1", + "pify": "^4.0.0", + "pretty-ms": "^4.0.0", + "protobufjs": "~6.8.6", + "semver": "^5.5.0", + "teeny-request": "^3.3.0" + }, + "dependencies": { + "@google-cloud/common": { + "version": "0.26.2", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.26.2.tgz", + "integrity": "sha512-xJ2M/q3MrUbnYZuFlpF01caAlEhAUoRn0NXp93Hn3pkFpfSOG8YfbKbpBAHvcKVbBOAKVIwPsleNtuyuabUwLQ==", + "requires": { + "@google-cloud/projectify": "^0.3.2", + "@google-cloud/promisify": "^0.3.0", + "@types/duplexify": "^3.5.0", + "@types/request": "^2.47.0", + "arrify": "^1.0.1", + "duplexify": "^3.6.0", + "ent": "^2.2.0", + "extend": "^3.0.1", + "google-auth-library": "^2.0.0", + "pify": "^4.0.0", + "retry-request": "^4.0.0", + "through2": "^3.0.0" + } + }, + "@google-cloud/promisify": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz", + "integrity": "sha512-QzB0/IMvB0eFxFK7Eqh+bfC8NLv3E9ScjWQrPOk6GgfNroxcVITdTlT8NRsRrcp5+QQJVPLkRqKG0PUdaWXmHw==" + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, + "gcp-metadata": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz", + "integrity": "sha512-caV4S84xAjENtpezLCT/GILEAF5h/bC4cNqZFmt/tjTn8t+JBtTkQrgBrJu3857YdsnlM8rxX/PMcKGtE8hUlw==", + "requires": { + "gaxios": "^1.0.2", + "json-bigint": "^0.3.0" + } + }, + "google-auth-library": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.2.tgz", + "integrity": "sha512-FURxmo1hBVmcfLauuMRKOPYAPKht3dGuI2wjeJFalDUThO0HoYVjr4yxt5cgYSFm1dgUpmN9G/poa7ceTFAIiA==", + "requires": { + "axios": "^0.18.0", + "gcp-metadata": "^0.7.0", + "gtoken": "^2.3.0", + "https-proxy-agent": "^2.2.1", + "jws": "^3.1.5", + "lru-cache": "^5.0.0", + "semver": "^5.5.0" + }, + "dependencies": { + "gcp-metadata": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz", + "integrity": "sha512-ffjC09amcDWjh3VZdkDngIo7WoluyC5Ag9PAYxZbmQLOLNI8lvPtoKTSCyU54j2gwy5roZh6sSMTfkY2ct7K3g==", + "requires": { + "axios": "^0.18.0", + "extend": "^3.0.1", + "retry-axios": "0.3.2" + } + } + } + }, + "through2": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "requires": { + "readable-stream": "2 || 3" + } + } + } + }, + "@google-cloud/projectify": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", + "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + }, + "@google-cloud/promisify": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz", + "integrity": "sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q==" + }, + "@google-cloud/trace-agent": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.6.1.tgz", + "integrity": "sha512-KDo85aPN4gSxJ7oEIOlKd7aGENZFXAM1kbIn1Ds+61gh/K1CQWSyepgJo3nUpAwH6D1ezDWV7Iaf8ueoITc8Uw==", + "requires": { + "@google-cloud/common": "^0.32.1", + "builtin-modules": "^3.0.0", + "console-log-level": "^1.4.0", + "continuation-local-storage": "^3.2.1", + "extend": "^3.0.0", + "gcp-metadata": "^1.0.0", + "hex2dec": "^1.0.1", + "is": "^3.2.0", + "methods": "^1.1.1", + "require-in-the-middle": "^4.0.0", + "semver": "^6.0.0", + "shimmer": "^1.2.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "semver": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", + "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@sindresorhus/is": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.15.0.tgz", + "integrity": "sha512-lu8BpxjAtRCAo5ifytTpCPCj99LF7o/2Myn+NXyNCBqvPYn7Pjd76AMmUB5l7XF1U6t0hcWrlEM5ESufW7wAeA==" + }, + "@sinonjs/formatio": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", + "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "dev": true, + "requires": { + "samsam": "1.3.0" + } + }, + "@types/caseless": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", + "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" + }, + "@types/console-log-level": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz", + "integrity": "sha512-x+OscEQwcx5Biair4enH7ov9W+clcqUWaZRaxn5IkT4yNWWjRr2oiYDkY/x1uXSTVZOQ2xlbFQySaQGB+VdXGQ==" + }, + "@types/duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==", + "requires": { + "@types/node": "*" + } + }, + "@types/form-data": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", + "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, + "@types/node": { + "version": "12.0.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz", + "integrity": "sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg==" + }, + "@types/request": { + "version": "2.48.1", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", + "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", + "requires": { + "@types/caseless": "*", + "@types/form-data": "*", + "@types/node": "*", + "@types/tough-cookie": "*" + } + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/tough-cookie": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", + "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" + }, + "abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "requires": { + "event-target-shim": "^5.0.0" + } + }, + "accepts": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz", + "integrity": "sha1-weBtYT5iRrqHRnjW2bkjibfOMQw=", + "requires": { + "mime": "~1.2.11", + "negotiator": "~0.4.0" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + }, + "asn1": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", + "dev": true, + "optional": true + }, + "assert-plus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", + "dev": true, + "optional": true + }, + "assertion-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "dev": true + }, + "async": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz", + "integrity": "sha1-7mXsdymML/FFa8RBigUtDwZDURI=" + }, + "async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "requires": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", + "dev": true, + "optional": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + }, + "axios": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", + "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bintrees": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" + }, + "body-parser": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz", + "integrity": "sha1-NGFHmjJ4/gD8rr7DMUu1T8T3tHw=", + "requires": { + "qs": "~0.6.6", + "raw-body": "~1.1.2", + "type-is": "~1.1.0" + } + }, + "boom": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", + "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", + "dev": true, + "optional": true, + "requires": { + "hoek": "0.9.x" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "bson": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz", + "integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ==" + }, + "buffer-crc32": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz", + "integrity": "sha1-vj5TgvwCttYySVasGvmKqYsIU0w=" + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "buffer-shims": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + }, + "builtin-modules": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", + "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" + }, + "bunyan": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", + "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", + "dev": true, + "requires": { + "dtrace-provider": "0.2.8", + "mv": "~2" + } + }, + "bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", + "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chai": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", + "integrity": "sha1-Pxog+CsLnXQ3V30k1vErGmnTtZA=", + "dev": true, + "requires": { + "assertion-error": "1.0.0", + "deep-eql": "0.1.3" + } + }, + "coffee-script": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", + "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" + }, + "combined-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "dev": true, + "optional": true, + "requires": { + "delayed-stream": "0.0.5" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-log-level": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", + "integrity": "sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==" + }, + "continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "requires": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "cookie": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", + "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" + }, + "cookie-signature": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", + "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cryptiles": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", + "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", + "dev": true, + "optional": true, + "requires": { + "boom": "0.4.x" + } + }, + "ctype": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", + "dev": true, + "optional": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "debug": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz", + "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=" + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + } + }, + "delay": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz", + "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==" + }, + "delayed-stream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", + "dev": true, + "optional": true + }, + "dtrace-provider": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", + "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", + "dev": true, + "optional": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "requires": { + "shimmer": "^1.2.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "requires": { + "once": "^1.4.0" + } + }, + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + }, + "es6-promise": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + }, + "dependencies": { + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + } + } + }, + "escape-html": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", + "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "express": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.1.2.tgz", + "integrity": "sha1-yx0RQlVximWhvNaVgDbvcgxSlIc=", + "requires": { + "accepts": "1.0.1", + "buffer-crc32": "0.2.1", + "cookie": "0.1.2", + "cookie-signature": "1.0.3", + "debug": ">= 0.7.3 < 1", + "escape-html": "1.0.1", + "fresh": "0.2.2", + "merge-descriptors": "0.0.2", + "methods": "0.1.0", + "parseurl": "1.0.1", + "path-to-regexp": "0.1.2", + "qs": "0.6.6", + "range-parser": "1.0.0", + "send": "0.3.0", + "serve-static": "1.1.0", + "type-is": "1.1.0", + "utils-merge": "1.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, + "fast-text-encoding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", + "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "findit2": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", + "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, + "forever-agent": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", + "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=", + "dev": true + }, + "form-data": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", + "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", + "dev": true, + "optional": true, + "requires": { + "async": "~0.9.0", + "combined-stream": "~0.0.4", + "mime": "~1.2.11" + }, + "dependencies": { + "async": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true, + "optional": true + } + } + }, + "formatio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "dev": true, + "requires": { + "samsam": "1.x" + } + }, + "fresh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", + "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "gaxios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", + "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.3.0" + } + }, + "gcp-metadata": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz", + "integrity": "sha512-Q6HrgfrCQeEircnNP3rCcEgiDv7eF9+1B+1MMgpE190+/+0mjQR8PxeOaRgxZWmdDAF9EIryHB9g1moPiw1SbQ==", + "requires": { + "gaxios": "^1.0.2", + "json-bigint": "^0.3.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "optional": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "google-auth-library": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz", + "integrity": "sha512-cDQMzTotwyWMrg5jRO7q0A4TL/3GWBgO7I7q5xGKNiiFf9SmGY/OJ1YsLMgI2MVHHsEGyrqYnbnmV1AE+Z6DnQ==", + "requires": { + "base64-js": "^1.3.0", + "fast-text-encoding": "^1.0.0", + "gaxios": "^1.2.1", + "gcp-metadata": "^1.0.0", + "gtoken": "^2.3.2", + "https-proxy-agent": "^2.2.1", + "jws": "^3.1.5", + "lru-cache": "^5.0.0", + "semver": "^5.5.0" + } + }, + "google-p12-pem": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", + "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", + "requires": { + "node-forge": "^0.8.0", + "pify": "^4.0.0" + } + }, + "gtoken": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", + "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "requires": { + "gaxios": "^1.0.4", + "google-p12-pem": "^1.0.0", + "jws": "^3.1.5", + "mime": "^2.2.0", + "pify": "^4.0.0" + }, + "dependencies": { + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "hawk": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", + "integrity": "sha1-uQuxaYByhUEdp//LjdJZhQLTtS0=", + "dev": true, + "optional": true, + "requires": { + "boom": "0.4.x", + "cryptiles": "0.2.x", + "hoek": "0.9.x", + "sntp": "0.2.x" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hex2dec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz", + "integrity": "sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==" + }, + "hoek": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", + "dev": true, + "optional": true + }, + "http-signature": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", + "dev": true, + "optional": true, + "requires": { + "asn1": "0.1.11", + "assert-plus": "^0.1.5", + "ctype": "0.5.3" + } + }, + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "is": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", + "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==" + }, + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-bigint": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", + "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", + "requires": { + "bignumber.js": "^7.0.0" + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "just-extend": { + "version": "1.1.27", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", + "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", + "dev": true + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" + }, + "logger-sharelatex": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.7.0.tgz", + "integrity": "sha512-9sxDGPSphOMDqUqGpOu/KxFAVcpydKggWv60g9D7++FDCxGkhLLn0kmBkDdgB00d1PadgX1CBMWKzIBpptDU/Q==", + "requires": { + "bunyan": "1.8.12", + "raven": "1.1.3", + "request": "2.88.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "bunyan": { + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", + "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "requires": { + "dtrace-provider": "~0.8", + "moment": "^2.10.6", + "mv": "~2", + "safe-json-stringify": "~1" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "dtrace-provider": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz", + "integrity": "sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ=", + "optional": true, + "requires": { + "nan": "^2.10.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "lolex": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.6.0.tgz", + "integrity": "sha512-e1UtIo1pbrIqEXib/yMjHciyqkng5lc0rrIbytgjmRgDR9+2ceNIAcwOWSgylRjoEP9VdVguCSRwnNmlbnOUwA==", + "dev": true + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "lsmod": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", + "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" + }, + "lynx": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", + "integrity": "sha1-Mxjc7xaQi4KG6Bisz9sxzXQkj50=", + "requires": { + "mersenne": "~0.0.3", + "statsd-parser": "~0.0.4" + } + }, + "merge-descriptors": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", + "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" + }, + "mersenne": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", + "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" + }, + "methods": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz", + "integrity": "sha1-M11Cnu/SG3us8unJIqjSvRSjDk8=" + }, + "metrics-sharelatex": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.2.0.tgz", + "integrity": "sha512-kjj3EdkrOJrENLFW/QHiPqBr5AbGEHeti90nMbw6sjKO2TOcuPJHT2Y66m8tqgotnMPKw+kXToRs8Rc9+0xuMQ==", + "requires": { + "@google-cloud/debug-agent": "^3.0.0", + "@google-cloud/profiler": "^0.2.3", + "@google-cloud/trace-agent": "^3.2.0", + "coffee-script": "1.6.0", + "lynx": "~0.1.1", + "prom-client": "^11.1.3", + "underscore": "~1.6.0" + }, + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + } + } + }, + "mime": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", + "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + } + } + }, + "module-details-from-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "optional": true + }, + "mongodb": { + "version": "2.2.35", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz", + "integrity": "sha512-3HGLucDg/8EeYMin3k+nFWChTA85hcYDCw1lPsWR6yV9A6RgKb24BkLiZ9ySZR+S0nfBjWoIUS7cyV6ceGx5Gg==", + "requires": { + "es6-promise": "3.2.1", + "mongodb-core": "2.1.19", + "readable-stream": "2.2.7" + }, + "dependencies": { + "readable-stream": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "requires": { + "buffer-shims": "~1.0.0", + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~1.0.0", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "mongodb-core": { + "version": "2.1.19", + "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz", + "integrity": "sha512-Jt4AtWUkpuW03kRdYGxga4O65O1UHlFfvvInslEfLlGi+zDMxbBe3J2NVmN9qPJ957Mn6Iz0UpMtV80cmxCVxw==", + "requires": { + "bson": "~1.0.4", + "require_optional": "~1.0.0" + } + }, + "mongojs": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", + "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", + "requires": { + "each-series": "^1.0.0", + "mongodb": "^2.0.45", + "once": "^1.3.2", + "parse-mongo-url": "^1.1.0", + "readable-stream": "^2.0.2", + "thunky": "^0.1.0", + "to-mongodb-core": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "optional": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + } + }, + "nan": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", + "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" + }, + "native-promise-only": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "dev": true + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "optional": true + }, + "negotiator": { + "version": "0.4.9", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", + "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" + }, + "nise": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.3.tgz", + "integrity": "sha512-v1J/FLUB9PfGqZLGDBhQqODkbLotP0WtLo9R4EJY2PPu5f5Xg4o0rA8FDlmrjFSv9vBBKcfnOSpfYYuu5RTHqg==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^2.0.0", + "just-extend": "^1.1.27", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + } + } + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "node-forge": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.4.tgz", + "integrity": "sha512-UOfdpxivIYY4g5tqp5FNRNgROVNxRACUxxJREntJLFaJr1E0UEqFtUIk0F/jYx/E+Y6sVXd0KDi/m5My0yGCVw==" + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "dev": true + }, + "oauth-sign": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", + "integrity": "sha1-y1QPk7srIqfVlBaRoojWDo6pOG4=", + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-duration": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", + "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" + }, + "parse-mongo-url": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" + }, + "parse-ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", + "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" + }, + "parseurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", + "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", + "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + }, + "pretty-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz", + "integrity": "sha512-qG66ahoLCwpLXD09ZPHSCbUWYTqdosB7SMP4OffgTgL2PBKXMuUsrk5Bwg8q4qPkjTXsKBMr+YK3Ltd/6F9s/Q==", + "requires": { + "parse-ms": "^2.0.0" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "prom-client": { + "version": "11.5.1", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.1.tgz", + "integrity": "sha512-AcFuxVgzoA/4nlpeg9SkM2HkDjNU3V7g2LCLwpudXSbcSLiFpRMVfsCoCY5RYeR/d9jkQng1mCmVKj1mPHvP0Q==", + "requires": { + "tdigest": "^0.1.1" + } + }, + "protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "dependencies": { + "@types/node": { + "version": "10.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.9.tgz", + "integrity": "sha512-NelG/dSahlXYtSoVPErrp06tYFrvzj8XLWmKA+X8x0W//4MqbUyZu++giUG/v0bjAT6/Qxa8IjodrfdACyb0Fg==" + } + } + }, + "psl": { + "version": "1.1.32", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", + "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "qs": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", + "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" + }, + "range-parser": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", + "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" + }, + "raven": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", + "integrity": "sha1-QnPBrm005CMPUbLAEEGjK5Iygio=", + "requires": { + "cookie": "0.3.1", + "json-stringify-safe": "5.0.1", + "lsmod": "1.0.0", + "stack-trace": "0.0.9", + "uuid": "3.0.0" + }, + "dependencies": { + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "uuid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", + "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" + } + } + }, + "raw-body": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", + "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "requires": { + "bytes": "1", + "string_decoder": "0.10" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "request": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", + "integrity": "sha1-tdi5UmrdSi1GKfTUFxJFc5lkRa4=", + "dev": true, + "requires": { + "aws-sign2": "~0.5.0", + "forever-agent": "~0.5.0", + "form-data": "~0.1.0", + "hawk": "~1.0.0", + "http-signature": "~0.10.0", + "json-stringify-safe": "~5.0.0", + "mime": "~1.2.9", + "node-uuid": "~1.4.0", + "oauth-sign": "~0.3.0", + "qs": "~0.6.0", + "tough-cookie": ">=0.12.0", + "tunnel-agent": "~0.3.0" + } + }, + "require-in-the-middle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.0.tgz", + "integrity": "sha512-GX12iFhCUzzNuIqvei0dTLUbBEjZ420KTY/MmDxe2GQKPDGyH/wgfGMWFABpnM/M6sLwC3IaSg8A95U6gIb+HQ==", + "requires": { + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.10.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "require-like": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", + "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", + "dev": true + }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, + "retry-axios": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz", + "integrity": "sha512-jp4YlI0qyDFfXiXGhkCOliBN1G7fRH03Nqy8YdShzGqbY5/9S2x/IR6C88ls2DFkbWuL3ASkP7QD3pVrNpPgwQ==" + }, + "retry-request": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.0.0.tgz", + "integrity": "sha512-S4HNLaWcMP6r8E4TMH52Y7/pM8uNayOcTDDQNBwsCccL1uI+Ol2TljxRDPzaNfbhOB30+XWP5NnZkB3LiJxi1w==", + "requires": { + "through2": "^2.0.0" + } + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "optional": true, + "requires": { + "glob": "^6.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-json-stringify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz", + "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==", + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "samsam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", + "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "dev": true + }, + "sandboxed-module": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", + "integrity": "sha1-8fvvvYCaT2kHO9B8rm/H2y6vX2o=", + "dev": true, + "requires": { + "require-like": "0.1.2", + "stack-trace": "0.0.6" + }, + "dependencies": { + "stack-trace": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", + "integrity": "sha1-HnGb1qJin/CcGJ4Xqe+QKpT8XbA=", + "dev": true + } + } + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + }, + "send": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", + "integrity": "sha1-lxgyRjSAb8dbxPj15R9X2dZmBuc=", + "requires": { + "buffer-crc32": "0.2.1", + "debug": "0.8.0", + "fresh": "~0.2.1", + "mime": "1.2.11", + "range-parser": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz", + "integrity": "sha1-BUHqkfDlA/3wxe7UGKMlUCNJZ/A=" + } + } + }, + "serve-static": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz", + "integrity": "sha1-RU36Bbs93U5wGokVuDoniqkcVkM=", + "requires": { + "parseurl": "1.0.1", + "send": "0.3.0" + } + }, + "settings-sharelatex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", + "integrity": "sha512-f7D+0lnlohoteSn6IKTH72NE+JnAdMWTKwQglAuimZWTID2FRRItZSGeYMTRpvEnaQApkoVwRp//WRMsiddnqw==", + "requires": { + "coffee-script": "1.6.0" + }, + "dependencies": { + "coffee-script": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + } + } + }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "sinon": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", + "integrity": "sha512-KY3OLOWpek/I4NGAMHetuutVgS2aRgMR5g5/1LSYvPJ3qo2BopIvk3esFztPxF40RWf/NNNJzdFPriSkXUVK3A==", + "dev": true, + "requires": { + "diff": "^3.1.0", + "formatio": "1.2.0", + "lolex": "^2.1.2", + "native-promise-only": "^0.8.1", + "nise": "^1.0.1", + "path-to-regexp": "^1.7.0", + "samsam": "^1.1.3", + "text-encoding": "0.6.4", + "type-detect": "^4.0.0" + }, + "dependencies": { + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + } + } + }, + "sntp": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", + "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", + "dev": true, + "optional": true, + "requires": { + "hoek": "0.9.x" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "stack-trace": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", + "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=" + }, + "statsd-parser": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", + "integrity": "sha1-y9JDlTzELv/VSLXSI4jtaJ7GOb0=" + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + }, + "tdigest": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", + "requires": { + "bintrees": "1.0.1" + } + }, + "teeny-request": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", + "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "requires": { + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.2.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + }, + "to-mongodb-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + }, + "tough-cookie": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", + "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "dev": true, + "optional": true, + "requires": { + "punycode": "^1.4.1" + } + }, + "tunnel-agent": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", + "integrity": "sha1-rWgbaPUyGtKCfEz7G31d8s/pQu4=", + "dev": true, + "optional": true + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + }, + "type-is": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz", + "integrity": "sha1-0CReyLJnZmjVndDPMlUGBnalfbY=", + "requires": { + "mime": "~1.2.11" + } + }, + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + } + } +} From bec7e7c0e1c0c4cf424a39beda448930281767e5 Mon Sep 17 00:00:00 2001 From: Nate Stemen <nathanielstemen@gmail.com> Date: Fri, 25 Oct 2019 12:59:28 -0400 Subject: [PATCH 202/349] replace private link with public one --- services/docstore/.github/PULL_REQUEST_TEMPLATE.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/docstore/.github/PULL_REQUEST_TEMPLATE.md b/services/docstore/.github/PULL_REQUEST_TEMPLATE.md index ed25ee83c1..12bb2eeb3f 100644 --- a/services/docstore/.github/PULL_REQUEST_TEMPLATE.md +++ b/services/docstore/.github/PULL_REQUEST_TEMPLATE.md @@ -1,4 +1,7 @@ -<!-- Please review https://github.com/overleaf/write_latex/blob/master/.github/CONTRIBUTING.md for guidance on what is expected in each section. --> + +<!-- ** This is an Overleaf public repository ** --> + +<!-- Please review https://github.com/overleaf/overleaf/blob/master/CONTRIBUTING.md for guidance on what is expected of a contribution. --> ### Description From bfa4cc00234e600eccc3e5e03b47daee2817a434 Mon Sep 17 00:00:00 2001 From: Nate Stemen <nathanielstemen@gmail.com> Date: Fri, 25 Oct 2019 12:59:47 -0400 Subject: [PATCH 203/349] bump build script to 1.1.24 --- services/docstore/Makefile | 4 ++-- services/docstore/buildscript.txt | 4 +++- services/docstore/docker-compose.ci.yml | 2 +- services/docstore/docker-compose.yml | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 93bd3d3991..6fe7385f4e 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.21 +# Version: 1.1.24 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) @@ -38,7 +38,7 @@ test_clean: $(DOCKER_COMPOSE) down -v -t 0 test_acceptance_pre_run: - @[ ! -f test/acceptance/scripts/pre-run ] && echo "docstore has no pre acceptance tests task" || $(DOCKER_COMPOSE) run --rm test_acceptance test/acceptance/scripts/pre-run + @[ ! -f test/acceptance/js/scripts/pre-run ] && echo "docstore has no pre acceptance tests task" || $(DOCKER_COMPOSE) run --rm test_acceptance test/acceptance/js/scripts/pre-run build: docker build --pull --tag ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ --tag gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index d4c500e1bd..97327b38f6 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -5,4 +5,6 @@ docstore --dependencies=mongo,redis --docker-repos=gcr.io/overleaf-ops --build-target=docker ---script-version=1.1.21 +--script-version=1.1.24 +--env-pass-through= +--public-repo=True diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index baac7bccae..05d153e982 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.21 +# Version: 1.1.24 version: "2" diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index ed252891e8..bfbfb4e1a2 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.21 +# Version: 1.1.24 version: "2" From 1132932dfc018641501c1927a9d1ebfba85d2122 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Fri, 7 Feb 2020 14:16:31 +0000 Subject: [PATCH 204/349] update to node 10.19.0 --- services/docstore/Dockerfile | 4 ++-- services/docstore/docker-compose.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 7656cf4526..dee218ce8c 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -1,4 +1,4 @@ -FROM node:10.16.3 as app +FROM node:10.19.0 as app WORKDIR /app @@ -12,7 +12,7 @@ COPY . /app RUN npm run compile:all -FROM node:10.16.3 +FROM node:10.19.0 COPY --from=app /app /app diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 1e25d01dd2..566b036867 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -7,7 +7,7 @@ version: "2" services: test_unit: - image: node:10.16.3 + image: node:10.19.0 volumes: - .:/app working_dir: /app From f93ee6ab572cb4738474c3fb5ae6ae38f3d6b5ca Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Fri, 7 Feb 2020 15:30:41 +0000 Subject: [PATCH 205/349] update .nvmrc --- services/docstore/.nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index bbf0c5a541..5b7269c0a9 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -6.14.1 +10.19.0 From 31349a40cd949bd1a21ae1baa3561a7883c68be5 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Fri, 7 Feb 2020 15:31:03 +0000 Subject: [PATCH 206/349] update node version in buildscript.txt --- services/docstore/buildscript.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 97327b38f6..81a12ff787 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,6 +1,6 @@ docstore --language=coffeescript ---node-version=6.14.1 +--node-version=10.19.0 --acceptance-creds=aws --dependencies=mongo,redis --docker-repos=gcr.io/overleaf-ops From 710577cdb1505a28d36d6952604b6fb3bc1ea41b Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <das7pad@outlook.com> Date: Mon, 10 Feb 2020 17:10:43 +0100 Subject: [PATCH 207/349] [misc] update the build scripts to 1.3.5 --- services/docstore/Dockerfile | 13 +++++++++---- services/docstore/Jenkinsfile | 1 + services/docstore/Makefile | 9 ++++++++- services/docstore/buildscript.txt | 6 +++--- services/docstore/docker-compose.ci.yml | 14 +++++++------- services/docstore/docker-compose.yml | 25 +++++++++---------------- 6 files changed, 37 insertions(+), 31 deletions(-) diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index dee218ce8c..e538fb48d9 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -1,7 +1,14 @@ -FROM node:10.19.0 as app +# This file was auto-generated, do not edit it directly. +# Instead run bin/update_build_scripts from +# https://github.com/sharelatex/sharelatex-dev-environment +# Version: 1.3.5 + +FROM node:10.19.0 as base WORKDIR /app +FROM base as app + #wildcard as some files may not be in all repos COPY package*.json npm-shrink*.json /app/ @@ -12,11 +19,9 @@ COPY . /app RUN npm run compile:all -FROM node:10.19.0 +FROM base COPY --from=app /app /app - -WORKDIR /app USER node CMD ["node", "--expose-gc", "app.js"] diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 02d67a77d7..14ea3db943 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -16,6 +16,7 @@ pipeline { } stages { + stage('Install') { steps { withCredentials([usernamePassword(credentialsId: 'GITHUB_INTEGRATION', usernameVariable: 'GH_AUTH_USERNAME', passwordVariable: 'GH_AUTH_PASSWORD')]) { diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 6fe7385f4e..d720f78b65 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,7 +1,7 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.24 +# Version: 1.3.5 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) @@ -31,14 +31,20 @@ test_unit: test_acceptance: test_clean test_acceptance_pre_run test_acceptance_run +test_acceptance_debug: test_clean test_acceptance_pre_run test_acceptance_run_debug + test_acceptance_run: @[ ! -d test/acceptance ] && echo "docstore has no acceptance tests" || $(DOCKER_COMPOSE) run --rm test_acceptance +test_acceptance_run_debug: + @[ ! -d test/acceptance ] && echo "docstore has no acceptance tests" || $(DOCKER_COMPOSE) run -p 127.0.0.9:19999:19999 --rm test_acceptance npm run test:acceptance -- --inspect=0.0.0.0:19999 --inspect-brk + test_clean: $(DOCKER_COMPOSE) down -v -t 0 test_acceptance_pre_run: @[ ! -f test/acceptance/js/scripts/pre-run ] && echo "docstore has no pre acceptance tests task" || $(DOCKER_COMPOSE) run --rm test_acceptance test/acceptance/js/scripts/pre-run + build: docker build --pull --tag ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ --tag gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ @@ -51,4 +57,5 @@ publish: docker push $(DOCKER_REPO)/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + .PHONY: clean test test_unit test_acceptance test_clean build publish diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 81a12ff787..572d647720 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,10 +1,10 @@ docstore +--public-repo=True --language=coffeescript +--env-add= --node-version=10.19.0 --acceptance-creds=aws --dependencies=mongo,redis --docker-repos=gcr.io/overleaf-ops ---build-target=docker ---script-version=1.1.24 --env-pass-through= ---public-repo=True +--script-version=1.3.5 diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 05d153e982..dd9abb66e5 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,9 +1,9 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.24 +# Version: 1.3.5 -version: "2" +version: "2.3" services: test_unit: @@ -28,13 +28,14 @@ services: MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test depends_on: - - mongo - - redis + mongo: + condition: service_healthy + redis: + condition: service_healthy user: node command: npm run test:acceptance:_run - tar: build: . image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER @@ -42,9 +43,8 @@ services: - ./:/tmp/build/ command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs . user: root - redis: image: redis mongo: - image: mongo:3.4 + image: mongo:3.6 diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 566b036867..fb42905c0a 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,9 +1,9 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.1.24 +# Version: 1.3.5 -version: "2" +version: "2.3" services: test_unit: @@ -18,7 +18,7 @@ services: user: node test_acceptance: - build: . + image: node:10.19.0 volumes: - .:/app working_dir: /app @@ -35,22 +35,15 @@ services: NODE_ENV: test user: node depends_on: - - mongo - - redis + mongo: + condition: service_healthy + redis: + condition: service_healthy command: npm run test:acceptance - - - tar: - build: . - image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER - volumes: - - ./:/tmp/build/ - command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs . - user: root - redis: image: redis mongo: - image: mongo:3.4 + image: mongo:3.6 + From f8c93b644cd04aa74aca9a718abcea8ff5c8547e Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Wed, 12 Feb 2020 12:37:00 +0000 Subject: [PATCH 208/349] remove unused .travis.yml file --- services/docstore/.travis.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 services/docstore/.travis.yml diff --git a/services/docstore/.travis.yml b/services/docstore/.travis.yml deleted file mode 100644 index febdbb55a3..0000000000 --- a/services/docstore/.travis.yml +++ /dev/null @@ -1,11 +0,0 @@ -language: node_js - -before_install: - - npm install -g grunt-cli - -install: - - npm install - - grunt install - -script: - - grunt test:unit From f2577a16cc23a56f29a43b70ba145e1f9e96a0c0 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <das7pad@outlook.com> Date: Wed, 12 Feb 2020 14:43:19 +0100 Subject: [PATCH 209/349] [misc] cleanup unused dependency on redis --- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose.ci.yml | 5 ----- services/docstore/docker-compose.yml | 5 ----- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 572d647720..8c8706f1cf 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -4,7 +4,7 @@ docstore --env-add= --node-version=10.19.0 --acceptance-creds=aws ---dependencies=mongo,redis +--dependencies=mongo --docker-repos=gcr.io/overleaf-ops --env-pass-through= --script-version=1.3.5 diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index dd9abb66e5..f3d86bb0f9 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -30,8 +30,6 @@ services: depends_on: mongo: condition: service_healthy - redis: - condition: service_healthy user: node command: npm run test:acceptance:_run @@ -43,8 +41,5 @@ services: - ./:/tmp/build/ command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs . user: root - redis: - image: redis - mongo: image: mongo:3.6 diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index fb42905c0a..10805fd581 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -37,13 +37,8 @@ services: depends_on: mongo: condition: service_healthy - redis: - condition: service_healthy command: npm run test:acceptance - redis: - image: redis - mongo: image: mongo:3.6 From 8fd7dbf13340f02b2f82e09292cd37c34dec3917 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 13:59:59 +0000 Subject: [PATCH 210/349] decaffeinate: update build scripts to es --- services/docstore/.dockerignore | 2 - services/docstore/.eslintrc | 65 +++++++++++++++++++++++++++++++ services/docstore/.prettierrc | 8 ++++ services/docstore/Dockerfile | 1 - services/docstore/Jenkinsfile | 7 ++++ services/docstore/Makefile | 15 ++++--- services/docstore/buildscript.txt | 14 +++---- services/docstore/nodemon.json | 7 ++-- services/docstore/package.json | 18 ++++----- 9 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 services/docstore/.eslintrc create mode 100644 services/docstore/.prettierrc diff --git a/services/docstore/.dockerignore b/services/docstore/.dockerignore index 386f26df30..ba1c3442de 100644 --- a/services/docstore/.dockerignore +++ b/services/docstore/.dockerignore @@ -5,5 +5,3 @@ gitrev .npm .nvmrc nodemon.json -app.js -**/js/* diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc new file mode 100644 index 0000000000..42a4b5cace --- /dev/null +++ b/services/docstore/.eslintrc @@ -0,0 +1,65 @@ +// this file was auto-generated, do not edit it directly. +// instead run bin/update_build_scripts from +// https://github.com/sharelatex/sharelatex-dev-environment +// Version: 1.3.5 +{ + "extends": [ + "standard", + "prettier", + "prettier/standard" + ], + "parserOptions": { + "ecmaVersion": 2017 + }, + "plugins": [ + "mocha", + "chai-expect", + "chai-friendly" + ], + "env": { + "node": true, + "mocha": true + }, + "rules": { + // Swap the no-unused-expressions rule with a more chai-friendly one + "no-unused-expressions": 0, + "chai-friendly/no-unused-expressions": "error" + }, + "overrides": [ + { + // Test specific rules + "files": ["test/**/*.js"], + "globals": { + "expect": true + }, + "rules": { + // mocha-specific rules + "mocha/handle-done-callback": "error", + "mocha/no-exclusive-tests": "error", + "mocha/no-global-tests": "error", + "mocha/no-identical-title": "error", + "mocha/no-nested-tests": "error", + "mocha/no-pending-tests": "error", + "mocha/no-skipped-tests": "error", + "mocha/no-mocha-arrows": "error", + + // chai-specific rules + "chai-expect/missing-assertion": "error", + "chai-expect/terminating-properties": "error", + + // prefer-arrow-callback applies to all callbacks, not just ones in mocha tests. + // we don't enforce this at the top-level - just in tests to manage `this` scope + // based on mocha's context mechanism + "mocha/prefer-arrow-callback": "error" + } + }, + { + // Backend specific rules + "files": ["app/**/*.js", "app.js", "index.js"], + "rules": { + // don't allow console.log in backend code + "no-console": "error" + } + } + ] +} diff --git a/services/docstore/.prettierrc b/services/docstore/.prettierrc new file mode 100644 index 0000000000..5845b82113 --- /dev/null +++ b/services/docstore/.prettierrc @@ -0,0 +1,8 @@ +# This file was auto-generated, do not edit it directly. +# Instead run bin/update_build_scripts from +# https://github.com/sharelatex/sharelatex-dev-environment +# Version: 1.3.5 +{ + "semi": false, + "singleQuote": true +} diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index e538fb48d9..2d8b097e26 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -17,7 +17,6 @@ RUN npm install --quiet COPY . /app -RUN npm run compile:all FROM base diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 14ea3db943..95132d21db 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -37,6 +37,13 @@ pipeline { } } + 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' diff --git a/services/docstore/Makefile b/services/docstore/Makefile index d720f78b65..1314c0d76d 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -19,12 +19,17 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ clean: docker rmi ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) docker rmi gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) - rm -f app.js - rm -rf app/js - rm -rf test/unit/js - rm -rf test/acceptance/js -test: test_unit test_acceptance +format: + $(DOCKER_COMPOSE) run --rm test_unit npm run format + +format_fix: + $(DOCKER_COMPOSE) run --rm test_unit npm run format:fix + +lint: + $(DOCKER_COMPOSE) run --rm test_unit npm run lint + +test: format lint test_unit test_acceptance test_unit: @[ ! -d test/unit ] && echo "docstore has no unit tests" || $(DOCKER_COMPOSE) run --rm test_unit diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 8c8706f1cf..77a5b00f8c 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,10 +1,10 @@ docstore ---public-repo=True ---language=coffeescript ---env-add= --node-version=10.19.0 ---acceptance-creds=aws ---dependencies=mongo ---docker-repos=gcr.io/overleaf-ops ---env-pass-through= --script-version=1.3.5 +--dependencies=mongo +--language=es +--docker-repos=gcr.io/overleaf-ops +--acceptance-creds=aws +--env-pass-through= +--env-add= +--public-repo=True diff --git a/services/docstore/nodemon.json b/services/docstore/nodemon.json index 98db38d71b..5826281b84 100644 --- a/services/docstore/nodemon.json +++ b/services/docstore/nodemon.json @@ -10,10 +10,9 @@ }, "watch": [ - "app/coffee/", - "app.coffee", + "app/js/", + "app.js", "config/" ], - "ext": "coffee" - + "ext": "js" } diff --git a/services/docstore/package.json b/services/docstore/package.json index b0b24ce551..ff0950cf27 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -8,17 +8,15 @@ "url": "https://github.com/sharelatex/docstore-sharelatex.git" }, "scripts": { - "compile:app": "([ -e app/coffee ] && coffee -m $COFFEE_OPTIONS -o app/js -c app/coffee || echo 'No CoffeeScript folder to compile') && ( [ -e app.coffee ] && coffee -m $COFFEE_OPTIONS -c app.coffee || echo 'No CoffeeScript app to compile')", - "start": "npm run compile:app && node $NODE_APP_OPTIONS app.js", - "test:acceptance:_run": "AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY AWS_BUCKET=$AWS_BUCKET AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID mocha --recursive --reporter spec --timeout 30000 --exit $@ test/acceptance/js", - "test:acceptance": "npm run compile:app && npm run compile:acceptance_tests && npm run test:acceptance:_run -- --grep=$MOCHA_GREP", - "test:unit:_run": "mocha --recursive --reporter spec --exit $@ test/unit/js", - "test:unit": "npm run compile:app && npm run compile:unit_tests && npm run test:unit:_run -- --grep=$MOCHA_GREP", - "compile:unit_tests": "[ ! -e test/unit/coffee ] && echo 'No unit tests to compile' || coffee -o test/unit/js -c test/unit/coffee", - "compile:acceptance_tests": "[ ! -e test/acceptance/coffee ] && echo 'No acceptance tests to compile' || coffee -o test/acceptance/js -c test/acceptance/coffee", - "compile:all": "npm run compile:app && npm run compile:unit_tests && npm run compile:acceptance_tests && npm run compile:smoke_tests", + "start": "node $NODE_APP_OPTIONS app.js", + "test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js", + "test:acceptance": "npm run test:acceptance:_run -- --grep=$MOCHA_GREP", + "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", - "compile:smoke_tests": "[ ! -e test/smoke/coffee ] && echo 'No smoke tests to compile' || coffee -o test/smoke/js -c test/smoke/coffee" + "lint": "node_modules/.bin/eslint .", + "format": "node_modules/.bin/prettier-eslint '**/*.js' --list-different", + "format:fix": "node_modules/.bin/prettier-eslint '**/*.js' --write" }, "dependencies": { "async": "~0.8.0", From b54e4cd2762805585c7ab595a138a2fb2c37381d Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:00:36 +0000 Subject: [PATCH 211/349] decaffeinate: update .gitignore --- services/docstore/.gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/services/docstore/.gitignore b/services/docstore/.gitignore index 6a355b35a8..50678c09e9 100644 --- a/services/docstore/.gitignore +++ b/services/docstore/.gitignore @@ -1,7 +1,2 @@ node_modules -app/js/ -test/unit/js -test/acceptance/js -app.js -**/*.map forever From b4aec5394b8fce84bff0b888458a34a52093fd69 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:01:32 +0000 Subject: [PATCH 212/349] decaffeinate: add eslint and prettier packages --- services/docstore/package-lock.json | 3029 ++++++++++++++++++++++++++- services/docstore/package.json | 18 + 2 files changed, 3044 insertions(+), 3 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 9eab5b1bd3..3ed5f34f56 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -4,6 +4,146 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true + }, + "@babel/runtime": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.4.tgz", + "integrity": "sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, "@google-cloud/common": { "version": "0.32.1", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz", @@ -284,6 +424,12 @@ "@types/node": "*" } }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/form-data": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", @@ -292,6 +438,12 @@ "@types/node": "*" } }, + "@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "dev": true + }, "@types/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", @@ -323,6 +475,51 @@ "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" }, + "@typescript-eslint/experimental-utils": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz", + "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "1.13.0", + "eslint-scope": "^4.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + } + } + }, + "@typescript-eslint/parser": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.13.0.tgz", + "integrity": "sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "1.13.0", + "@typescript-eslint/typescript-estree": "1.13.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz", + "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==", + "dev": true, + "requires": { + "lodash.unescape": "4.0.1", + "semver": "5.5.0" + } + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -345,6 +542,12 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" }, + "acorn-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "dev": true + }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -364,6 +567,70 @@ "uri-js": "^4.2.2" } }, + "ansi-escapes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -389,6 +656,18 @@ "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", "dev": true }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "async": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz", @@ -429,6 +708,37 @@ "is-buffer": "^2.0.2" } }, + "axobject-query": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.2.tgz", + "integrity": "sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ==", + "dev": true + }, + "babel-eslint": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", + "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -475,12 +785,17 @@ "type-is": "~1.1.0" } }, + "boolify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/boolify/-/boolify-1.0.1.tgz", + "integrity": "sha1-tcCeF8rNET0Rt7s+04TMASmU2Gs=", + "dev": true + }, "boom": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", "dev": true, - "optional": true, "requires": { "hoek": "0.9.x" } @@ -540,6 +855,29 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=" }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.1.2.tgz", + "integrity": "sha512-QfFrU0CIw2oltVvpndW32kuJ/9YOJwUnmWrjlXt1nnJZHCaS9i6bfOpg9R4Lw8aZjStkJWM+jc0cdXjWBgVJSw==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -555,11 +893,111 @@ "deep-eql": "0.1.3" } }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, "coffee-script": { "version": "1.12.7", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "combined-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", @@ -570,6 +1008,18 @@ "delayed-stream": "0.0.5" } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "common-tags": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", + "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -580,6 +1030,12 @@ "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", "integrity": "sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==" }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "continuation-local-storage": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", @@ -599,11 +1055,30 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" }, + "core-js": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, "cryptiles": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", @@ -621,6 +1096,12 @@ "dev": true, "optional": true }, + "damerau-levenshtein": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", + "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -641,6 +1122,12 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz", "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=" }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, "deep-eql": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", @@ -650,6 +1137,21 @@ "type-detect": "0.1.1" } }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "delay": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz", @@ -662,6 +1164,21 @@ "dev": true, "optional": true }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", @@ -710,6 +1227,12 @@ "shimmer": "^1.2.0" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -723,6 +1246,45 @@ "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-promise": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", @@ -754,6 +1316,454 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.6.0.tgz", + "integrity": "sha512-PpEBq7b6qY/qrOmpYQ/jTMDYfuQMELR4g4WI1M/NaSDDD/bdcMb+dj4Hgks7p41kW2caXsPsEZAEAyAgjVVC0g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-config-prettier": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.0.tgz", + "integrity": "sha512-AtndijGte1rPILInUdHjvKEGbIV06NuvPrqlIEaEaWtbtvJh464mDeyGMdZEQMsGvC0ZVkiex1fSNcC4HAbRGg==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-config-standard": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz", + "integrity": "sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==", + "dev": true + }, + "eslint-config-standard-jsx": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-8.1.0.tgz", + "integrity": "sha512-ULVC8qH8qCqbU792ZOO6DaiaZyHNS/5CZt3hKqHkEhVlhPEPN3nfBqqxJCyp59XrjIBZPu1chMYe9T2DXZ7TMw==", + "dev": true + }, + "eslint-config-standard-react": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-react/-/eslint-config-standard-react-9.2.0.tgz", + "integrity": "sha512-u+KRP2uCtthZ/W4DlLWCC59GZNV/y9k9yicWWammgTs/Omh8ZUUPF3EnYm81MAcbkYQq2Wg0oxutAhi/FQ8mIw==", + "dev": true, + "requires": { + "eslint-config-standard-jsx": "^8.0.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "eslint-plugin-chai-expect": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.1.0.tgz", + "integrity": "sha512-rd0/4mjMV6c3i0o4DKkWI4uaFN9DK707kW+/fDphaDI6HVgxXnhML9Xgt5vHnTXmSSnDhupuCFBgsEAEpchXmQ==", + "dev": true + }, + "eslint-plugin-chai-friendly": { + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz", + "integrity": "sha512-6/Jb/J/ZvSebydwbBJO1R9E5ky7YeElfK56Veh7e4QGFHCXoIXGH9HhVz+ibJLM3XJ1XjP+T7rKBLUa/Y7eIng==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "regexpp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.1" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + } + } + }, + "eslint-plugin-mocha": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.2.2.tgz", + "integrity": "sha512-oNhPzfkT6Q6CJ0HMVJ2KLxEWG97VWGTmuHOoRcDLE0U88ugUyFNV9wrT2XIt5cGtqc5W9k38m4xTN34L09KhBA==", + "dev": true, + "requires": { + "ramda": "^0.26.1" + } + }, + "eslint-plugin-node": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.0.0.tgz", + "integrity": "sha512-chUs/NVID+sknFiJzxoN9lM7uKSOEta8GC8365hw1nDfwIPIjjpRSwwPvQanWv8dt/pDe9EV4anmVSwdiSndNg==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz", + "integrity": "sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-promise": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.18.3.tgz", + "integrity": "sha512-Bt56LNHAQCoou88s8ViKRjMB2+36XRejCQ1VoLj716KI1MoE99HpTVvIThJ0rvFmG4E4Gsq+UgToEjn+j044Bg==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.3", + "object.entries": "^1.1.1", + "object.fromentries": "^2.0.2", + "object.values": "^1.1.1", + "prop-types": "^15.7.2", + "resolve": "^1.14.2", + "string.prototype.matchall": "^4.0.2" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-plugin-standard": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", + "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "dev": true, + "requires": { + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", + "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", @@ -788,6 +1798,17 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -798,26 +1819,107 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, "fast-text-encoding": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==" }, + "figures": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "follow-redirects": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", @@ -883,6 +1985,18 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gaxios": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", @@ -903,6 +2017,18 @@ "json-bigint": "^0.3.0" } }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -931,6 +2057,21 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "google-auth-library": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz", @@ -956,6 +2097,12 @@ "pify": "^4.0.0" } }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, "gtoken": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", @@ -989,12 +2136,44 @@ "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, "hawk": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", @@ -1023,8 +2202,13 @@ "version": "0.9.1", "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", - "dev": true, - "optional": true + "dev": true + }, + "hosted-git-info": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true }, "http-signature": { "version": "0.10.1", @@ -1062,6 +2246,51 @@ } } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1076,16 +2305,117 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "inquirer": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", + "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + } + }, + "internal-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", + "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "has": "^1.0.3", + "side-channel": "^1.0.2" + } + }, "is": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==" }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-buffer": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1096,16 +2426,44 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", @@ -1124,6 +2482,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -1147,6 +2511,16 @@ } } }, + "jsx-ast-utils": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz", + "integrity": "sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" + } + }, "just-extend": { "version": "1.1.27", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", @@ -1172,11 +2546,75 @@ "safe-buffer": "^5.0.1" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" }, + "lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "dev": true + }, "logger-sharelatex": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.7.0.tgz", @@ -1316,6 +2754,64 @@ } } }, + "loglevel": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", + "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==", + "dev": true + }, + "loglevel-colored-level-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz", + "integrity": "sha1-akAhj9x64V/HbD0PPmdsRlOIYD4=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "loglevel": "^1.4.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, "lolex": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.6.0.tgz", @@ -1327,6 +2823,15 @@ "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -1349,6 +2854,30 @@ "statsd-parser": "~0.0.4" } }, + "make-plural": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", + "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true, + "optional": true + } + } + }, + "map-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", + "dev": true + }, "merge-descriptors": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", @@ -1359,6 +2888,29 @@ "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" }, + "messageformat": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", + "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", + "dev": true, + "requires": { + "make-plural": "^4.3.0", + "messageformat-formatters": "^2.0.1", + "messageformat-parser": "^4.1.2" + } + }, + "messageformat-formatters": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", + "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==", + "dev": true + }, + "messageformat-parser": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.2.tgz", + "integrity": "sha512-7dWuifeyldz7vhEuL96Kwq1fhZXBW+TUfbnHN4UCrCxoXQTYjHnR78eI66Gk9LaLLsAvzPNVJBaa66DRfFNaiA==", + "dev": true + }, "methods": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz", @@ -1403,6 +2955,12 @@ "mime-db": "1.40.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1559,6 +3117,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -1581,6 +3145,12 @@ "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", "dev": true }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", @@ -1592,6 +3162,12 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "nise": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.3.tgz", @@ -1638,6 +3214,18 @@ "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", "dev": true }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "oauth-sign": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", @@ -1645,6 +3233,72 @@ "dev": true, "optional": true }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", + "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", + "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1653,6 +3307,35 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", @@ -1661,16 +3344,60 @@ "p-try": "^2.0.0" } }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + }, + "dependencies": { + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-duration": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "parse-mongo-url": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", @@ -1686,11 +3413,29 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", @@ -1701,6 +3446,23 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -1711,6 +3473,618 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true + }, + "prettier-eslint": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-9.0.1.tgz", + "integrity": "sha512-KZT65QTosSAqBBqmrC+RpXbsMRe7Os2YSR9cAfFbDlyPAopzA/S5bioiZ3rpziNQNSJaOxmtXSx07EQ+o2Dlug==", + "dev": true, + "requires": { + "@typescript-eslint/parser": "^1.10.2", + "common-tags": "^1.4.0", + "core-js": "^3.1.4", + "dlv": "^1.1.0", + "eslint": "^5.0.0", + "indent-string": "^4.0.0", + "lodash.merge": "^4.6.0", + "loglevel-colored-level-prefix": "^1.0.0", + "prettier": "^1.7.0", + "pretty-format": "^23.0.1", + "require-relative": "^0.8.7", + "typescript": "^3.2.1", + "vue-eslint-parser": "^2.0.2" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "prettier-eslint-cli": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-5.0.0.tgz", + "integrity": "sha512-cei9UbN1aTrz3sQs88CWpvY/10PYTevzd76zoG1tdJ164OhmNTFRKPTOZrutVvscoQWzbnLKkviS3gu5JXwvZg==", + "dev": true, + "requires": { + "arrify": "^2.0.1", + "boolify": "^1.0.0", + "camelcase-keys": "^6.0.0", + "chalk": "^2.4.2", + "common-tags": "^1.8.0", + "core-js": "^3.1.4", + "eslint": "^5.0.0", + "find-up": "^4.1.0", + "get-stdin": "^7.0.0", + "glob": "^7.1.4", + "ignore": "^5.1.2", + "lodash.memoize": "^4.1.2", + "loglevel-colored-level-prefix": "^1.0.0", + "messageformat": "^2.2.1", + "prettier-eslint": "^9.0.0", + "rxjs": "^6.5.2", + "yargs": "^13.2.4" + }, + "dependencies": { + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + } + } + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, + "pretty-format": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", + "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + }, "pretty-ms": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz", @@ -1724,6 +4098,12 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "prom-client": { "version": "11.5.1", "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.1.tgz", @@ -1732,6 +4112,17 @@ "tdigest": "^0.1.1" } }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, "protobufjs": { "version": "6.8.8", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", @@ -1774,6 +4165,18 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "ramda": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", + "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==", + "dev": true + }, "range-parser": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", @@ -1812,6 +4215,33 @@ "string_decoder": "0.10" } }, + "react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -1841,6 +4271,28 @@ } } }, + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "request": { "version": "2.34.0", "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", @@ -1861,6 +4313,12 @@ "tunnel-agent": "~0.3.0" } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, "require-in-the-middle": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.0.tgz", @@ -1892,6 +4350,18 @@ "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", "dev": true }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "require-relative": { + "version": "0.8.7", + "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", + "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "dev": true + }, "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", @@ -1914,6 +4384,16 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "retry-axios": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz", @@ -1936,6 +4416,24 @@ "glob": "^6.0.1" } }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -2009,6 +4507,12 @@ "send": "0.3.0" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, "settings-sharelatex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", @@ -2024,11 +4528,42 @@ } } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "shimmer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" }, + "side-channel": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", + "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "dev": true, + "requires": { + "es-abstract": "^1.17.0-next.1", + "object-inspect": "^1.7.0" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "sinon": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", @@ -2075,6 +4610,25 @@ } } }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, "sntp": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", @@ -2090,6 +4644,38 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", @@ -2098,6 +4684,12 @@ "through": "2" } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -2144,11 +4736,96 @@ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string.prototype.matchall": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", + "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "has-symbols": "^1.0.1", + "internal-slot": "^1.0.2", + "regexp.prototype.flags": "^1.3.0", + "side-channel": "^1.0.2" + } + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, "supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", @@ -2158,6 +4835,61 @@ "has-flag": "^2.0.0" } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", + "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", @@ -2189,6 +4921,12 @@ "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", "dev": true }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -2208,6 +4946,21 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, "to-mongodb-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", @@ -2223,6 +4976,12 @@ "punycode": "^1.4.1" } }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, "tunnel-agent": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", @@ -2235,12 +4994,27 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-detect": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", "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 + }, "type-is": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz", @@ -2249,6 +5023,12 @@ "mime": "~1.2.11" } }, + "typescript": { + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", + "dev": true + }, "underscore": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", @@ -2279,6 +5059,22 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" }, + "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==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -2296,20 +5092,247 @@ } } }, + "vue-eslint-parser": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz", + "integrity": "sha512-ZezcU71Owm84xVF6gfurBQUGg8WQ+WZGxgDEQu1IHFBZNx7BFZg3L1yHxrCBNNwbwFtE1GuvfJKMtb6Xuwc/Bw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "eslint-scope": "^3.7.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^3.5.2", + "esquery": "^1.0.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "acorn-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, + "requires": { + "acorn": "^3.0.4" + }, + "dependencies": { + "acorn": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true + } + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "espree": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", + "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "dev": true, + "requires": { + "acorn": "^5.5.0", + "acorn-jsx": "^3.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + }, + "dependencies": { + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } } diff --git a/services/docstore/package.json b/services/docstore/package.json index ff0950cf27..5181dbbc65 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -30,9 +30,27 @@ "underscore": "~1.6.0" }, "devDependencies": { + "babel-eslint": "^10.0.3", "bunyan": "~0.22.3", "chai": "~1.9.1", + "eslint": "^6.6.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.5.0", + "eslint-plugin-import": "^2.20.1", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-mocha": "^6.2.2", + "eslint-plugin-node": "^11.0.0", + "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-promise": "^4.2.1", + "eslint-plugin-react": "^7.18.3", + "eslint-plugin-standard": "^4.0.1", "mocha": "^4.0.1", + "prettier": "^1.19.1", + "prettier-eslint-cli": "^5.0.0", "request": "~2.34.0", "sandboxed-module": "~0.3.0", "sinon": "~3.2.1" From 88badb15c4911a0ed97dd6f05d81952b9338716e Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:01:44 +0000 Subject: [PATCH 213/349] decaffeinate: Rename DocArchiveManager.coffee and 7 other files from .coffee to .js --- .../app/coffee/{DocArchiveManager.coffee => DocArchiveManager.js} | 0 services/docstore/app/coffee/{DocManager.coffee => DocManager.js} | 0 services/docstore/app/coffee/{Errors.coffee => Errors.js} | 0 .../app/coffee/{HealthChecker.coffee => HealthChecker.js} | 0 .../app/coffee/{HttpController.coffee => HttpController.js} | 0 .../docstore/app/coffee/{MongoManager.coffee => MongoManager.js} | 0 .../docstore/app/coffee/{RangeManager.coffee => RangeManager.js} | 0 services/docstore/app/coffee/{mongojs.coffee => mongojs.js} | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename services/docstore/app/coffee/{DocArchiveManager.coffee => DocArchiveManager.js} (100%) rename services/docstore/app/coffee/{DocManager.coffee => DocManager.js} (100%) rename services/docstore/app/coffee/{Errors.coffee => Errors.js} (100%) rename services/docstore/app/coffee/{HealthChecker.coffee => HealthChecker.js} (100%) rename services/docstore/app/coffee/{HttpController.coffee => HttpController.js} (100%) rename services/docstore/app/coffee/{MongoManager.coffee => MongoManager.js} (100%) rename services/docstore/app/coffee/{RangeManager.coffee => RangeManager.js} (100%) rename services/docstore/app/coffee/{mongojs.coffee => mongojs.js} (100%) diff --git a/services/docstore/app/coffee/DocArchiveManager.coffee b/services/docstore/app/coffee/DocArchiveManager.js similarity index 100% rename from services/docstore/app/coffee/DocArchiveManager.coffee rename to services/docstore/app/coffee/DocArchiveManager.js diff --git a/services/docstore/app/coffee/DocManager.coffee b/services/docstore/app/coffee/DocManager.js similarity index 100% rename from services/docstore/app/coffee/DocManager.coffee rename to services/docstore/app/coffee/DocManager.js diff --git a/services/docstore/app/coffee/Errors.coffee b/services/docstore/app/coffee/Errors.js similarity index 100% rename from services/docstore/app/coffee/Errors.coffee rename to services/docstore/app/coffee/Errors.js diff --git a/services/docstore/app/coffee/HealthChecker.coffee b/services/docstore/app/coffee/HealthChecker.js similarity index 100% rename from services/docstore/app/coffee/HealthChecker.coffee rename to services/docstore/app/coffee/HealthChecker.js diff --git a/services/docstore/app/coffee/HttpController.coffee b/services/docstore/app/coffee/HttpController.js similarity index 100% rename from services/docstore/app/coffee/HttpController.coffee rename to services/docstore/app/coffee/HttpController.js diff --git a/services/docstore/app/coffee/MongoManager.coffee b/services/docstore/app/coffee/MongoManager.js similarity index 100% rename from services/docstore/app/coffee/MongoManager.coffee rename to services/docstore/app/coffee/MongoManager.js diff --git a/services/docstore/app/coffee/RangeManager.coffee b/services/docstore/app/coffee/RangeManager.js similarity index 100% rename from services/docstore/app/coffee/RangeManager.coffee rename to services/docstore/app/coffee/RangeManager.js diff --git a/services/docstore/app/coffee/mongojs.coffee b/services/docstore/app/coffee/mongojs.js similarity index 100% rename from services/docstore/app/coffee/mongojs.coffee rename to services/docstore/app/coffee/mongojs.js From afa2577381197c9e1922ffb014281660d264bb2d Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:01:46 +0000 Subject: [PATCH 214/349] decaffeinate: Convert DocArchiveManager.coffee and 7 other files to JS --- .../docstore/app/coffee/DocArchiveManager.js | 354 ++++++++++-------- services/docstore/app/coffee/DocManager.js | 274 ++++++++------ services/docstore/app/coffee/Errors.js | 18 +- services/docstore/app/coffee/HealthChecker.js | 99 ++--- .../docstore/app/coffee/HttpController.js | 346 ++++++++++------- services/docstore/app/coffee/MongoManager.js | 146 +++++--- services/docstore/app/coffee/RangeManager.js | 87 +++-- services/docstore/app/coffee/mongojs.js | 11 +- 8 files changed, 796 insertions(+), 539 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.js b/services/docstore/app/coffee/DocArchiveManager.js index 1fb6fb2657..e3c048558e 100644 --- a/services/docstore/app/coffee/DocArchiveManager.js +++ b/services/docstore/app/coffee/DocArchiveManager.js @@ -1,156 +1,208 @@ -MongoManager = require "./MongoManager" -Errors = require "./Errors" -logger = require "logger-sharelatex" -_ = require "underscore" -async = require "async" -settings = require("settings-sharelatex") -request = require("request") -crypto = require("crypto") -RangeManager = require("./RangeManager") -thirtySeconds = 30 * 1000 +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let DocArchive; +const MongoManager = require("./MongoManager"); +const Errors = require("./Errors"); +const logger = require("logger-sharelatex"); +const _ = require("underscore"); +const async = require("async"); +const settings = require("settings-sharelatex"); +const request = require("request"); +const crypto = require("crypto"); +const RangeManager = require("./RangeManager"); +const thirtySeconds = 30 * 1000; -module.exports = DocArchive = +module.exports = (DocArchive = { - archiveAllDocs: (project_id, callback = (err, docs) ->) -> - MongoManager.getProjectsDocs project_id, {include_deleted: true}, {lines: true, ranges: true, rev: true, inS3: true}, (err, docs) -> - if err? - return callback(err) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - docs = _.filter docs, (doc)-> doc.inS3 != true - jobs = _.map docs, (doc) -> - (cb)-> - DocArchive.archiveDoc project_id, doc, cb - async.parallelLimit jobs, 5, callback + archiveAllDocs(project_id, callback) { + if (callback == null) { callback = function(err, docs) {}; } + return MongoManager.getProjectsDocs(project_id, {include_deleted: true}, {lines: true, ranges: true, rev: true, inS3: true}, function(err, docs) { + if (err != null) { + return callback(err); + } else if ((docs == null)) { + return callback(new Errors.NotFoundError(`No docs for project ${project_id}`)); + } + docs = _.filter(docs, doc => doc.inS3 !== true); + const jobs = _.map(docs, doc => cb => DocArchive.archiveDoc(project_id, doc, cb)); + return async.parallelLimit(jobs, 5, callback); + }); + }, - archiveDoc: (project_id, doc, callback)-> - logger.log project_id: project_id, doc_id: doc._id, "sending doc to s3" - try - options = DocArchive.buildS3Options(project_id+"/"+doc._id) - catch e - return callback e - DocArchive._mongoDocToS3Doc doc, (error, json_doc) -> - return callback(error) if error? - options.body = json_doc - options.headers = - 'Content-Type': "application/json" - request.put options, (err, res) -> - if err? || res.statusCode != 200 - logger.err err:err, res:res, project_id:project_id, doc_id: doc._id, statusCode: res?.statusCode, "something went wrong archiving doc in aws" - return callback new Error("Error in S3 request") - md5lines = crypto.createHash("md5").update(json_doc, "utf8").digest("hex") - md5response = res.headers.etag.toString().replace(/\"/g, '') - if md5lines != md5response - logger.err responseMD5:md5response, linesMD5:md5lines, project_id:project_id, doc_id: doc?._id, "err in response md5 from s3" - return callback new Error("Error in S3 md5 response") - MongoManager.markDocAsArchived doc._id, doc.rev, (err) -> - return callback(err) if err? - callback() - - unArchiveAllDocs: (project_id, callback = (err) ->) -> - MongoManager.getArchivedProjectDocs project_id, (err, docs) -> - if err? - logger.err err:err, project_id:project_id, "error unarchiving all docs" - return callback(err) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - jobs = _.map docs, (doc) -> - (cb)-> - if !doc.inS3? - return cb() - else - DocArchive.unarchiveDoc project_id, doc._id, cb - async.parallelLimit jobs, 5, callback - - unarchiveDoc: (project_id, doc_id, callback)-> - logger.log project_id: project_id, doc_id: doc_id, "getting doc from s3" - try - options = DocArchive.buildS3Options(project_id+"/"+doc_id) - catch e - return callback e - options.json = true - request.get options, (err, res, doc)-> - if err? || res.statusCode != 200 - logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong unarchiving doc from aws" - return callback new Errors.NotFoundError("Error in S3 request") - DocArchive._s3DocToMongoDoc doc, (error, mongo_doc) -> - return callback(error) if error? - MongoManager.upsertIntoDocCollection project_id, doc_id.toString(), mongo_doc, (err) -> - return callback(err) if err? - logger.log project_id: project_id, doc_id: doc_id, "deleting doc from s3" - DocArchive._deleteDocFromS3 project_id, doc_id, callback - - destroyAllDocs: (project_id, callback = (err) ->) -> - MongoManager.getProjectsDocs project_id, {include_deleted: true}, {_id: 1}, (err, docs) -> - if err? - logger.err err:err, project_id:project_id, "error getting project's docs" - return callback(err) - else if !docs? - return callback() - jobs = _.map docs, (doc) -> - (cb)-> - DocArchive.destroyDoc(project_id, doc._id, cb) - async.parallelLimit jobs, 5, callback - - destroyDoc: (project_id, doc_id, callback)-> - logger.log project_id: project_id, doc_id: doc_id, "removing doc from mongo and s3" - MongoManager.findDoc project_id, doc_id, {inS3: 1}, (error, doc) -> - return callback error if error? - return callback new Errors.NotFoundError("Doc not found in Mongo") unless doc? - if doc.inS3 == true - DocArchive._deleteDocFromS3 project_id, doc_id, (err) -> - return err if err? - MongoManager.destroyDoc doc_id, callback - else - MongoManager.destroyDoc doc_id, callback - - _deleteDocFromS3: (project_id, doc_id, callback) -> - try - options = DocArchive.buildS3Options(project_id+"/"+doc_id) - catch e - return callback e - options.json = true - request.del options, (err, res, body)-> - if err? || res.statusCode != 204 - logger.err err:err, res:res, project_id:project_id, doc_id:doc_id, "something went wrong deleting doc from aws" - return callback new Error("Error in S3 request") - callback() - - _s3DocToMongoDoc: (doc, callback = (error, mongo_doc) ->) -> - mongo_doc = {} - if doc.schema_v == 1 and doc.lines? - mongo_doc.lines = doc.lines - if doc.ranges? - mongo_doc.ranges = RangeManager.jsonRangesToMongo(doc.ranges) - else if doc instanceof Array - mongo_doc.lines = doc - else - return callback(new Error("I don't understand the doc format in s3")) - return callback null, mongo_doc - - _mongoDocToS3Doc: (doc, callback = (error, s3_doc) ->) -> - if !doc.lines? - return callback(new Error("doc has no lines")) - json = JSON.stringify({ - lines: doc.lines - ranges: doc.ranges - schema_v: 1 - }) - if json.indexOf("\u0000") != -1 - error = new Error("null bytes detected") - logger.err {err: error, doc, json}, error.message - return callback(error) - return callback null, json - - buildS3Options: (key)-> - if !settings.docstore.s3? - throw new Error("S3 settings are not configured") - return { - aws: - key: settings.docstore.s3.key - secret: settings.docstore.s3.secret - bucket: settings.docstore.s3.bucket - timeout: thirtySeconds - uri:"https://#{settings.docstore.s3.bucket}.s3.amazonaws.com/#{key}" + archiveDoc(project_id, doc, callback){ + let options; + logger.log({project_id, doc_id: doc._id}, "sending doc to s3"); + try { + options = DocArchive.buildS3Options(project_id+"/"+doc._id); + } catch (e) { + return callback(e); } + return DocArchive._mongoDocToS3Doc(doc, function(error, json_doc) { + if (error != null) { return callback(error); } + options.body = json_doc; + options.headers = + {'Content-Type': "application/json"}; + return request.put(options, function(err, res) { + if ((err != null) || (res.statusCode !== 200)) { + logger.err({err, res, project_id, doc_id: doc._id, statusCode: (res != null ? res.statusCode : undefined)}, "something went wrong archiving doc in aws"); + return callback(new Error("Error in S3 request")); + } + const md5lines = crypto.createHash("md5").update(json_doc, "utf8").digest("hex"); + const md5response = res.headers.etag.toString().replace(/\"/g, ''); + if (md5lines !== md5response) { + logger.err({responseMD5:md5response, linesMD5:md5lines, project_id, doc_id: (doc != null ? doc._id : undefined)}, "err in response md5 from s3"); + return callback(new Error("Error in S3 md5 response")); + } + return MongoManager.markDocAsArchived(doc._id, doc.rev, function(err) { + if (err != null) { return callback(err); } + return callback(); + }); + }); + }); + }, + + unArchiveAllDocs(project_id, callback) { + if (callback == null) { callback = function(err) {}; } + return MongoManager.getArchivedProjectDocs(project_id, function(err, docs) { + if (err != null) { + logger.err({err, project_id}, "error unarchiving all docs"); + return callback(err); + } else if ((docs == null)) { + return callback(new Errors.NotFoundError(`No docs for project ${project_id}`)); + } + const jobs = _.map(docs, doc => (function(cb) { + if ((doc.inS3 == null)) { + return cb(); + } else { + return DocArchive.unarchiveDoc(project_id, doc._id, cb); + } + })); + return async.parallelLimit(jobs, 5, callback); + }); + }, + + unarchiveDoc(project_id, doc_id, callback){ + let options; + logger.log({project_id, doc_id}, "getting doc from s3"); + try { + options = DocArchive.buildS3Options(project_id+"/"+doc_id); + } catch (e) { + return callback(e); + } + options.json = true; + return request.get(options, function(err, res, doc){ + if ((err != null) || (res.statusCode !== 200)) { + logger.err({err, res, project_id, doc_id}, "something went wrong unarchiving doc from aws"); + return callback(new Errors.NotFoundError("Error in S3 request")); + } + return DocArchive._s3DocToMongoDoc(doc, function(error, mongo_doc) { + if (error != null) { return callback(error); } + return MongoManager.upsertIntoDocCollection(project_id, doc_id.toString(), mongo_doc, function(err) { + if (err != null) { return callback(err); } + logger.log({project_id, doc_id}, "deleting doc from s3"); + return DocArchive._deleteDocFromS3(project_id, doc_id, callback); + }); + }); + }); + }, + + destroyAllDocs(project_id, callback) { + if (callback == null) { callback = function(err) {}; } + return MongoManager.getProjectsDocs(project_id, {include_deleted: true}, {_id: 1}, function(err, docs) { + if (err != null) { + logger.err({err, project_id}, "error getting project's docs"); + return callback(err); + } else if ((docs == null)) { + return callback(); + } + const jobs = _.map(docs, doc => cb => DocArchive.destroyDoc(project_id, doc._id, cb)); + return async.parallelLimit(jobs, 5, callback); + }); + }, + + destroyDoc(project_id, doc_id, callback){ + logger.log({project_id, doc_id}, "removing doc from mongo and s3"); + return MongoManager.findDoc(project_id, doc_id, {inS3: 1}, function(error, doc) { + if (error != null) { return callback(error); } + if (doc == null) { return callback(new Errors.NotFoundError("Doc not found in Mongo")); } + if (doc.inS3 === true) { + return DocArchive._deleteDocFromS3(project_id, doc_id, function(err) { + if (err != null) { return err; } + return MongoManager.destroyDoc(doc_id, callback); + }); + } else { + return MongoManager.destroyDoc(doc_id, callback); + } + }); + }, + + _deleteDocFromS3(project_id, doc_id, callback) { + let options; + try { + options = DocArchive.buildS3Options(project_id+"/"+doc_id); + } catch (e) { + return callback(e); + } + options.json = true; + return request.del(options, function(err, res, body){ + if ((err != null) || (res.statusCode !== 204)) { + logger.err({err, res, project_id, doc_id}, "something went wrong deleting doc from aws"); + return callback(new Error("Error in S3 request")); + } + return callback(); + }); + }, + + _s3DocToMongoDoc(doc, callback) { + if (callback == null) { callback = function(error, mongo_doc) {}; } + const mongo_doc = {}; + if ((doc.schema_v === 1) && (doc.lines != null)) { + mongo_doc.lines = doc.lines; + if (doc.ranges != null) { + mongo_doc.ranges = RangeManager.jsonRangesToMongo(doc.ranges); + } + } else if (doc instanceof Array) { + mongo_doc.lines = doc; + } else { + return callback(new Error("I don't understand the doc format in s3")); + } + return callback(null, mongo_doc); + }, + + _mongoDocToS3Doc(doc, callback) { + if (callback == null) { callback = function(error, s3_doc) {}; } + if ((doc.lines == null)) { + return callback(new Error("doc has no lines")); + } + const json = JSON.stringify({ + lines: doc.lines, + ranges: doc.ranges, + schema_v: 1 + }); + if (json.indexOf("\u0000") !== -1) { + const error = new Error("null bytes detected"); + logger.err({err: error, doc, json}, error.message); + return callback(error); + } + return callback(null, json); + }, + + buildS3Options(key){ + if ((settings.docstore.s3 == null)) { + throw new Error("S3 settings are not configured"); + } + return { + aws: { + key: settings.docstore.s3.key, + secret: settings.docstore.s3.secret, + bucket: settings.docstore.s3.bucket + }, + timeout: thirtySeconds, + uri:`https://${settings.docstore.s3.bucket}.s3.amazonaws.com/${key}` + }; + } +}); diff --git a/services/docstore/app/coffee/DocManager.js b/services/docstore/app/coffee/DocManager.js index be55a23e44..8bb86d8eb3 100644 --- a/services/docstore/app/coffee/DocManager.js +++ b/services/docstore/app/coffee/DocManager.js @@ -1,130 +1,184 @@ -MongoManager = require "./MongoManager" -Errors = require "./Errors" -logger = require "logger-sharelatex" -_ = require "underscore" -DocArchive = require "./DocArchiveManager" -RangeManager = require "./RangeManager" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let DocManager; +const MongoManager = require("./MongoManager"); +const Errors = require("./Errors"); +const logger = require("logger-sharelatex"); +const _ = require("underscore"); +const DocArchive = require("./DocArchiveManager"); +const RangeManager = require("./RangeManager"); -module.exports = DocManager = +module.exports = (DocManager = { - # TODO: For historical reasons, the doc version is currently stored in the docOps - # collection (which is all that this collection contains). In future, we should - # migrate this version property to be part of the docs collection, to guarantee - # consitency between lines and version when writing/reading, and for a simpler schema. - _getDoc: (project_id, doc_id, filter = {}, callback = (error, doc) ->) -> - if filter.inS3 != true - return callback("must include inS3 when getting doc") + // TODO: For historical reasons, the doc version is currently stored in the docOps + // collection (which is all that this collection contains). In future, we should + // migrate this version property to be part of the docs collection, to guarantee + // consitency between lines and version when writing/reading, and for a simpler schema. + _getDoc(project_id, doc_id, filter, callback) { + if (filter == null) { filter = {}; } + if (callback == null) { callback = function(error, doc) {}; } + if (filter.inS3 !== true) { + return callback("must include inS3 when getting doc"); + } - MongoManager.findDoc project_id, doc_id, filter, (err, doc)-> - if err? - return callback(err) - else if !doc? - return callback new Errors.NotFoundError("No such doc: #{doc_id} in project #{project_id}") - else if doc?.inS3 - DocArchive.unarchiveDoc project_id, doc_id, (err)-> - if err? - logger.err err:err, project_id:project_id, doc_id:doc_id, "error unarchiving doc" - return callback(err) - DocManager._getDoc project_id, doc_id, filter, callback - else - if filter.version - MongoManager.getDocVersion doc_id, (error, version) -> - return callback(error) if error? - doc.version = version - callback err, doc - else - callback err, doc + return MongoManager.findDoc(project_id, doc_id, filter, function(err, doc){ + if (err != null) { + return callback(err); + } else if ((doc == null)) { + return callback(new Errors.NotFoundError(`No such doc: ${doc_id} in project ${project_id}`)); + } else if ((doc != null ? doc.inS3 : undefined)) { + return DocArchive.unarchiveDoc(project_id, doc_id, function(err){ + if (err != null) { + logger.err({err, project_id, doc_id}, "error unarchiving doc"); + return callback(err); + } + return DocManager._getDoc(project_id, doc_id, filter, callback); + }); + } else { + if (filter.version) { + return MongoManager.getDocVersion(doc_id, function(error, version) { + if (error != null) { return callback(error); } + doc.version = version; + return callback(err, doc); + }); + } else { + return callback(err, doc); + } + } + }); + }, - checkDocExists: (project_id, doc_id, callback = (err, exists)->)-> - DocManager._getDoc project_id, doc_id, {_id:1, inS3:true}, (err, doc)-> - if err? - return callback(err) - callback(err, doc?) + checkDocExists(project_id, doc_id, callback){ + if (callback == null) { callback = function(err, exists){}; } + return DocManager._getDoc(project_id, doc_id, {_id:1, inS3:true}, function(err, doc){ + if (err != null) { + return callback(err); + } + return callback(err, (doc != null)); + }); + }, - getFullDoc: (project_id, doc_id, callback = (err, doc)->)-> - DocManager._getDoc project_id, doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}, (err, doc)-> - if err? - return callback(err) - callback(err, doc) + getFullDoc(project_id, doc_id, callback){ + if (callback == null) { callback = function(err, doc){}; } + return DocManager._getDoc(project_id, doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}, function(err, doc){ + if (err != null) { + return callback(err); + } + return callback(err, doc); + }); + }, - getDocLines: (project_id, doc_id, callback = (err, doc)->)-> - DocManager._getDoc project_id, doc_id, {lines:true, inS3:true}, (err, doc)-> - if err? - return callback(err) - callback(err, doc) + getDocLines(project_id, doc_id, callback){ + if (callback == null) { callback = function(err, doc){}; } + return DocManager._getDoc(project_id, doc_id, {lines:true, inS3:true}, function(err, doc){ + if (err != null) { + return callback(err); + } + return callback(err, doc); + }); + }, - getAllNonDeletedDocs: (project_id, filter, callback = (error, docs) ->) -> - DocArchive.unArchiveAllDocs project_id, (error) -> - if error? - return callback(error) - MongoManager.getProjectsDocs project_id, {include_deleted: false}, filter, (error, docs) -> - if err? - return callback(error) - else if !docs? - return callback new Errors.NotFoundError("No docs for project #{project_id}") - else - return callback(null, docs) + getAllNonDeletedDocs(project_id, filter, callback) { + if (callback == null) { callback = function(error, docs) {}; } + return DocArchive.unArchiveAllDocs(project_id, function(error) { + if (error != null) { + return callback(error); + } + return MongoManager.getProjectsDocs(project_id, {include_deleted: false}, filter, function(error, docs) { + if (typeof err !== 'undefined' && err !== null) { + return callback(error); + } else if ((docs == null)) { + return callback(new Errors.NotFoundError(`No docs for project ${project_id}`)); + } else { + return callback(null, docs); + } + }); + }); + }, - updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, modified, rev) ->) -> - if !lines? or !version? or !ranges? - return callback(new Error("no lines, version or ranges provided")) + updateDoc(project_id, doc_id, lines, version, ranges, callback) { + if (callback == null) { callback = function(error, modified, rev) {}; } + if ((lines == null) || (version == null) || (ranges == null)) { + return callback(new Error("no lines, version or ranges provided")); + } - DocManager._getDoc project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}, (err, doc)-> - if err? and !(err instanceof Errors.NotFoundError) - logger.err project_id: project_id, doc_id: doc_id, err:err, "error getting document for update" - return callback(err) + return DocManager._getDoc(project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}, function(err, doc){ + let updateLines, updateRanges, updateVersion; + if ((err != null) && !(err instanceof Errors.NotFoundError)) { + logger.err({project_id, doc_id, err}, "error getting document for update"); + return callback(err); + } - ranges = RangeManager.jsonRangesToMongo(ranges) + ranges = RangeManager.jsonRangesToMongo(ranges); - if !doc? - # If the document doesn't exist, we'll make sure to create/update all parts of it. - updateLines = true - updateVersion = true - updateRanges = true - else - updateLines = not _.isEqual(doc.lines, lines) - updateVersion = (doc.version != version) - updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges) + if ((doc == null)) { + // If the document doesn't exist, we'll make sure to create/update all parts of it. + updateLines = true; + updateVersion = true; + updateRanges = true; + } else { + updateLines = !_.isEqual(doc.lines, lines); + updateVersion = (doc.version !== version); + updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges); + } - modified = false - rev = doc?.rev || 0 + let modified = false; + let rev = (doc != null ? doc.rev : undefined) || 0; - updateLinesAndRangesIfNeeded = (cb) -> - if updateLines or updateRanges - update = {} - if updateLines - update.lines = lines - if updateRanges - update.ranges = ranges - logger.log { project_id, doc_id }, "updating doc lines and ranges" + const updateLinesAndRangesIfNeeded = function(cb) { + if (updateLines || updateRanges) { + const update = {}; + if (updateLines) { + update.lines = lines; + } + if (updateRanges) { + update.ranges = ranges; + } + logger.log({ project_id, doc_id }, "updating doc lines and ranges"); - modified = true - rev += 1 # rev will be incremented in mongo by MongoManager.upsertIntoDocCollection - MongoManager.upsertIntoDocCollection project_id, doc_id, update, cb - else - logger.log { project_id, doc_id, }, "doc lines have not changed - not updating" - cb() + modified = true; + rev += 1; // rev will be incremented in mongo by MongoManager.upsertIntoDocCollection + return MongoManager.upsertIntoDocCollection(project_id, doc_id, update, cb); + } else { + logger.log({ project_id, doc_id, }, "doc lines have not changed - not updating"); + return cb(); + } + }; - updateVersionIfNeeded = (cb) -> - if updateVersion - logger.log { project_id, doc_id, oldVersion: doc?.version, newVersion: version }, "updating doc version" - modified = true - MongoManager.setDocVersion doc_id, version, cb - else - logger.log { project_id, doc_id, version }, "doc version has not changed - not updating" - cb() + const updateVersionIfNeeded = function(cb) { + if (updateVersion) { + logger.log({ project_id, doc_id, oldVersion: (doc != null ? doc.version : undefined), newVersion: version }, "updating doc version"); + modified = true; + return MongoManager.setDocVersion(doc_id, version, cb); + } else { + logger.log({ project_id, doc_id, version }, "doc version has not changed - not updating"); + return cb(); + } + }; - updateLinesAndRangesIfNeeded (error) -> - return callback(error) if error? - updateVersionIfNeeded (error) -> - return callback(error) if error? - callback null, modified, rev + return updateLinesAndRangesIfNeeded(function(error) { + if (error != null) { return callback(error); } + return updateVersionIfNeeded(function(error) { + if (error != null) { return callback(error); } + return callback(null, modified, rev); + }); + }); + }); + }, - deleteDoc: (project_id, doc_id, callback = (error) ->) -> - DocManager.checkDocExists project_id, doc_id, (error, exists) -> - return callback(error) if error? - return callback new Errors.NotFoundError("No such project/doc to delete: #{project_id}/#{doc_id}") if !exists - MongoManager.markDocAsDeleted project_id, doc_id, callback + deleteDoc(project_id, doc_id, callback) { + if (callback == null) { callback = function(error) {}; } + return DocManager.checkDocExists(project_id, doc_id, function(error, exists) { + if (error != null) { return callback(error); } + if (!exists) { return callback(new Errors.NotFoundError(`No such project/doc to delete: ${project_id}/${doc_id}`)); } + return MongoManager.markDocAsDeleted(project_id, doc_id, callback); + }); + } +}); diff --git a/services/docstore/app/coffee/Errors.js b/services/docstore/app/coffee/Errors.js index 4a29822efc..1345cc0f86 100644 --- a/services/docstore/app/coffee/Errors.js +++ b/services/docstore/app/coffee/Errors.js @@ -1,10 +1,12 @@ -NotFoundError = (message) -> - error = new Error(message) - error.name = "NotFoundError" - error.__proto__ = NotFoundError.prototype - return error -NotFoundError.prototype.__proto__ = Error.prototype +let Errors; +var NotFoundError = function(message) { + const error = new Error(message); + error.name = "NotFoundError"; + error.__proto__ = NotFoundError.prototype; + return error; +}; +NotFoundError.prototype.__proto__ = Error.prototype; -module.exports = Errors = - NotFoundError: NotFoundError +module.exports = (Errors = + {NotFoundError}); diff --git a/services/docstore/app/coffee/HealthChecker.js b/services/docstore/app/coffee/HealthChecker.js index 4280f8aa58..1da8c770d0 100644 --- a/services/docstore/app/coffee/HealthChecker.js +++ b/services/docstore/app/coffee/HealthChecker.js @@ -1,44 +1,59 @@ -{db, ObjectId} = require "./mongojs" -request = require("request") -async = require("async") -_ = require("underscore") -crypto = require("crypto") -settings = require("settings-sharelatex") -port = settings.internal.docstore.port -logger = require "logger-sharelatex" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const {db, ObjectId} = require("./mongojs"); +const request = require("request"); +const async = require("async"); +const _ = require("underscore"); +const crypto = require("crypto"); +const settings = require("settings-sharelatex"); +const { + port +} = settings.internal.docstore; +const logger = require("logger-sharelatex"); -module.exports = - check : (callback)-> - doc_id = ObjectId() - project_id = ObjectId(settings.docstore.healthCheck.project_id) - url = "http://localhost:#{port}/project/#{project_id}/doc/#{doc_id}" - lines = ["smoke test - delete me", "#{crypto.randomBytes(32).toString("hex")}"] - getOpts = -> {url:url, timeout:3000} - logger.log lines:lines, url:url, doc_id:doc_id, project_id:project_id, "running health check" - jobs = [ - (cb)-> - opts = getOpts() - opts.json = {lines: lines, version: 42, ranges: {}} - request.post(opts, cb) - (cb)-> - opts = getOpts() - opts.json = true - request.get opts, (err, res, body)-> - if err? - logger.err err:err, "docstore returned a error in health check get" - cb(err) - else if !res? - cb("no response from docstore with get check") - else if res?.statusCode != 200 - cb("status code not 200, its #{res.statusCode}") - else if _.isEqual(body?.lines, lines) and body?._id == doc_id.toString() - cb() - else - cb("health check lines not equal #{body.lines} != #{lines}") - (cb)-> - db.docs.remove {_id: doc_id, project_id: project_id}, cb - (cb)-> - db.docOps.remove {doc_id: doc_id}, cb - ] - async.series jobs, callback +module.exports = { + check(callback){ + const doc_id = ObjectId(); + const project_id = ObjectId(settings.docstore.healthCheck.project_id); + const url = `http://localhost:${port}/project/${project_id}/doc/${doc_id}`; + const lines = ["smoke test - delete me", `${crypto.randomBytes(32).toString("hex")}`]; + const getOpts = () => ({ + url, + timeout:3000 + }); + logger.log({lines, url, doc_id, project_id}, "running health check"); + const jobs = [ + function(cb){ + const opts = getOpts(); + opts.json = {lines, version: 42, ranges: {}}; + return request.post(opts, cb); + }, + function(cb){ + const opts = getOpts(); + opts.json = true; + return request.get(opts, function(err, res, body){ + if (err != null) { + logger.err({err}, "docstore returned a error in health check get"); + return cb(err); + } else if ((res == null)) { + return cb("no response from docstore with get check"); + } else if ((res != null ? res.statusCode : undefined) !== 200) { + return cb(`status code not 200, its ${res.statusCode}`); + } else if (_.isEqual(body != null ? body.lines : undefined, lines) && ((body != null ? body._id : undefined) === doc_id.toString())) { + return cb(); + } else { + return cb(`health check lines not equal ${body.lines} != ${lines}`); + } + }); + }, + cb => db.docs.remove({_id: doc_id, project_id}, cb), + cb => db.docOps.remove({doc_id}, cb) + ]; + return async.series(jobs, callback); + } +}; diff --git a/services/docstore/app/coffee/HttpController.js b/services/docstore/app/coffee/HttpController.js index cec535e1cd..3d87086a0d 100644 --- a/services/docstore/app/coffee/HttpController.js +++ b/services/docstore/app/coffee/HttpController.js @@ -1,144 +1,224 @@ -DocManager = require "./DocManager" -logger = require "logger-sharelatex" -DocArchive = require "./DocArchiveManager" -HealthChecker = require "./HealthChecker" -Settings = require "settings-sharelatex" +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let HttpController; +const DocManager = require("./DocManager"); +const logger = require("logger-sharelatex"); +const DocArchive = require("./DocArchiveManager"); +const HealthChecker = require("./HealthChecker"); +const Settings = require("settings-sharelatex"); -module.exports = HttpController = - getDoc: (req, res, next = (error) ->) -> - project_id = req.params.project_id - doc_id = req.params.doc_id - include_deleted = req.query?.include_deleted == "true" - logger.log project_id: project_id, doc_id: doc_id, "getting doc" - DocManager.getFullDoc project_id, doc_id, (error, doc) -> - return next(error) if error? - logger.log {doc_id, project_id}, "got doc" - if !doc? - res.send 404 - else if doc.deleted && !include_deleted - res.send 404 - else - res.json HttpController._buildDocView(doc) - - getRawDoc: (req, res, next = (error)->)-> - project_id = req.params.project_id - doc_id = req.params.doc_id - logger.log project_id: project_id, doc_id: doc_id, "getting raw doc" - DocManager.getDocLines project_id, doc_id, (error, doc) -> - return next(error) if error? - if !doc? - res.send 404 - else - res.setHeader('content-type', 'text/plain') - res.send HttpController._buildRawDocView(doc) - - getAllDocs: (req, res, next = (error) ->) -> - project_id = req.params.project_id - logger.log project_id: project_id, "getting all docs" - DocManager.getAllNonDeletedDocs project_id, {lines: true, rev: true}, (error, docs = []) -> - return next(error) if error? - res.json HttpController._buildDocsArrayView(project_id, docs) - - getAllRanges: (req, res, next = (error) ->) -> - project_id = req.params.project_id - logger.log {project_id}, "getting all ranges" - DocManager.getAllNonDeletedDocs project_id, {ranges: true}, (error, docs = []) -> - return next(error) if error? - res.json HttpController._buildDocsArrayView(project_id, docs) - - updateDoc: (req, res, next = (error) ->) -> - project_id = req.params.project_id - doc_id = req.params.doc_id - lines = req.body?.lines - version = req.body?.version - ranges = req.body?.ranges - - if !lines? or lines not instanceof Array - logger.error project_id: project_id, doc_id: doc_id, "no doc lines provided" - res.send 400 # Bad Request - return - - if !version? or typeof version is not "number" - logger.error project_id: project_id, doc_id: doc_id, "no doc version provided" - res.send 400 # Bad Request - return - - if !ranges? - logger.error project_id: project_id, doc_id: doc_id, "no doc ranges provided" - res.send 400 # Bad Request - return - - bodyLength = lines.reduce( - (len, line) => line.length + len - 0 - ) - if bodyLength > Settings.max_doc_length - logger.error project_id: project_id, doc_id: doc_id, bodyLength: bodyLength, "document body too large" - res.status(413).send("document body too large") - return - - logger.log project_id: project_id, doc_id: doc_id, "got http request to update doc" - DocManager.updateDoc project_id, doc_id, lines, version, ranges, (error, modified, rev) -> - return next(error) if error? - res.json { - modified: modified - rev: rev +module.exports = (HttpController = { + getDoc(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + const { + doc_id + } = req.params; + const include_deleted = (req.query != null ? req.query.include_deleted : undefined) === "true"; + logger.log({project_id, doc_id}, "getting doc"); + return DocManager.getFullDoc(project_id, doc_id, function(error, doc) { + if (error != null) { return next(error); } + logger.log({doc_id, project_id}, "got doc"); + if ((doc == null)) { + return res.send(404); + } else if (doc.deleted && !include_deleted) { + return res.send(404); + } else { + return res.json(HttpController._buildDocView(doc)); } + }); + }, - deleteDoc: (req, res, next = (error) ->) -> - project_id = req.params.project_id - doc_id = req.params.doc_id - logger.log project_id: project_id, doc_id: doc_id, "deleting doc" - DocManager.deleteDoc project_id, doc_id, (error) -> - return next(error) if error? - res.send 204 + getRawDoc(req, res, next){ + if (next == null) { next = function(error){}; } + const { + project_id + } = req.params; + const { + doc_id + } = req.params; + logger.log({project_id, doc_id}, "getting raw doc"); + return DocManager.getDocLines(project_id, doc_id, function(error, doc) { + if (error != null) { return next(error); } + if ((doc == null)) { + return res.send(404); + } else { + res.setHeader('content-type', 'text/plain'); + return res.send(HttpController._buildRawDocView(doc)); + } + }); + }, - _buildDocView: (doc) -> - doc_view = { _id: doc._id?.toString() } - for attribute in ["lines", "rev", "version", "ranges", "deleted"] - if doc[attribute]? - doc_view[attribute] = doc[attribute] - return doc_view - - _buildRawDocView: (doc)-> - return (doc?.lines or []).join("\n") + getAllDocs(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + logger.log({project_id}, "getting all docs"); + return DocManager.getAllNonDeletedDocs(project_id, {lines: true, rev: true}, function(error, docs) { + if (docs == null) { docs = []; } + if (error != null) { return next(error); } + return res.json(HttpController._buildDocsArrayView(project_id, docs)); + }); + }, - _buildDocsArrayView: (project_id, docs) -> - docViews = [] - for doc in docs - if doc? # There can end up being null docs for some reason :( (probably a race condition) - docViews.push HttpController._buildDocView(doc) - else - logger.error err: new Error("null doc"), project_id: project_id, "encountered null doc" - return docViews + getAllRanges(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + logger.log({project_id}, "getting all ranges"); + return DocManager.getAllNonDeletedDocs(project_id, {ranges: true}, function(error, docs) { + if (docs == null) { docs = []; } + if (error != null) { return next(error); } + return res.json(HttpController._buildDocsArrayView(project_id, docs)); + }); + }, - archiveAllDocs: (req, res, next = (error) ->) -> - project_id = req.params.project_id - logger.log project_id: project_id, "archiving all docs" - DocArchive.archiveAllDocs project_id, (error) -> - return next(error) if error? - res.send 204 + updateDoc(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + const { + doc_id + } = req.params; + const lines = req.body != null ? req.body.lines : undefined; + const version = req.body != null ? req.body.version : undefined; + const ranges = req.body != null ? req.body.ranges : undefined; - unArchiveAllDocs: (req, res, next = (error) ->) -> - project_id = req.params.project_id - logger.log project_id: project_id, "unarchiving all docs" - DocArchive.unArchiveAllDocs project_id, (error) -> - return next(error) if error? - res.send 200 + if ((lines == null) || !(lines instanceof Array)) { + logger.error({project_id, doc_id}, "no doc lines provided"); + res.send(400); // Bad Request + return; + } + + if ((version == null) || (typeof version === !"number")) { + logger.error({project_id, doc_id}, "no doc version provided"); + res.send(400); // Bad Request + return; + } + + if ((ranges == null)) { + logger.error({project_id, doc_id}, "no doc ranges provided"); + res.send(400); // Bad Request + return; + } - destroyAllDocs: (req, res, next = (error) ->) -> - project_id = req.params.project_id - logger.log project_id: project_id, "destroying all docs" - DocArchive.destroyAllDocs project_id, (error) -> - return next(error) if error? - res.send 204 + const bodyLength = lines.reduce( + (len, line) => line.length + len, + 0 + ); + if (bodyLength > Settings.max_doc_length) { + logger.error({project_id, doc_id, bodyLength}, "document body too large"); + res.status(413).send("document body too large"); + return; + } - healthCheck: (req, res)-> - HealthChecker.check (err)-> - if err? - logger.err err:err, "error performing health check" - res.send 500 - else - res.send 200 + logger.log({project_id, doc_id}, "got http request to update doc"); + return DocManager.updateDoc(project_id, doc_id, lines, version, ranges, function(error, modified, rev) { + if (error != null) { return next(error); } + return res.json({ + modified, + rev + }); + }); + }, + + deleteDoc(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + const { + doc_id + } = req.params; + logger.log({project_id, doc_id}, "deleting doc"); + return DocManager.deleteDoc(project_id, doc_id, function(error) { + if (error != null) { return next(error); } + return res.send(204); + }); + }, + + _buildDocView(doc) { + const doc_view = { _id: (doc._id != null ? doc._id.toString() : undefined) }; + for (let attribute of ["lines", "rev", "version", "ranges", "deleted"]) { + if (doc[attribute] != null) { + doc_view[attribute] = doc[attribute]; + } + } + return doc_view; + }, + + _buildRawDocView(doc){ + return ((doc != null ? doc.lines : undefined) || []).join("\n"); + }, + + _buildDocsArrayView(project_id, docs) { + const docViews = []; + for (let doc of Array.from(docs)) { + if (doc != null) { // There can end up being null docs for some reason :( (probably a race condition) + docViews.push(HttpController._buildDocView(doc)); + } else { + logger.error({err: new Error("null doc"), project_id}, "encountered null doc"); + } + } + return docViews; + }, + + archiveAllDocs(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + logger.log({project_id}, "archiving all docs"); + return DocArchive.archiveAllDocs(project_id, function(error) { + if (error != null) { return next(error); } + return res.send(204); + }); + }, + + unArchiveAllDocs(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + logger.log({project_id}, "unarchiving all docs"); + return DocArchive.unArchiveAllDocs(project_id, function(error) { + if (error != null) { return next(error); } + return res.send(200); + }); + }, + + destroyAllDocs(req, res, next) { + if (next == null) { next = function(error) {}; } + const { + project_id + } = req.params; + logger.log({project_id}, "destroying all docs"); + return DocArchive.destroyAllDocs(project_id, function(error) { + if (error != null) { return next(error); } + return res.send(204); + }); + }, + + healthCheck(req, res){ + return HealthChecker.check(function(err){ + if (err != null) { + logger.err({err}, "error performing health check"); + return res.send(500); + } else { + return res.send(200); + } + }); + } +}); diff --git a/services/docstore/app/coffee/MongoManager.js b/services/docstore/app/coffee/MongoManager.js index 3bd9eb34c5..0fc304b79f 100644 --- a/services/docstore/app/coffee/MongoManager.js +++ b/services/docstore/app/coffee/MongoManager.js @@ -1,85 +1,118 @@ -{db, ObjectId} = require "./mongojs" -logger = require 'logger-sharelatex' -metrics = require 'metrics-sharelatex' +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let MongoManager; +const {db, ObjectId} = require("./mongojs"); +const logger = require('logger-sharelatex'); +const metrics = require('metrics-sharelatex'); -module.exports = MongoManager = +module.exports = (MongoManager = { - findDoc: (project_id, doc_id, filter, callback = (error, doc) ->) -> - db.docs.find {_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, filter, (error, docs = []) -> - callback error, docs[0] + findDoc(project_id, doc_id, filter, callback) { + if (callback == null) { callback = function(error, doc) {}; } + return db.docs.find({_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, filter, function(error, docs) { + if (docs == null) { docs = []; } + return callback(error, docs[0]); + }); + }, - getProjectsDocs: (project_id, options = {include_deleted: true}, filter, callback)-> - query = {project_id: ObjectId(project_id.toString())} - if !options.include_deleted - query.deleted = { $ne: true } - db.docs.find query, filter, callback + getProjectsDocs(project_id, options, filter, callback){ + if (options == null) { options = {include_deleted: true}; } + const query = {project_id: ObjectId(project_id.toString())}; + if (!options.include_deleted) { + query.deleted = { $ne: true }; + } + return db.docs.find(query, filter, callback); + }, - getArchivedProjectDocs: (project_id, callback)-> - query = - project_id: ObjectId(project_id.toString()) + getArchivedProjectDocs(project_id, callback){ + const query = { + project_id: ObjectId(project_id.toString()), inS3: true - db.docs.find query, {}, callback + }; + return db.docs.find(query, {}, callback); + }, - upsertIntoDocCollection: (project_id, doc_id, updates, callback)-> - update = - $set: updates - $inc: + upsertIntoDocCollection(project_id, doc_id, updates, callback){ + const update = { + $set: updates, + $inc: { rev: 1 - $unset: + }, + $unset: { inS3: true - update.$set["project_id"] = ObjectId(project_id) - db.docs.update _id: ObjectId(doc_id), update, {upsert: true}, callback + } + }; + update.$set["project_id"] = ObjectId(project_id); + return db.docs.update({_id: ObjectId(doc_id)}, update, {upsert: true}, callback); + }, - markDocAsDeleted: (project_id, doc_id, callback)-> - db.docs.update { + markDocAsDeleted(project_id, doc_id, callback){ + return db.docs.update({ _id: ObjectId(doc_id), project_id: ObjectId(project_id) }, { $set: { deleted: true } - }, callback + }, callback); + }, - markDocAsArchived: (doc_id, rev, callback)-> - update = - $set: {} + markDocAsArchived(doc_id, rev, callback){ + const update = { + $set: {}, $unset: {} - update.$set["inS3"] = true - update.$unset["lines"] = true - update.$unset["ranges"] = true - query = - _id: doc_id - rev: rev - db.docs.update query, update, (err)-> - callback(err) + }; + update.$set["inS3"] = true; + update.$unset["lines"] = true; + update.$unset["ranges"] = true; + const query = { + _id: doc_id, + rev + }; + return db.docs.update(query, update, err => callback(err)); + }, - getDocVersion: (doc_id, callback = (error, version) ->) -> - db.docOps.find { + getDocVersion(doc_id, callback) { + if (callback == null) { callback = function(error, version) {}; } + return db.docOps.find({ doc_id: ObjectId(doc_id) }, { version: 1 - }, (error, docs) -> - return callback(error) if error? - if docs.length < 1 or !docs[0].version? - return callback null, 0 - else - return callback null, docs[0].version + }, function(error, docs) { + if (error != null) { return callback(error); } + if ((docs.length < 1) || (docs[0].version == null)) { + return callback(null, 0); + } else { + return callback(null, docs[0].version); + } + }); + }, - setDocVersion: (doc_id, version, callback = (error) ->) -> - db.docOps.update { + setDocVersion(doc_id, version, callback) { + if (callback == null) { callback = function(error) {}; } + return db.docOps.update({ doc_id: ObjectId(doc_id) }, { - $set: version: version + $set: { version + } }, { upsert: true - }, callback + }, callback); + }, - destroyDoc: (doc_id, callback) -> - db.docs.remove { + destroyDoc(doc_id, callback) { + return db.docs.remove({ _id: ObjectId(doc_id) - }, (err) -> - return callback(err) if err? - db.docOps.remove { + }, function(err) { + if (err != null) { return callback(err); } + return db.docOps.remove({ doc_id: ObjectId(doc_id) - }, callback + }, callback); + }); + } +}); [ 'findDoc', @@ -89,5 +122,4 @@ module.exports = MongoManager = 'markDocAsArchived', 'getDocVersion', 'setDocVersion' -].map (method) -> - metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger) +].map(method => metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger)); diff --git a/services/docstore/app/coffee/RangeManager.js b/services/docstore/app/coffee/RangeManager.js index 4867ffbe19..6973ebd259 100644 --- a/services/docstore/app/coffee/RangeManager.js +++ b/services/docstore/app/coffee/RangeManager.js @@ -1,40 +1,61 @@ -_ = require "underscore" -{ObjectId} = require("./mongojs") +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let RangeManager; +const _ = require("underscore"); +const {ObjectId} = require("./mongojs"); -module.exports = RangeManager = - shouldUpdateRanges: (doc_ranges, incoming_ranges) -> - if !incoming_ranges? - throw new Error("expected incoming_ranges") +module.exports = (RangeManager = { + shouldUpdateRanges(doc_ranges, incoming_ranges) { + if ((incoming_ranges == null)) { + throw new Error("expected incoming_ranges"); + } - # If the ranges are empty, we don't store them in the DB, so set - # doc_ranges to an empty object as default, since this is was the - # incoming_ranges will be for an empty range set. - if !doc_ranges? - doc_ranges = {} + // If the ranges are empty, we don't store them in the DB, so set + // doc_ranges to an empty object as default, since this is was the + // incoming_ranges will be for an empty range set. + if ((doc_ranges == null)) { + doc_ranges = {}; + } - return not _.isEqual(doc_ranges, incoming_ranges) + return !_.isEqual(doc_ranges, incoming_ranges); + }, - jsonRangesToMongo: (ranges) -> - return null if !ranges? + jsonRangesToMongo(ranges) { + if ((ranges == null)) { return null; } - updateMetadata = (metadata) -> - if metadata?.ts? - metadata.ts = new Date(metadata.ts) - if metadata?.user_id? - metadata.user_id = RangeManager._safeObjectId(metadata.user_id) + const updateMetadata = function(metadata) { + if ((metadata != null ? metadata.ts : undefined) != null) { + metadata.ts = new Date(metadata.ts); + } + if ((metadata != null ? metadata.user_id : undefined) != null) { + return metadata.user_id = RangeManager._safeObjectId(metadata.user_id); + } + }; - for change in ranges.changes or [] - change.id = RangeManager._safeObjectId(change.id) - updateMetadata(change.metadata) - for comment in ranges.comments or [] - comment.id = RangeManager._safeObjectId(comment.id) - if comment.op?.t? - comment.op.t = RangeManager._safeObjectId(comment.op.t) - updateMetadata(comment.metadata) - return ranges + for (let change of Array.from(ranges.changes || [])) { + change.id = RangeManager._safeObjectId(change.id); + updateMetadata(change.metadata); + } + for (let comment of Array.from(ranges.comments || [])) { + comment.id = RangeManager._safeObjectId(comment.id); + if ((comment.op != null ? comment.op.t : undefined) != null) { + comment.op.t = RangeManager._safeObjectId(comment.op.t); + } + updateMetadata(comment.metadata); + } + return ranges; + }, - _safeObjectId: (data) -> - try - return ObjectId(data) - catch error - return data \ No newline at end of file + _safeObjectId(data) { + try { + return ObjectId(data); + } catch (error) { + return data; + } + } +}); \ No newline at end of file diff --git a/services/docstore/app/coffee/mongojs.js b/services/docstore/app/coffee/mongojs.js index 0153c3cfcd..fd0d6cde8b 100644 --- a/services/docstore/app/coffee/mongojs.js +++ b/services/docstore/app/coffee/mongojs.js @@ -1,7 +1,8 @@ -Settings = require "settings-sharelatex" -mongojs = require "mongojs" -db = mongojs(Settings.mongo.url, ["docs", "docOps"]) -module.exports = - db: db +const Settings = require("settings-sharelatex"); +const mongojs = require("mongojs"); +const db = mongojs(Settings.mongo.url, ["docs", "docOps"]); +module.exports = { + db, ObjectId: mongojs.ObjectId +}; From d31a747c72c70726ce9776639a032b4f5d0ad9f0 Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:01:47 +0000 Subject: [PATCH 215/349] decaffeinate: Run post-processing cleanups on DocArchiveManager.coffee and 7 other files --- services/docstore/app/coffee/DocArchiveManager.js | 7 +++++++ services/docstore/app/coffee/DocManager.js | 9 +++++++++ services/docstore/app/coffee/Errors.js | 6 ++++++ services/docstore/app/coffee/HealthChecker.js | 6 ++++++ services/docstore/app/coffee/HttpController.js | 11 +++++++++-- services/docstore/app/coffee/MongoManager.js | 14 ++++++++++---- services/docstore/app/coffee/RangeManager.js | 10 ++++++++-- services/docstore/app/coffee/mongojs.js | 2 ++ 8 files changed, 57 insertions(+), 8 deletions(-) diff --git a/services/docstore/app/coffee/DocArchiveManager.js b/services/docstore/app/coffee/DocArchiveManager.js index e3c048558e..636d8b155b 100644 --- a/services/docstore/app/coffee/DocArchiveManager.js +++ b/services/docstore/app/coffee/DocArchiveManager.js @@ -1,3 +1,10 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-useless-escape, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns diff --git a/services/docstore/app/coffee/DocManager.js b/services/docstore/app/coffee/DocManager.js index 8bb86d8eb3..bddb1ee937 100644 --- a/services/docstore/app/coffee/DocManager.js +++ b/services/docstore/app/coffee/DocManager.js @@ -1,3 +1,12 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-dupe-keys, + no-undef, + standard/no-callback-literal, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns diff --git a/services/docstore/app/coffee/Errors.js b/services/docstore/app/coffee/Errors.js index 1345cc0f86..a000b8f1f4 100644 --- a/services/docstore/app/coffee/Errors.js +++ b/services/docstore/app/coffee/Errors.js @@ -1,3 +1,9 @@ +/* eslint-disable + no-proto, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. let Errors; var NotFoundError = function(message) { const error = new Error(message); diff --git a/services/docstore/app/coffee/HealthChecker.js b/services/docstore/app/coffee/HealthChecker.js index 1da8c770d0..143e797f4e 100644 --- a/services/docstore/app/coffee/HealthChecker.js +++ b/services/docstore/app/coffee/HealthChecker.js @@ -1,3 +1,9 @@ +/* eslint-disable + camelcase, + standard/no-callback-literal, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns diff --git a/services/docstore/app/coffee/HttpController.js b/services/docstore/app/coffee/HttpController.js index 3d87086a0d..7f6eb9e728 100644 --- a/services/docstore/app/coffee/HttpController.js +++ b/services/docstore/app/coffee/HttpController.js @@ -1,3 +1,10 @@ +/* eslint-disable + camelcase, + handle-callback-err, + valid-typeof, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from @@ -150,7 +157,7 @@ module.exports = (HttpController = { _buildDocView(doc) { const doc_view = { _id: (doc._id != null ? doc._id.toString() : undefined) }; - for (let attribute of ["lines", "rev", "version", "ranges", "deleted"]) { + for (const attribute of ["lines", "rev", "version", "ranges", "deleted"]) { if (doc[attribute] != null) { doc_view[attribute] = doc[attribute]; } @@ -164,7 +171,7 @@ module.exports = (HttpController = { _buildDocsArrayView(project_id, docs) { const docViews = []; - for (let doc of Array.from(docs)) { + for (const doc of Array.from(docs)) { if (doc != null) { // There can end up being null docs for some reason :( (probably a race condition) docViews.push(HttpController._buildDocView(doc)); } else { diff --git a/services/docstore/app/coffee/MongoManager.js b/services/docstore/app/coffee/MongoManager.js index 0fc304b79f..27918267f9 100644 --- a/services/docstore/app/coffee/MongoManager.js +++ b/services/docstore/app/coffee/MongoManager.js @@ -1,3 +1,9 @@ +/* eslint-disable + camelcase, + handle-callback-err, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -46,7 +52,7 @@ module.exports = (MongoManager = { inS3: true } }; - update.$set["project_id"] = ObjectId(project_id); + update.$set.project_id = ObjectId(project_id); return db.docs.update({_id: ObjectId(doc_id)}, update, {upsert: true}, callback); }, @@ -64,9 +70,9 @@ module.exports = (MongoManager = { $set: {}, $unset: {} }; - update.$set["inS3"] = true; - update.$unset["lines"] = true; - update.$unset["ranges"] = true; + update.$set.inS3 = true; + update.$unset.lines = true; + update.$unset.ranges = true; const query = { _id: doc_id, rev diff --git a/services/docstore/app/coffee/RangeManager.js b/services/docstore/app/coffee/RangeManager.js index 6973ebd259..cee272a8e6 100644 --- a/services/docstore/app/coffee/RangeManager.js +++ b/services/docstore/app/coffee/RangeManager.js @@ -1,3 +1,9 @@ +/* eslint-disable + camelcase, + no-return-assign, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from @@ -37,11 +43,11 @@ module.exports = (RangeManager = { } }; - for (let change of Array.from(ranges.changes || [])) { + for (const change of Array.from(ranges.changes || [])) { change.id = RangeManager._safeObjectId(change.id); updateMetadata(change.metadata); } - for (let comment of Array.from(ranges.comments || [])) { + for (const comment of Array.from(ranges.comments || [])) { comment.id = RangeManager._safeObjectId(comment.id); if ((comment.op != null ? comment.op.t : undefined) != null) { comment.op.t = RangeManager._safeObjectId(comment.op.t); diff --git a/services/docstore/app/coffee/mongojs.js b/services/docstore/app/coffee/mongojs.js index fd0d6cde8b..8000129ae5 100644 --- a/services/docstore/app/coffee/mongojs.js +++ b/services/docstore/app/coffee/mongojs.js @@ -1,3 +1,5 @@ +// TODO: This file was created by bulk-decaffeinate. +// Sanity-check the conversion and remove this comment. const Settings = require("settings-sharelatex"); const mongojs = require("mongojs"); const db = mongojs(Settings.mongo.url, ["docs", "docOps"]); From c1805978c4c14699fe4cc9728746bd2bdfa1ae86 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:02:01 +0000 Subject: [PATCH 216/349] decaffeinate: rename app/coffee dir to app/js --- services/docstore/app/{coffee => js}/DocArchiveManager.js | 0 services/docstore/app/{coffee => js}/DocManager.js | 0 services/docstore/app/{coffee => js}/Errors.js | 0 services/docstore/app/{coffee => js}/HealthChecker.js | 0 services/docstore/app/{coffee => js}/HttpController.js | 0 services/docstore/app/{coffee => js}/MongoManager.js | 0 services/docstore/app/{coffee => js}/RangeManager.js | 0 services/docstore/app/{coffee => js}/mongojs.js | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename services/docstore/app/{coffee => js}/DocArchiveManager.js (100%) rename services/docstore/app/{coffee => js}/DocManager.js (100%) rename services/docstore/app/{coffee => js}/Errors.js (100%) rename services/docstore/app/{coffee => js}/HealthChecker.js (100%) rename services/docstore/app/{coffee => js}/HttpController.js (100%) rename services/docstore/app/{coffee => js}/MongoManager.js (100%) rename services/docstore/app/{coffee => js}/RangeManager.js (100%) rename services/docstore/app/{coffee => js}/mongojs.js (100%) diff --git a/services/docstore/app/coffee/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js similarity index 100% rename from services/docstore/app/coffee/DocArchiveManager.js rename to services/docstore/app/js/DocArchiveManager.js diff --git a/services/docstore/app/coffee/DocManager.js b/services/docstore/app/js/DocManager.js similarity index 100% rename from services/docstore/app/coffee/DocManager.js rename to services/docstore/app/js/DocManager.js diff --git a/services/docstore/app/coffee/Errors.js b/services/docstore/app/js/Errors.js similarity index 100% rename from services/docstore/app/coffee/Errors.js rename to services/docstore/app/js/Errors.js diff --git a/services/docstore/app/coffee/HealthChecker.js b/services/docstore/app/js/HealthChecker.js similarity index 100% rename from services/docstore/app/coffee/HealthChecker.js rename to services/docstore/app/js/HealthChecker.js diff --git a/services/docstore/app/coffee/HttpController.js b/services/docstore/app/js/HttpController.js similarity index 100% rename from services/docstore/app/coffee/HttpController.js rename to services/docstore/app/js/HttpController.js diff --git a/services/docstore/app/coffee/MongoManager.js b/services/docstore/app/js/MongoManager.js similarity index 100% rename from services/docstore/app/coffee/MongoManager.js rename to services/docstore/app/js/MongoManager.js diff --git a/services/docstore/app/coffee/RangeManager.js b/services/docstore/app/js/RangeManager.js similarity index 100% rename from services/docstore/app/coffee/RangeManager.js rename to services/docstore/app/js/RangeManager.js diff --git a/services/docstore/app/coffee/mongojs.js b/services/docstore/app/js/mongojs.js similarity index 100% rename from services/docstore/app/coffee/mongojs.js rename to services/docstore/app/js/mongojs.js From fb931e206c95bf1788534dac5bb9839b6229bf3e Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:02:21 +0000 Subject: [PATCH 217/349] prettier: convert app/js decaffeinated files to Prettier format --- services/docstore/app/js/DocArchiveManager.js | 461 ++++++++++-------- services/docstore/app/js/DocManager.js | 426 +++++++++------- services/docstore/app/js/Errors.js | 18 +- services/docstore/app/js/HealthChecker.js | 107 ++-- services/docstore/app/js/HttpController.js | 434 +++++++++-------- services/docstore/app/js/MongoManager.js | 263 +++++----- services/docstore/app/js/RangeManager.js | 104 ++-- services/docstore/app/js/mongojs.js | 13 +- 8 files changed, 1039 insertions(+), 787 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 636d8b155b..af1af21957 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -11,205 +11,282 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let DocArchive; -const MongoManager = require("./MongoManager"); -const Errors = require("./Errors"); -const logger = require("logger-sharelatex"); -const _ = require("underscore"); -const async = require("async"); -const settings = require("settings-sharelatex"); -const request = require("request"); -const crypto = require("crypto"); -const RangeManager = require("./RangeManager"); -const thirtySeconds = 30 * 1000; +let DocArchive +const MongoManager = require('./MongoManager') +const Errors = require('./Errors') +const logger = require('logger-sharelatex') +const _ = require('underscore') +const async = require('async') +const settings = require('settings-sharelatex') +const request = require('request') +const crypto = require('crypto') +const RangeManager = require('./RangeManager') +const thirtySeconds = 30 * 1000 -module.exports = (DocArchive = { +module.exports = DocArchive = { + archiveAllDocs(project_id, callback) { + if (callback == null) { + callback = function(err, docs) {} + } + return MongoManager.getProjectsDocs( + project_id, + { include_deleted: true }, + { lines: true, ranges: true, rev: true, inS3: true }, + function(err, docs) { + if (err != null) { + return callback(err) + } else if (docs == null) { + return callback( + new Errors.NotFoundError(`No docs for project ${project_id}`) + ) + } + docs = _.filter(docs, doc => doc.inS3 !== true) + const jobs = _.map(docs, doc => cb => + DocArchive.archiveDoc(project_id, doc, cb) + ) + return async.parallelLimit(jobs, 5, callback) + } + ) + }, - archiveAllDocs(project_id, callback) { - if (callback == null) { callback = function(err, docs) {}; } - return MongoManager.getProjectsDocs(project_id, {include_deleted: true}, {lines: true, ranges: true, rev: true, inS3: true}, function(err, docs) { - if (err != null) { - return callback(err); - } else if ((docs == null)) { - return callback(new Errors.NotFoundError(`No docs for project ${project_id}`)); - } - docs = _.filter(docs, doc => doc.inS3 !== true); - const jobs = _.map(docs, doc => cb => DocArchive.archiveDoc(project_id, doc, cb)); - return async.parallelLimit(jobs, 5, callback); - }); - }, + archiveDoc(project_id, doc, callback) { + let options + logger.log({ project_id, doc_id: doc._id }, 'sending doc to s3') + try { + options = DocArchive.buildS3Options(project_id + '/' + doc._id) + } catch (e) { + return callback(e) + } + return DocArchive._mongoDocToS3Doc(doc, function(error, json_doc) { + if (error != null) { + return callback(error) + } + options.body = json_doc + options.headers = { 'Content-Type': 'application/json' } + return request.put(options, function(err, res) { + if (err != null || res.statusCode !== 200) { + logger.err( + { + err, + res, + project_id, + doc_id: doc._id, + statusCode: res != null ? res.statusCode : undefined + }, + 'something went wrong archiving doc in aws' + ) + return callback(new Error('Error in S3 request')) + } + const md5lines = crypto + .createHash('md5') + .update(json_doc, 'utf8') + .digest('hex') + const md5response = res.headers.etag.toString().replace(/\"/g, '') + if (md5lines !== md5response) { + logger.err( + { + responseMD5: md5response, + linesMD5: md5lines, + project_id, + doc_id: doc != null ? doc._id : undefined + }, + 'err in response md5 from s3' + ) + return callback(new Error('Error in S3 md5 response')) + } + return MongoManager.markDocAsArchived(doc._id, doc.rev, function(err) { + if (err != null) { + return callback(err) + } + return callback() + }) + }) + }) + }, + unArchiveAllDocs(project_id, callback) { + if (callback == null) { + callback = function(err) {} + } + return MongoManager.getArchivedProjectDocs(project_id, function(err, docs) { + if (err != null) { + logger.err({ err, project_id }, 'error unarchiving all docs') + return callback(err) + } else if (docs == null) { + return callback( + new Errors.NotFoundError(`No docs for project ${project_id}`) + ) + } + const jobs = _.map( + docs, + doc => + function(cb) { + if (doc.inS3 == null) { + return cb() + } else { + return DocArchive.unarchiveDoc(project_id, doc._id, cb) + } + } + ) + return async.parallelLimit(jobs, 5, callback) + }) + }, - archiveDoc(project_id, doc, callback){ - let options; - logger.log({project_id, doc_id: doc._id}, "sending doc to s3"); - try { - options = DocArchive.buildS3Options(project_id+"/"+doc._id); - } catch (e) { - return callback(e); - } - return DocArchive._mongoDocToS3Doc(doc, function(error, json_doc) { - if (error != null) { return callback(error); } - options.body = json_doc; - options.headers = - {'Content-Type': "application/json"}; - return request.put(options, function(err, res) { - if ((err != null) || (res.statusCode !== 200)) { - logger.err({err, res, project_id, doc_id: doc._id, statusCode: (res != null ? res.statusCode : undefined)}, "something went wrong archiving doc in aws"); - return callback(new Error("Error in S3 request")); - } - const md5lines = crypto.createHash("md5").update(json_doc, "utf8").digest("hex"); - const md5response = res.headers.etag.toString().replace(/\"/g, ''); - if (md5lines !== md5response) { - logger.err({responseMD5:md5response, linesMD5:md5lines, project_id, doc_id: (doc != null ? doc._id : undefined)}, "err in response md5 from s3"); - return callback(new Error("Error in S3 md5 response")); - } - return MongoManager.markDocAsArchived(doc._id, doc.rev, function(err) { - if (err != null) { return callback(err); } - return callback(); - }); - }); - }); - }, + unarchiveDoc(project_id, doc_id, callback) { + let options + logger.log({ project_id, doc_id }, 'getting doc from s3') + try { + options = DocArchive.buildS3Options(project_id + '/' + doc_id) + } catch (e) { + return callback(e) + } + options.json = true + return request.get(options, function(err, res, doc) { + if (err != null || res.statusCode !== 200) { + logger.err( + { err, res, project_id, doc_id }, + 'something went wrong unarchiving doc from aws' + ) + return callback(new Errors.NotFoundError('Error in S3 request')) + } + return DocArchive._s3DocToMongoDoc(doc, function(error, mongo_doc) { + if (error != null) { + return callback(error) + } + return MongoManager.upsertIntoDocCollection( + project_id, + doc_id.toString(), + mongo_doc, + function(err) { + if (err != null) { + return callback(err) + } + logger.log({ project_id, doc_id }, 'deleting doc from s3') + return DocArchive._deleteDocFromS3(project_id, doc_id, callback) + } + ) + }) + }) + }, - unArchiveAllDocs(project_id, callback) { - if (callback == null) { callback = function(err) {}; } - return MongoManager.getArchivedProjectDocs(project_id, function(err, docs) { - if (err != null) { - logger.err({err, project_id}, "error unarchiving all docs"); - return callback(err); - } else if ((docs == null)) { - return callback(new Errors.NotFoundError(`No docs for project ${project_id}`)); - } - const jobs = _.map(docs, doc => (function(cb) { - if ((doc.inS3 == null)) { - return cb(); - } else { - return DocArchive.unarchiveDoc(project_id, doc._id, cb); - } - })); - return async.parallelLimit(jobs, 5, callback); - }); - }, + destroyAllDocs(project_id, callback) { + if (callback == null) { + callback = function(err) {} + } + return MongoManager.getProjectsDocs( + project_id, + { include_deleted: true }, + { _id: 1 }, + function(err, docs) { + if (err != null) { + logger.err({ err, project_id }, "error getting project's docs") + return callback(err) + } else if (docs == null) { + return callback() + } + const jobs = _.map(docs, doc => cb => + DocArchive.destroyDoc(project_id, doc._id, cb) + ) + return async.parallelLimit(jobs, 5, callback) + } + ) + }, - unarchiveDoc(project_id, doc_id, callback){ - let options; - logger.log({project_id, doc_id}, "getting doc from s3"); - try { - options = DocArchive.buildS3Options(project_id+"/"+doc_id); - } catch (e) { - return callback(e); - } - options.json = true; - return request.get(options, function(err, res, doc){ - if ((err != null) || (res.statusCode !== 200)) { - logger.err({err, res, project_id, doc_id}, "something went wrong unarchiving doc from aws"); - return callback(new Errors.NotFoundError("Error in S3 request")); - } - return DocArchive._s3DocToMongoDoc(doc, function(error, mongo_doc) { - if (error != null) { return callback(error); } - return MongoManager.upsertIntoDocCollection(project_id, doc_id.toString(), mongo_doc, function(err) { - if (err != null) { return callback(err); } - logger.log({project_id, doc_id}, "deleting doc from s3"); - return DocArchive._deleteDocFromS3(project_id, doc_id, callback); - }); - }); - }); - }, + destroyDoc(project_id, doc_id, callback) { + logger.log({ project_id, doc_id }, 'removing doc from mongo and s3') + return MongoManager.findDoc(project_id, doc_id, { inS3: 1 }, function( + error, + doc + ) { + if (error != null) { + return callback(error) + } + if (doc == null) { + return callback(new Errors.NotFoundError('Doc not found in Mongo')) + } + if (doc.inS3 === true) { + return DocArchive._deleteDocFromS3(project_id, doc_id, function(err) { + if (err != null) { + return err + } + return MongoManager.destroyDoc(doc_id, callback) + }) + } else { + return MongoManager.destroyDoc(doc_id, callback) + } + }) + }, - destroyAllDocs(project_id, callback) { - if (callback == null) { callback = function(err) {}; } - return MongoManager.getProjectsDocs(project_id, {include_deleted: true}, {_id: 1}, function(err, docs) { - if (err != null) { - logger.err({err, project_id}, "error getting project's docs"); - return callback(err); - } else if ((docs == null)) { - return callback(); - } - const jobs = _.map(docs, doc => cb => DocArchive.destroyDoc(project_id, doc._id, cb)); - return async.parallelLimit(jobs, 5, callback); - }); - }, + _deleteDocFromS3(project_id, doc_id, callback) { + let options + try { + options = DocArchive.buildS3Options(project_id + '/' + doc_id) + } catch (e) { + return callback(e) + } + options.json = true + return request.del(options, function(err, res, body) { + if (err != null || res.statusCode !== 204) { + logger.err( + { err, res, project_id, doc_id }, + 'something went wrong deleting doc from aws' + ) + return callback(new Error('Error in S3 request')) + } + return callback() + }) + }, - destroyDoc(project_id, doc_id, callback){ - logger.log({project_id, doc_id}, "removing doc from mongo and s3"); - return MongoManager.findDoc(project_id, doc_id, {inS3: 1}, function(error, doc) { - if (error != null) { return callback(error); } - if (doc == null) { return callback(new Errors.NotFoundError("Doc not found in Mongo")); } - if (doc.inS3 === true) { - return DocArchive._deleteDocFromS3(project_id, doc_id, function(err) { - if (err != null) { return err; } - return MongoManager.destroyDoc(doc_id, callback); - }); - } else { - return MongoManager.destroyDoc(doc_id, callback); - } - }); - }, + _s3DocToMongoDoc(doc, callback) { + if (callback == null) { + callback = function(error, mongo_doc) {} + } + const mongo_doc = {} + if (doc.schema_v === 1 && doc.lines != null) { + mongo_doc.lines = doc.lines + if (doc.ranges != null) { + mongo_doc.ranges = RangeManager.jsonRangesToMongo(doc.ranges) + } + } else if (doc instanceof Array) { + mongo_doc.lines = doc + } else { + return callback(new Error("I don't understand the doc format in s3")) + } + return callback(null, mongo_doc) + }, - _deleteDocFromS3(project_id, doc_id, callback) { - let options; - try { - options = DocArchive.buildS3Options(project_id+"/"+doc_id); - } catch (e) { - return callback(e); - } - options.json = true; - return request.del(options, function(err, res, body){ - if ((err != null) || (res.statusCode !== 204)) { - logger.err({err, res, project_id, doc_id}, "something went wrong deleting doc from aws"); - return callback(new Error("Error in S3 request")); - } - return callback(); - }); - }, + _mongoDocToS3Doc(doc, callback) { + if (callback == null) { + callback = function(error, s3_doc) {} + } + if (doc.lines == null) { + return callback(new Error('doc has no lines')) + } + const json = JSON.stringify({ + lines: doc.lines, + ranges: doc.ranges, + schema_v: 1 + }) + if (json.indexOf('\u0000') !== -1) { + const error = new Error('null bytes detected') + logger.err({ err: error, doc, json }, error.message) + return callback(error) + } + return callback(null, json) + }, - _s3DocToMongoDoc(doc, callback) { - if (callback == null) { callback = function(error, mongo_doc) {}; } - const mongo_doc = {}; - if ((doc.schema_v === 1) && (doc.lines != null)) { - mongo_doc.lines = doc.lines; - if (doc.ranges != null) { - mongo_doc.ranges = RangeManager.jsonRangesToMongo(doc.ranges); - } - } else if (doc instanceof Array) { - mongo_doc.lines = doc; - } else { - return callback(new Error("I don't understand the doc format in s3")); - } - return callback(null, mongo_doc); - }, - - _mongoDocToS3Doc(doc, callback) { - if (callback == null) { callback = function(error, s3_doc) {}; } - if ((doc.lines == null)) { - return callback(new Error("doc has no lines")); - } - const json = JSON.stringify({ - lines: doc.lines, - ranges: doc.ranges, - schema_v: 1 - }); - if (json.indexOf("\u0000") !== -1) { - const error = new Error("null bytes detected"); - logger.err({err: error, doc, json}, error.message); - return callback(error); - } - return callback(null, json); - }, - - buildS3Options(key){ - if ((settings.docstore.s3 == null)) { - throw new Error("S3 settings are not configured"); - } - return { - aws: { - key: settings.docstore.s3.key, - secret: settings.docstore.s3.secret, - bucket: settings.docstore.s3.bucket - }, - timeout: thirtySeconds, - uri:`https://${settings.docstore.s3.bucket}.s3.amazonaws.com/${key}` - }; - } -}); + buildS3Options(key) { + if (settings.docstore.s3 == null) { + throw new Error('S3 settings are not configured') + } + return { + aws: { + key: settings.docstore.s3.key, + secret: settings.docstore.s3.secret, + bucket: settings.docstore.s3.bucket + }, + timeout: thirtySeconds, + uri: `https://${settings.docstore.s3.bucket}.s3.amazonaws.com/${key}` + } + } +} diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index bddb1ee937..15a782861b 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -13,181 +13,277 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let DocManager; -const MongoManager = require("./MongoManager"); -const Errors = require("./Errors"); -const logger = require("logger-sharelatex"); -const _ = require("underscore"); -const DocArchive = require("./DocArchiveManager"); -const RangeManager = require("./RangeManager"); +let DocManager +const MongoManager = require('./MongoManager') +const Errors = require('./Errors') +const logger = require('logger-sharelatex') +const _ = require('underscore') +const DocArchive = require('./DocArchiveManager') +const RangeManager = require('./RangeManager') -module.exports = (DocManager = { - +module.exports = DocManager = { + // TODO: For historical reasons, the doc version is currently stored in the docOps + // collection (which is all that this collection contains). In future, we should + // migrate this version property to be part of the docs collection, to guarantee + // consitency between lines and version when writing/reading, and for a simpler schema. + _getDoc(project_id, doc_id, filter, callback) { + if (filter == null) { + filter = {} + } + if (callback == null) { + callback = function(error, doc) {} + } + if (filter.inS3 !== true) { + return callback('must include inS3 when getting doc') + } - // TODO: For historical reasons, the doc version is currently stored in the docOps - // collection (which is all that this collection contains). In future, we should - // migrate this version property to be part of the docs collection, to guarantee - // consitency between lines and version when writing/reading, and for a simpler schema. - _getDoc(project_id, doc_id, filter, callback) { - if (filter == null) { filter = {}; } - if (callback == null) { callback = function(error, doc) {}; } - if (filter.inS3 !== true) { - return callback("must include inS3 when getting doc"); - } + return MongoManager.findDoc(project_id, doc_id, filter, function(err, doc) { + if (err != null) { + return callback(err) + } else if (doc == null) { + return callback( + new Errors.NotFoundError( + `No such doc: ${doc_id} in project ${project_id}` + ) + ) + } else if (doc != null ? doc.inS3 : undefined) { + return DocArchive.unarchiveDoc(project_id, doc_id, function(err) { + if (err != null) { + logger.err({ err, project_id, doc_id }, 'error unarchiving doc') + return callback(err) + } + return DocManager._getDoc(project_id, doc_id, filter, callback) + }) + } else { + if (filter.version) { + return MongoManager.getDocVersion(doc_id, function(error, version) { + if (error != null) { + return callback(error) + } + doc.version = version + return callback(err, doc) + }) + } else { + return callback(err, doc) + } + } + }) + }, - return MongoManager.findDoc(project_id, doc_id, filter, function(err, doc){ - if (err != null) { - return callback(err); - } else if ((doc == null)) { - return callback(new Errors.NotFoundError(`No such doc: ${doc_id} in project ${project_id}`)); - } else if ((doc != null ? doc.inS3 : undefined)) { - return DocArchive.unarchiveDoc(project_id, doc_id, function(err){ - if (err != null) { - logger.err({err, project_id, doc_id}, "error unarchiving doc"); - return callback(err); - } - return DocManager._getDoc(project_id, doc_id, filter, callback); - }); - } else { - if (filter.version) { - return MongoManager.getDocVersion(doc_id, function(error, version) { - if (error != null) { return callback(error); } - doc.version = version; - return callback(err, doc); - }); - } else { - return callback(err, doc); - } - } - }); - }, + checkDocExists(project_id, doc_id, callback) { + if (callback == null) { + callback = function(err, exists) {} + } + return DocManager._getDoc( + project_id, + doc_id, + { _id: 1, inS3: true }, + function(err, doc) { + if (err != null) { + return callback(err) + } + return callback(err, doc != null) + } + ) + }, - checkDocExists(project_id, doc_id, callback){ - if (callback == null) { callback = function(err, exists){}; } - return DocManager._getDoc(project_id, doc_id, {_id:1, inS3:true}, function(err, doc){ - if (err != null) { - return callback(err); - } - return callback(err, (doc != null)); - }); - }, + getFullDoc(project_id, doc_id, callback) { + if (callback == null) { + callback = function(err, doc) {} + } + return DocManager._getDoc( + project_id, + doc_id, + { + lines: true, + rev: true, + deleted: true, + version: true, + ranges: true, + inS3: true + }, + function(err, doc) { + if (err != null) { + return callback(err) + } + return callback(err, doc) + } + ) + }, - getFullDoc(project_id, doc_id, callback){ - if (callback == null) { callback = function(err, doc){}; } - return DocManager._getDoc(project_id, doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}, function(err, doc){ - if (err != null) { - return callback(err); - } - return callback(err, doc); - }); - }, + getDocLines(project_id, doc_id, callback) { + if (callback == null) { + callback = function(err, doc) {} + } + return DocManager._getDoc( + project_id, + doc_id, + { lines: true, inS3: true }, + function(err, doc) { + if (err != null) { + return callback(err) + } + return callback(err, doc) + } + ) + }, + getAllNonDeletedDocs(project_id, filter, callback) { + if (callback == null) { + callback = function(error, docs) {} + } + return DocArchive.unArchiveAllDocs(project_id, function(error) { + if (error != null) { + return callback(error) + } + return MongoManager.getProjectsDocs( + project_id, + { include_deleted: false }, + filter, + function(error, docs) { + if (typeof err !== 'undefined' && err !== null) { + return callback(error) + } else if (docs == null) { + return callback( + new Errors.NotFoundError(`No docs for project ${project_id}`) + ) + } else { + return callback(null, docs) + } + } + ) + }) + }, - getDocLines(project_id, doc_id, callback){ - if (callback == null) { callback = function(err, doc){}; } - return DocManager._getDoc(project_id, doc_id, {lines:true, inS3:true}, function(err, doc){ - if (err != null) { - return callback(err); - } - return callback(err, doc); - }); - }, + updateDoc(project_id, doc_id, lines, version, ranges, callback) { + if (callback == null) { + callback = function(error, modified, rev) {} + } + if (lines == null || version == null || ranges == null) { + return callback(new Error('no lines, version or ranges provided')) + } - getAllNonDeletedDocs(project_id, filter, callback) { - if (callback == null) { callback = function(error, docs) {}; } - return DocArchive.unArchiveAllDocs(project_id, function(error) { - if (error != null) { - return callback(error); - } - return MongoManager.getProjectsDocs(project_id, {include_deleted: false}, filter, function(error, docs) { - if (typeof err !== 'undefined' && err !== null) { - return callback(error); - } else if ((docs == null)) { - return callback(new Errors.NotFoundError(`No docs for project ${project_id}`)); - } else { - return callback(null, docs); - } - }); - }); - }, + return DocManager._getDoc( + project_id, + doc_id, + { + version: true, + rev: true, + lines: true, + version: true, + ranges: true, + inS3: true + }, + function(err, doc) { + let updateLines, updateRanges, updateVersion + if (err != null && !(err instanceof Errors.NotFoundError)) { + logger.err( + { project_id, doc_id, err }, + 'error getting document for update' + ) + return callback(err) + } - updateDoc(project_id, doc_id, lines, version, ranges, callback) { - if (callback == null) { callback = function(error, modified, rev) {}; } - if ((lines == null) || (version == null) || (ranges == null)) { - return callback(new Error("no lines, version or ranges provided")); - } - - return DocManager._getDoc(project_id, doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}, function(err, doc){ - let updateLines, updateRanges, updateVersion; - if ((err != null) && !(err instanceof Errors.NotFoundError)) { - logger.err({project_id, doc_id, err}, "error getting document for update"); - return callback(err); - } - - ranges = RangeManager.jsonRangesToMongo(ranges); + ranges = RangeManager.jsonRangesToMongo(ranges) - if ((doc == null)) { - // If the document doesn't exist, we'll make sure to create/update all parts of it. - updateLines = true; - updateVersion = true; - updateRanges = true; - } else { - updateLines = !_.isEqual(doc.lines, lines); - updateVersion = (doc.version !== version); - updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges); - } - - let modified = false; - let rev = (doc != null ? doc.rev : undefined) || 0; + if (doc == null) { + // If the document doesn't exist, we'll make sure to create/update all parts of it. + updateLines = true + updateVersion = true + updateRanges = true + } else { + updateLines = !_.isEqual(doc.lines, lines) + updateVersion = doc.version !== version + updateRanges = RangeManager.shouldUpdateRanges(doc.ranges, ranges) + } - const updateLinesAndRangesIfNeeded = function(cb) { - if (updateLines || updateRanges) { - const update = {}; - if (updateLines) { - update.lines = lines; - } - if (updateRanges) { - update.ranges = ranges; - } - logger.log({ project_id, doc_id }, "updating doc lines and ranges"); - - modified = true; - rev += 1; // rev will be incremented in mongo by MongoManager.upsertIntoDocCollection - return MongoManager.upsertIntoDocCollection(project_id, doc_id, update, cb); - } else { - logger.log({ project_id, doc_id, }, "doc lines have not changed - not updating"); - return cb(); - } - }; - - const updateVersionIfNeeded = function(cb) { - if (updateVersion) { - logger.log({ project_id, doc_id, oldVersion: (doc != null ? doc.version : undefined), newVersion: version }, "updating doc version"); - modified = true; - return MongoManager.setDocVersion(doc_id, version, cb); - } else { - logger.log({ project_id, doc_id, version }, "doc version has not changed - not updating"); - return cb(); - } - }; - - return updateLinesAndRangesIfNeeded(function(error) { - if (error != null) { return callback(error); } - return updateVersionIfNeeded(function(error) { - if (error != null) { return callback(error); } - return callback(null, modified, rev); - }); - }); - }); - }, + let modified = false + let rev = (doc != null ? doc.rev : undefined) || 0 - deleteDoc(project_id, doc_id, callback) { - if (callback == null) { callback = function(error) {}; } - return DocManager.checkDocExists(project_id, doc_id, function(error, exists) { - if (error != null) { return callback(error); } - if (!exists) { return callback(new Errors.NotFoundError(`No such project/doc to delete: ${project_id}/${doc_id}`)); } - return MongoManager.markDocAsDeleted(project_id, doc_id, callback); - }); - } -}); + const updateLinesAndRangesIfNeeded = function(cb) { + if (updateLines || updateRanges) { + const update = {} + if (updateLines) { + update.lines = lines + } + if (updateRanges) { + update.ranges = ranges + } + logger.log({ project_id, doc_id }, 'updating doc lines and ranges') + modified = true + rev += 1 // rev will be incremented in mongo by MongoManager.upsertIntoDocCollection + return MongoManager.upsertIntoDocCollection( + project_id, + doc_id, + update, + cb + ) + } else { + logger.log( + { project_id, doc_id }, + 'doc lines have not changed - not updating' + ) + return cb() + } + } + + const updateVersionIfNeeded = function(cb) { + if (updateVersion) { + logger.log( + { + project_id, + doc_id, + oldVersion: doc != null ? doc.version : undefined, + newVersion: version + }, + 'updating doc version' + ) + modified = true + return MongoManager.setDocVersion(doc_id, version, cb) + } else { + logger.log( + { project_id, doc_id, version }, + 'doc version has not changed - not updating' + ) + return cb() + } + } + + return updateLinesAndRangesIfNeeded(function(error) { + if (error != null) { + return callback(error) + } + return updateVersionIfNeeded(function(error) { + if (error != null) { + return callback(error) + } + return callback(null, modified, rev) + }) + }) + } + ) + }, + + deleteDoc(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error) {} + } + return DocManager.checkDocExists(project_id, doc_id, function( + error, + exists + ) { + if (error != null) { + return callback(error) + } + if (!exists) { + return callback( + new Errors.NotFoundError( + `No such project/doc to delete: ${project_id}/${doc_id}` + ) + ) + } + return MongoManager.markDocAsDeleted(project_id, doc_id, callback) + }) + } +} diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index a000b8f1f4..f3bc8e37eb 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -4,15 +4,13 @@ */ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. -let Errors; +let Errors var NotFoundError = function(message) { - const error = new Error(message); - error.name = "NotFoundError"; - error.__proto__ = NotFoundError.prototype; - return error; -}; -NotFoundError.prototype.__proto__ = Error.prototype; - -module.exports = (Errors = - {NotFoundError}); + const error = new Error(message) + error.name = 'NotFoundError' + error.__proto__ = NotFoundError.prototype + return error +} +NotFoundError.prototype.__proto__ = Error.prototype +module.exports = Errors = { NotFoundError } diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 143e797f4e..87b16a9951 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -10,56 +10,59 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const {db, ObjectId} = require("./mongojs"); -const request = require("request"); -const async = require("async"); -const _ = require("underscore"); -const crypto = require("crypto"); -const settings = require("settings-sharelatex"); -const { - port -} = settings.internal.docstore; -const logger = require("logger-sharelatex"); +const { db, ObjectId } = require('./mongojs') +const request = require('request') +const async = require('async') +const _ = require('underscore') +const crypto = require('crypto') +const settings = require('settings-sharelatex') +const { port } = settings.internal.docstore +const logger = require('logger-sharelatex') - -module.exports = { - check(callback){ - const doc_id = ObjectId(); - const project_id = ObjectId(settings.docstore.healthCheck.project_id); - const url = `http://localhost:${port}/project/${project_id}/doc/${doc_id}`; - const lines = ["smoke test - delete me", `${crypto.randomBytes(32).toString("hex")}`]; - const getOpts = () => ({ - url, - timeout:3000 - }); - logger.log({lines, url, doc_id, project_id}, "running health check"); - const jobs = [ - function(cb){ - const opts = getOpts(); - opts.json = {lines, version: 42, ranges: {}}; - return request.post(opts, cb); - }, - function(cb){ - const opts = getOpts(); - opts.json = true; - return request.get(opts, function(err, res, body){ - if (err != null) { - logger.err({err}, "docstore returned a error in health check get"); - return cb(err); - } else if ((res == null)) { - return cb("no response from docstore with get check"); - } else if ((res != null ? res.statusCode : undefined) !== 200) { - return cb(`status code not 200, its ${res.statusCode}`); - } else if (_.isEqual(body != null ? body.lines : undefined, lines) && ((body != null ? body._id : undefined) === doc_id.toString())) { - return cb(); - } else { - return cb(`health check lines not equal ${body.lines} != ${lines}`); - } - }); - }, - cb => db.docs.remove({_id: doc_id, project_id}, cb), - cb => db.docOps.remove({doc_id}, cb) - ]; - return async.series(jobs, callback); - } -}; +module.exports = { + check(callback) { + const doc_id = ObjectId() + const project_id = ObjectId(settings.docstore.healthCheck.project_id) + const url = `http://localhost:${port}/project/${project_id}/doc/${doc_id}` + const lines = [ + 'smoke test - delete me', + `${crypto.randomBytes(32).toString('hex')}` + ] + const getOpts = () => ({ + url, + timeout: 3000 + }) + logger.log({ lines, url, doc_id, project_id }, 'running health check') + const jobs = [ + function(cb) { + const opts = getOpts() + opts.json = { lines, version: 42, ranges: {} } + return request.post(opts, cb) + }, + function(cb) { + const opts = getOpts() + opts.json = true + return request.get(opts, function(err, res, body) { + if (err != null) { + logger.err({ err }, 'docstore returned a error in health check get') + return cb(err) + } else if (res == null) { + return cb('no response from docstore with get check') + } else if ((res != null ? res.statusCode : undefined) !== 200) { + return cb(`status code not 200, its ${res.statusCode}`) + } else if ( + _.isEqual(body != null ? body.lines : undefined, lines) && + (body != null ? body._id : undefined) === doc_id.toString() + ) { + return cb() + } else { + return cb(`health check lines not equal ${body.lines} != ${lines}`) + } + }) + }, + cb => db.docs.remove({ _id: doc_id, project_id }, cb), + cb => db.docOps.remove({ doc_id }, cb) + ] + return async.series(jobs, callback) + } +} diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 7f6eb9e728..7e17c15b65 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -12,220 +12,252 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let HttpController; -const DocManager = require("./DocManager"); -const logger = require("logger-sharelatex"); -const DocArchive = require("./DocArchiveManager"); -const HealthChecker = require("./HealthChecker"); -const Settings = require("settings-sharelatex"); +let HttpController +const DocManager = require('./DocManager') +const logger = require('logger-sharelatex') +const DocArchive = require('./DocArchiveManager') +const HealthChecker = require('./HealthChecker') +const Settings = require('settings-sharelatex') +module.exports = HttpController = { + getDoc(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + const { doc_id } = req.params + const include_deleted = + (req.query != null ? req.query.include_deleted : undefined) === 'true' + logger.log({ project_id, doc_id }, 'getting doc') + return DocManager.getFullDoc(project_id, doc_id, function(error, doc) { + if (error != null) { + return next(error) + } + logger.log({ doc_id, project_id }, 'got doc') + if (doc == null) { + return res.send(404) + } else if (doc.deleted && !include_deleted) { + return res.send(404) + } else { + return res.json(HttpController._buildDocView(doc)) + } + }) + }, -module.exports = (HttpController = { - getDoc(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - const { - doc_id - } = req.params; - const include_deleted = (req.query != null ? req.query.include_deleted : undefined) === "true"; - logger.log({project_id, doc_id}, "getting doc"); - return DocManager.getFullDoc(project_id, doc_id, function(error, doc) { - if (error != null) { return next(error); } - logger.log({doc_id, project_id}, "got doc"); - if ((doc == null)) { - return res.send(404); - } else if (doc.deleted && !include_deleted) { - return res.send(404); - } else { - return res.json(HttpController._buildDocView(doc)); - } - }); - }, + getRawDoc(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + const { doc_id } = req.params + logger.log({ project_id, doc_id }, 'getting raw doc') + return DocManager.getDocLines(project_id, doc_id, function(error, doc) { + if (error != null) { + return next(error) + } + if (doc == null) { + return res.send(404) + } else { + res.setHeader('content-type', 'text/plain') + return res.send(HttpController._buildRawDocView(doc)) + } + }) + }, - getRawDoc(req, res, next){ - if (next == null) { next = function(error){}; } - const { - project_id - } = req.params; - const { - doc_id - } = req.params; - logger.log({project_id, doc_id}, "getting raw doc"); - return DocManager.getDocLines(project_id, doc_id, function(error, doc) { - if (error != null) { return next(error); } - if ((doc == null)) { - return res.send(404); - } else { - res.setHeader('content-type', 'text/plain'); - return res.send(HttpController._buildRawDocView(doc)); - } - }); - }, + getAllDocs(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + logger.log({ project_id }, 'getting all docs') + return DocManager.getAllNonDeletedDocs( + project_id, + { lines: true, rev: true }, + function(error, docs) { + if (docs == null) { + docs = [] + } + if (error != null) { + return next(error) + } + return res.json(HttpController._buildDocsArrayView(project_id, docs)) + } + ) + }, - getAllDocs(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - logger.log({project_id}, "getting all docs"); - return DocManager.getAllNonDeletedDocs(project_id, {lines: true, rev: true}, function(error, docs) { - if (docs == null) { docs = []; } - if (error != null) { return next(error); } - return res.json(HttpController._buildDocsArrayView(project_id, docs)); - }); - }, - - getAllRanges(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - logger.log({project_id}, "getting all ranges"); - return DocManager.getAllNonDeletedDocs(project_id, {ranges: true}, function(error, docs) { - if (docs == null) { docs = []; } - if (error != null) { return next(error); } - return res.json(HttpController._buildDocsArrayView(project_id, docs)); - }); - }, + getAllRanges(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + logger.log({ project_id }, 'getting all ranges') + return DocManager.getAllNonDeletedDocs( + project_id, + { ranges: true }, + function(error, docs) { + if (docs == null) { + docs = [] + } + if (error != null) { + return next(error) + } + return res.json(HttpController._buildDocsArrayView(project_id, docs)) + } + ) + }, - updateDoc(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - const { - doc_id - } = req.params; - const lines = req.body != null ? req.body.lines : undefined; - const version = req.body != null ? req.body.version : undefined; - const ranges = req.body != null ? req.body.ranges : undefined; + updateDoc(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + const { doc_id } = req.params + const lines = req.body != null ? req.body.lines : undefined + const version = req.body != null ? req.body.version : undefined + const ranges = req.body != null ? req.body.ranges : undefined - if ((lines == null) || !(lines instanceof Array)) { - logger.error({project_id, doc_id}, "no doc lines provided"); - res.send(400); // Bad Request - return; - } - - if ((version == null) || (typeof version === !"number")) { - logger.error({project_id, doc_id}, "no doc version provided"); - res.send(400); // Bad Request - return; - } - - if ((ranges == null)) { - logger.error({project_id, doc_id}, "no doc ranges provided"); - res.send(400); // Bad Request - return; - } + if (lines == null || !(lines instanceof Array)) { + logger.error({ project_id, doc_id }, 'no doc lines provided') + res.send(400) // Bad Request + return + } - const bodyLength = lines.reduce( - (len, line) => line.length + len, - 0 - ); - if (bodyLength > Settings.max_doc_length) { - logger.error({project_id, doc_id, bodyLength}, "document body too large"); - res.status(413).send("document body too large"); - return; - } + if (version == null || typeof version === !'number') { + logger.error({ project_id, doc_id }, 'no doc version provided') + res.send(400) // Bad Request + return + } - logger.log({project_id, doc_id}, "got http request to update doc"); - return DocManager.updateDoc(project_id, doc_id, lines, version, ranges, function(error, modified, rev) { - if (error != null) { return next(error); } - return res.json({ - modified, - rev - }); - }); - }, + if (ranges == null) { + logger.error({ project_id, doc_id }, 'no doc ranges provided') + res.send(400) // Bad Request + return + } - deleteDoc(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - const { - doc_id - } = req.params; - logger.log({project_id, doc_id}, "deleting doc"); - return DocManager.deleteDoc(project_id, doc_id, function(error) { - if (error != null) { return next(error); } - return res.send(204); - }); - }, + const bodyLength = lines.reduce((len, line) => line.length + len, 0) + if (bodyLength > Settings.max_doc_length) { + logger.error( + { project_id, doc_id, bodyLength }, + 'document body too large' + ) + res.status(413).send('document body too large') + return + } - _buildDocView(doc) { - const doc_view = { _id: (doc._id != null ? doc._id.toString() : undefined) }; - for (const attribute of ["lines", "rev", "version", "ranges", "deleted"]) { - if (doc[attribute] != null) { - doc_view[attribute] = doc[attribute]; - } - } - return doc_view; - }, + logger.log({ project_id, doc_id }, 'got http request to update doc') + return DocManager.updateDoc( + project_id, + doc_id, + lines, + version, + ranges, + function(error, modified, rev) { + if (error != null) { + return next(error) + } + return res.json({ + modified, + rev + }) + } + ) + }, - _buildRawDocView(doc){ - return ((doc != null ? doc.lines : undefined) || []).join("\n"); - }, - - _buildDocsArrayView(project_id, docs) { - const docViews = []; - for (const doc of Array.from(docs)) { - if (doc != null) { // There can end up being null docs for some reason :( (probably a race condition) - docViews.push(HttpController._buildDocView(doc)); - } else { - logger.error({err: new Error("null doc"), project_id}, "encountered null doc"); - } - } - return docViews; - }, + deleteDoc(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + const { doc_id } = req.params + logger.log({ project_id, doc_id }, 'deleting doc') + return DocManager.deleteDoc(project_id, doc_id, function(error) { + if (error != null) { + return next(error) + } + return res.send(204) + }) + }, - archiveAllDocs(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - logger.log({project_id}, "archiving all docs"); - return DocArchive.archiveAllDocs(project_id, function(error) { - if (error != null) { return next(error); } - return res.send(204); - }); - }, + _buildDocView(doc) { + const doc_view = { _id: doc._id != null ? doc._id.toString() : undefined } + for (const attribute of ['lines', 'rev', 'version', 'ranges', 'deleted']) { + if (doc[attribute] != null) { + doc_view[attribute] = doc[attribute] + } + } + return doc_view + }, - unArchiveAllDocs(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - logger.log({project_id}, "unarchiving all docs"); - return DocArchive.unArchiveAllDocs(project_id, function(error) { - if (error != null) { return next(error); } - return res.send(200); - }); - }, + _buildRawDocView(doc) { + return ((doc != null ? doc.lines : undefined) || []).join('\n') + }, - destroyAllDocs(req, res, next) { - if (next == null) { next = function(error) {}; } - const { - project_id - } = req.params; - logger.log({project_id}, "destroying all docs"); - return DocArchive.destroyAllDocs(project_id, function(error) { - if (error != null) { return next(error); } - return res.send(204); - }); - }, + _buildDocsArrayView(project_id, docs) { + const docViews = [] + for (const doc of Array.from(docs)) { + if (doc != null) { + // There can end up being null docs for some reason :( (probably a race condition) + docViews.push(HttpController._buildDocView(doc)) + } else { + logger.error( + { err: new Error('null doc'), project_id }, + 'encountered null doc' + ) + } + } + return docViews + }, - healthCheck(req, res){ - return HealthChecker.check(function(err){ - if (err != null) { - logger.err({err}, "error performing health check"); - return res.send(500); - } else { - return res.send(200); - } - }); - } -}); + archiveAllDocs(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + logger.log({ project_id }, 'archiving all docs') + return DocArchive.archiveAllDocs(project_id, function(error) { + if (error != null) { + return next(error) + } + return res.send(204) + }) + }, + unArchiveAllDocs(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + logger.log({ project_id }, 'unarchiving all docs') + return DocArchive.unArchiveAllDocs(project_id, function(error) { + if (error != null) { + return next(error) + } + return res.send(200) + }) + }, + + destroyAllDocs(req, res, next) { + if (next == null) { + next = function(error) {} + } + const { project_id } = req.params + logger.log({ project_id }, 'destroying all docs') + return DocArchive.destroyAllDocs(project_id, function(error) { + if (error != null) { + return next(error) + } + return res.send(204) + }) + }, + + healthCheck(req, res) { + return HealthChecker.check(function(err) { + if (err != null) { + logger.err({ err }, 'error performing health check') + return res.send(500) + } else { + return res.send(200) + } + }) + } +} diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 27918267f9..413f60be82 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -10,122 +10,167 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let MongoManager; -const {db, ObjectId} = require("./mongojs"); -const logger = require('logger-sharelatex'); -const metrics = require('metrics-sharelatex'); +let MongoManager +const { db, ObjectId } = require('./mongojs') +const logger = require('logger-sharelatex') +const metrics = require('metrics-sharelatex') -module.exports = (MongoManager = { +module.exports = MongoManager = { + findDoc(project_id, doc_id, filter, callback) { + if (callback == null) { + callback = function(error, doc) {} + } + return db.docs.find( + { + _id: ObjectId(doc_id.toString()), + project_id: ObjectId(project_id.toString()) + }, + filter, + function(error, docs) { + if (docs == null) { + docs = [] + } + return callback(error, docs[0]) + } + ) + }, - findDoc(project_id, doc_id, filter, callback) { - if (callback == null) { callback = function(error, doc) {}; } - return db.docs.find({_id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString())}, filter, function(error, docs) { - if (docs == null) { docs = []; } - return callback(error, docs[0]); - }); - }, + getProjectsDocs(project_id, options, filter, callback) { + if (options == null) { + options = { include_deleted: true } + } + const query = { project_id: ObjectId(project_id.toString()) } + if (!options.include_deleted) { + query.deleted = { $ne: true } + } + return db.docs.find(query, filter, callback) + }, - getProjectsDocs(project_id, options, filter, callback){ - if (options == null) { options = {include_deleted: true}; } - const query = {project_id: ObjectId(project_id.toString())}; - if (!options.include_deleted) { - query.deleted = { $ne: true }; - } - return db.docs.find(query, filter, callback); - }, + getArchivedProjectDocs(project_id, callback) { + const query = { + project_id: ObjectId(project_id.toString()), + inS3: true + } + return db.docs.find(query, {}, callback) + }, - getArchivedProjectDocs(project_id, callback){ - const query = { - project_id: ObjectId(project_id.toString()), - inS3: true - }; - return db.docs.find(query, {}, callback); - }, + upsertIntoDocCollection(project_id, doc_id, updates, callback) { + const update = { + $set: updates, + $inc: { + rev: 1 + }, + $unset: { + inS3: true + } + } + update.$set.project_id = ObjectId(project_id) + return db.docs.update( + { _id: ObjectId(doc_id) }, + update, + { upsert: true }, + callback + ) + }, - upsertIntoDocCollection(project_id, doc_id, updates, callback){ - const update = { - $set: updates, - $inc: { - rev: 1 - }, - $unset: { - inS3: true - } - }; - update.$set.project_id = ObjectId(project_id); - return db.docs.update({_id: ObjectId(doc_id)}, update, {upsert: true}, callback); - }, + markDocAsDeleted(project_id, doc_id, callback) { + return db.docs.update( + { + _id: ObjectId(doc_id), + project_id: ObjectId(project_id) + }, + { + $set: { deleted: true } + }, + callback + ) + }, - markDocAsDeleted(project_id, doc_id, callback){ - return db.docs.update({ - _id: ObjectId(doc_id), - project_id: ObjectId(project_id) - }, { - $set: { deleted: true } - }, callback); - }, + markDocAsArchived(doc_id, rev, callback) { + const update = { + $set: {}, + $unset: {} + } + update.$set.inS3 = true + update.$unset.lines = true + update.$unset.ranges = true + const query = { + _id: doc_id, + rev + } + return db.docs.update(query, update, err => callback(err)) + }, - markDocAsArchived(doc_id, rev, callback){ - const update = { - $set: {}, - $unset: {} - }; - update.$set.inS3 = true; - update.$unset.lines = true; - update.$unset.ranges = true; - const query = { - _id: doc_id, - rev - }; - return db.docs.update(query, update, err => callback(err)); - }, - - getDocVersion(doc_id, callback) { - if (callback == null) { callback = function(error, version) {}; } - return db.docOps.find({ - doc_id: ObjectId(doc_id) - }, { - version: 1 - }, function(error, docs) { - if (error != null) { return callback(error); } - if ((docs.length < 1) || (docs[0].version == null)) { - return callback(null, 0); - } else { - return callback(null, docs[0].version); - } - }); - }, + getDocVersion(doc_id, callback) { + if (callback == null) { + callback = function(error, version) {} + } + return db.docOps.find( + { + doc_id: ObjectId(doc_id) + }, + { + version: 1 + }, + function(error, docs) { + if (error != null) { + return callback(error) + } + if (docs.length < 1 || docs[0].version == null) { + return callback(null, 0) + } else { + return callback(null, docs[0].version) + } + } + ) + }, - setDocVersion(doc_id, version, callback) { - if (callback == null) { callback = function(error) {}; } - return db.docOps.update({ - doc_id: ObjectId(doc_id) - }, { - $set: { version - } - }, { - upsert: true - }, callback); - }, + setDocVersion(doc_id, version, callback) { + if (callback == null) { + callback = function(error) {} + } + return db.docOps.update( + { + doc_id: ObjectId(doc_id) + }, + { + $set: { version } + }, + { + upsert: true + }, + callback + ) + }, - destroyDoc(doc_id, callback) { - return db.docs.remove({ - _id: ObjectId(doc_id) - }, function(err) { - if (err != null) { return callback(err); } - return db.docOps.remove({ - doc_id: ObjectId(doc_id) - }, callback); - }); - } -}); + destroyDoc(doc_id, callback) { + return db.docs.remove( + { + _id: ObjectId(doc_id) + }, + function(err) { + if (err != null) { + return callback(err) + } + return db.docOps.remove( + { + doc_id: ObjectId(doc_id) + }, + callback + ) + } + ) + } +} -[ - 'findDoc', - 'getProjectsDocs', - 'getArchivedProjectDocs', - 'upsertIntoDocCollection', - 'markDocAsArchived', - 'getDocVersion', - 'setDocVersion' -].map(method => metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger)); +;[ + 'findDoc', + 'getProjectsDocs', + 'getArchivedProjectDocs', + 'upsertIntoDocCollection', + 'markDocAsArchived', + 'getDocVersion', + 'setDocVersion' +].map(method => + metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger) +) diff --git a/services/docstore/app/js/RangeManager.js b/services/docstore/app/js/RangeManager.js index cee272a8e6..5a0061a9de 100644 --- a/services/docstore/app/js/RangeManager.js +++ b/services/docstore/app/js/RangeManager.js @@ -11,57 +11,59 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let RangeManager; -const _ = require("underscore"); -const {ObjectId} = require("./mongojs"); +let RangeManager +const _ = require('underscore') +const { ObjectId } = require('./mongojs') -module.exports = (RangeManager = { - shouldUpdateRanges(doc_ranges, incoming_ranges) { - if ((incoming_ranges == null)) { - throw new Error("expected incoming_ranges"); - } +module.exports = RangeManager = { + shouldUpdateRanges(doc_ranges, incoming_ranges) { + if (incoming_ranges == null) { + throw new Error('expected incoming_ranges') + } - // If the ranges are empty, we don't store them in the DB, so set - // doc_ranges to an empty object as default, since this is was the - // incoming_ranges will be for an empty range set. - if ((doc_ranges == null)) { - doc_ranges = {}; - } + // If the ranges are empty, we don't store them in the DB, so set + // doc_ranges to an empty object as default, since this is was the + // incoming_ranges will be for an empty range set. + if (doc_ranges == null) { + doc_ranges = {} + } - return !_.isEqual(doc_ranges, incoming_ranges); - }, - - jsonRangesToMongo(ranges) { - if ((ranges == null)) { return null; } - - const updateMetadata = function(metadata) { - if ((metadata != null ? metadata.ts : undefined) != null) { - metadata.ts = new Date(metadata.ts); - } - if ((metadata != null ? metadata.user_id : undefined) != null) { - return metadata.user_id = RangeManager._safeObjectId(metadata.user_id); - } - }; - - for (const change of Array.from(ranges.changes || [])) { - change.id = RangeManager._safeObjectId(change.id); - updateMetadata(change.metadata); - } - for (const comment of Array.from(ranges.comments || [])) { - comment.id = RangeManager._safeObjectId(comment.id); - if ((comment.op != null ? comment.op.t : undefined) != null) { - comment.op.t = RangeManager._safeObjectId(comment.op.t); - } - updateMetadata(comment.metadata); - } - return ranges; - }, - - _safeObjectId(data) { - try { - return ObjectId(data); - } catch (error) { - return data; - } - } -}); \ No newline at end of file + return !_.isEqual(doc_ranges, incoming_ranges) + }, + + jsonRangesToMongo(ranges) { + if (ranges == null) { + return null + } + + const updateMetadata = function(metadata) { + if ((metadata != null ? metadata.ts : undefined) != null) { + metadata.ts = new Date(metadata.ts) + } + if ((metadata != null ? metadata.user_id : undefined) != null) { + return (metadata.user_id = RangeManager._safeObjectId(metadata.user_id)) + } + } + + for (const change of Array.from(ranges.changes || [])) { + change.id = RangeManager._safeObjectId(change.id) + updateMetadata(change.metadata) + } + for (const comment of Array.from(ranges.comments || [])) { + comment.id = RangeManager._safeObjectId(comment.id) + if ((comment.op != null ? comment.op.t : undefined) != null) { + comment.op.t = RangeManager._safeObjectId(comment.op.t) + } + updateMetadata(comment.metadata) + } + return ranges + }, + + _safeObjectId(data) { + try { + return ObjectId(data) + } catch (error) { + return data + } + } +} diff --git a/services/docstore/app/js/mongojs.js b/services/docstore/app/js/mongojs.js index 8000129ae5..41f3bec470 100644 --- a/services/docstore/app/js/mongojs.js +++ b/services/docstore/app/js/mongojs.js @@ -1,10 +1,9 @@ // TODO: This file was created by bulk-decaffeinate. // Sanity-check the conversion and remove this comment. -const Settings = require("settings-sharelatex"); -const mongojs = require("mongojs"); -const db = mongojs(Settings.mongo.url, ["docs", "docOps"]); +const Settings = require('settings-sharelatex') +const mongojs = require('mongojs') +const db = mongojs(Settings.mongo.url, ['docs', 'docOps']) module.exports = { - db, - ObjectId: mongojs.ObjectId -}; - + db, + ObjectId: mongojs.ObjectId +} From 5098fa6d400a93bb7ddbf88dd2617285e81e33ec Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:02:47 +0000 Subject: [PATCH 218/349] decaffeinate: Rename DocArchiveManagerTests.coffee and 4 other files from .coffee to .js --- .../{DocArchiveManagerTests.coffee => DocArchiveManagerTests.js} | 0 .../unit/coffee/{DocManagerTests.coffee => DocManagerTests.js} | 0 .../coffee/{HttpControllerTests.coffee => HttpControllerTests.js} | 0 .../coffee/{MongoManagerTests.coffee => MongoManagerTests.js} | 0 .../coffee/{RangeManagerTests.coffee => RangeManagerTests.js} | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename services/docstore/test/unit/coffee/{DocArchiveManagerTests.coffee => DocArchiveManagerTests.js} (100%) rename services/docstore/test/unit/coffee/{DocManagerTests.coffee => DocManagerTests.js} (100%) rename services/docstore/test/unit/coffee/{HttpControllerTests.coffee => HttpControllerTests.js} (100%) rename services/docstore/test/unit/coffee/{MongoManagerTests.coffee => MongoManagerTests.js} (100%) rename services/docstore/test/unit/coffee/{RangeManagerTests.coffee => RangeManagerTests.js} (100%) diff --git a/services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee b/services/docstore/test/unit/coffee/DocArchiveManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/DocArchiveManagerTests.coffee rename to services/docstore/test/unit/coffee/DocArchiveManagerTests.js diff --git a/services/docstore/test/unit/coffee/DocManagerTests.coffee b/services/docstore/test/unit/coffee/DocManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/DocManagerTests.coffee rename to services/docstore/test/unit/coffee/DocManagerTests.js diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.coffee b/services/docstore/test/unit/coffee/HttpControllerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/HttpControllerTests.coffee rename to services/docstore/test/unit/coffee/HttpControllerTests.js diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.coffee b/services/docstore/test/unit/coffee/MongoManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/MongoManagerTests.coffee rename to services/docstore/test/unit/coffee/MongoManagerTests.js diff --git a/services/docstore/test/unit/coffee/RangeManagerTests.coffee b/services/docstore/test/unit/coffee/RangeManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/RangeManagerTests.coffee rename to services/docstore/test/unit/coffee/RangeManagerTests.js From 06bdba5c148d678391516aba8cd13824c340298d Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:02:48 +0000 Subject: [PATCH 219/349] decaffeinate: Convert DocArchiveManagerTests.coffee and 4 other files to JS --- .../unit/coffee/DocArchiveManagerTests.js | 628 ++++++++------ .../test/unit/coffee/DocManagerTests.js | 770 ++++++++++-------- .../test/unit/coffee/HttpControllerTests.js | 643 ++++++++------- .../test/unit/coffee/MongoManagerTests.js | 319 +++++--- .../test/unit/coffee/RangeManagerTests.js | 265 +++--- 5 files changed, 1512 insertions(+), 1113 deletions(-) diff --git a/services/docstore/test/unit/coffee/DocArchiveManagerTests.js b/services/docstore/test/unit/coffee/DocArchiveManagerTests.js index 70196a4b86..a6602405bd 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/coffee/DocArchiveManagerTests.js @@ -1,356 +1,444 @@ -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -should = chai.should() -expect = chai.expect -modulePath = "../../../app/js/DocArchiveManager.js" -SandboxedModule = require('sandboxed-module') -ObjectId = require("mongojs").ObjectId -Errors = require "../../../app/js/Errors" -crypto = require("crypto") +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const { + assert +} = require("chai"); +const sinon = require('sinon'); +const chai = require('chai'); +const should = chai.should(); +const { + expect +} = chai; +const modulePath = "../../../app/js/DocArchiveManager.js"; +const SandboxedModule = require('sandboxed-module'); +const { + ObjectId +} = require("mongojs"); +const Errors = require("../../../app/js/Errors"); +const crypto = require("crypto"); -describe "DocArchiveManager", -> +describe("DocArchiveManager", function() { - beforeEach -> + beforeEach(function() { - @settings = - docstore: - s3: - secret: "secret" - key: "this_key" + this.settings = { + docstore: { + s3: { + secret: "secret", + key: "this_key", bucket:"doc-archive-unit-test" + } + } + }; - @request = - put: {} - get: {} + this.request = { + put: {}, + get: {}, del: {} + }; - @archivedDocs = [{ - _id: ObjectId() - inS3:true + this.archivedDocs = [{ + _id: ObjectId(), + inS3:true, rev: 2 }, { - _id: ObjectId() - inS3:true + _id: ObjectId(), + inS3:true, rev: 4 }, { - _id: ObjectId() - inS3:true + _id: ObjectId(), + inS3:true, rev: 6 - }] + }]; - @mongoDocs = [{ - _id: ObjectId() - lines: ["one", "two", "three"] + this.mongoDocs = [{ + _id: ObjectId(), + lines: ["one", "two", "three"], rev: 2 }, { - _id: ObjectId() - lines: ["aaa", "bbb", "ccc"] + _id: ObjectId(), + lines: ["aaa", "bbb", "ccc"], rev: 4 }, { - _id: ObjectId() - inS3: true + _id: ObjectId(), + inS3: true, rev: 6 }, { - _id: ObjectId() - inS3: true + _id: ObjectId(), + inS3: true, rev: 6 }, { - _id: ObjectId() - lines: ["111", "222", "333"] + _id: ObjectId(), + lines: ["111", "222", "333"], rev: 6 - }] + }]; - @unarchivedDocs = [{ - _id: ObjectId() - lines: ["wombat", "potato", "banana"] + this.unarchivedDocs = [{ + _id: ObjectId(), + lines: ["wombat", "potato", "banana"], rev: 2 }, { - _id: ObjectId() - lines: ["llama", "turnip", "apple"] + _id: ObjectId(), + lines: ["llama", "turnip", "apple"], rev: 4 }, { - _id: ObjectId() - lines: ["elephant", "swede", "nectarine"] + _id: ObjectId(), + lines: ["elephant", "swede", "nectarine"], rev: 6 - }] + }]; - @mixedDocs = @archivedDocs.concat(@unarchivedDocs) + this.mixedDocs = this.archivedDocs.concat(this.unarchivedDocs); - @MongoManager = - markDocAsArchived: sinon.stub().callsArgWith(2, null) - upsertIntoDocCollection: sinon.stub().callsArgWith(3, null) - getProjectsDocs: sinon.stub().callsArgWith(3, null, @mongoDocs) - getArchivedProjectDocs: sinon.stub().callsArgWith(2, null, @mongoDocs) + this.MongoManager = { + markDocAsArchived: sinon.stub().callsArgWith(2, null), + upsertIntoDocCollection: sinon.stub().callsArgWith(3, null), + getProjectsDocs: sinon.stub().callsArgWith(3, null, this.mongoDocs), + getArchivedProjectDocs: sinon.stub().callsArgWith(2, null, this.mongoDocs) + }; - @requires = - "settings-sharelatex": @settings - "./MongoManager": @MongoManager - "request": @request - "./RangeManager": @RangeManager = {} - "logger-sharelatex": - log:-> - err:-> - @globals = - JSON: JSON + this.requires = { + "settings-sharelatex": this.settings, + "./MongoManager": this.MongoManager, + "request": this.request, + "./RangeManager": (this.RangeManager = {}), + "logger-sharelatex": { + log() {}, + err() {} + } + }; + this.globals = + {JSON}; - @error = "my errror" - @project_id = ObjectId().toString() - @stubbedError = new Errors.NotFoundError("Error in S3 request") - @DocArchiveManager = SandboxedModule.require modulePath, requires: @requires, globals: @globals + this.error = "my errror"; + this.project_id = ObjectId().toString(); + this.stubbedError = new Errors.NotFoundError("Error in S3 request"); + return this.DocArchiveManager = SandboxedModule.require(modulePath, {requires: this.requires, globals: this.globals}); + }); - describe "archiveDoc", -> + describe("archiveDoc", function() { - it "should use correct options", (done)-> - @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:""}}) - @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> - opts = @request.put.args[0][0] - assert.deepEqual(opts.aws, {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket}) - opts.body.should.equal JSON.stringify( - lines: @mongoDocs[0].lines - ranges: @mongoDocs[0].ranges + it("should use correct options", function(done){ + this.request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:""}}); + return this.DocArchiveManager.archiveDoc(this.project_id, this.mongoDocs[0], err=> { + const opts = this.request.put.args[0][0]; + assert.deepEqual(opts.aws, {key:this.settings.docstore.s3.key, secret:this.settings.docstore.s3.secret, bucket:this.settings.docstore.s3.bucket}); + opts.body.should.equal(JSON.stringify({ + lines: this.mongoDocs[0].lines, + ranges: this.mongoDocs[0].ranges, schema_v: 1 - ) - opts.timeout.should.equal (30*1000) - opts.uri.should.equal "https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{@mongoDocs[0]._id}" - done() + }) + ); + opts.timeout.should.equal((30*1000)); + opts.uri.should.equal(`https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}`); + return done(); + }); + }); - it "should return no md5 error", (done)-> - data = JSON.stringify( - lines: @mongoDocs[0].lines - ranges: @mongoDocs[0].ranges + it("should return no md5 error", function(done){ + const data = JSON.stringify({ + lines: this.mongoDocs[0].lines, + ranges: this.mongoDocs[0].ranges, schema_v: 1 - ) - @md5 = crypto.createHash("md5").update(data).digest("hex") - @request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:@md5}}) - @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> - should.not.exist err - done() + }); + this.md5 = crypto.createHash("md5").update(data).digest("hex"); + this.request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:this.md5}}); + return this.DocArchiveManager.archiveDoc(this.project_id, this.mongoDocs[0], err=> { + should.not.exist(err); + return done(); + }); + }); - it "should return the error", (done)-> - @request.put = sinon.stub().callsArgWith(1, @stubbedError, {statusCode:400,headers:{etag:""}}) - @DocArchiveManager.archiveDoc @project_id, @mongoDocs[0], (err)=> - should.exist err - done() + return it("should return the error", function(done){ + this.request.put = sinon.stub().callsArgWith(1, this.stubbedError, {statusCode:400,headers:{etag:""}}); + return this.DocArchiveManager.archiveDoc(this.project_id, this.mongoDocs[0], err=> { + should.exist(err); + return done(); + }); + }); + }); - describe "unarchiveDoc", -> + describe("unarchiveDoc", function() { - it "should use correct options", (done)-> - @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, @mongoDocs[0].lines) - @request.del = sinon.stub().callsArgWith(1, null, statusCode:204, {}) - @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0]._id, (err)=> - opts = @request.get.args[0][0] - assert.deepEqual(opts.aws, {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket}) - opts.json.should.equal true - opts.timeout.should.equal (30*1000) - opts.uri.should.equal "https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{@mongoDocs[0]._id}" - done() + it("should use correct options", function(done){ + this.request.get = sinon.stub().callsArgWith(1, null, {statusCode:200}, this.mongoDocs[0].lines); + this.request.del = sinon.stub().callsArgWith(1, null, {statusCode:204}, {}); + return this.DocArchiveManager.unarchiveDoc(this.project_id, this.mongoDocs[0]._id, err=> { + const opts = this.request.get.args[0][0]; + assert.deepEqual(opts.aws, {key:this.settings.docstore.s3.key, secret:this.settings.docstore.s3.secret, bucket:this.settings.docstore.s3.bucket}); + opts.json.should.equal(true); + opts.timeout.should.equal((30*1000)); + opts.uri.should.equal(`https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}`); + return done(); + }); + }); - it "should return the error", (done)-> - @request.get = sinon.stub().callsArgWith(1, @stubbedError, {}, {}) - @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0], (err)=> - should.exist err - done() + it("should return the error", function(done){ + this.request.get = sinon.stub().callsArgWith(1, this.stubbedError, {}, {}); + return this.DocArchiveManager.unarchiveDoc(this.project_id, this.mongoDocs[0], err=> { + should.exist(err); + return done(); + }); + }); - it "should error if the doc lines are a string not an array", (done)-> - @request.get = sinon.stub().callsArgWith(1, null, statusCode:200, "this is a string") - @request.del = sinon.stub() - @DocArchiveManager.unarchiveDoc @project_id, @mongoDocs[0], (err)=> - should.exist err - @request.del.called.should.equal false - done() + return it("should error if the doc lines are a string not an array", function(done){ + this.request.get = sinon.stub().callsArgWith(1, null, {statusCode:200}, "this is a string"); + this.request.del = sinon.stub(); + return this.DocArchiveManager.unarchiveDoc(this.project_id, this.mongoDocs[0], err=> { + should.exist(err); + this.request.del.called.should.equal(false); + return done(); + }); + }); + }); - describe "archiveAllDocs", -> + describe("archiveAllDocs", function() { - it "should archive all project docs which are not in s3", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @mongoDocs) - @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) + it("should archive all project docs which are not in s3", function(done){ + this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.mongoDocs); + this.DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null); - @DocArchiveManager.archiveAllDocs @project_id, (err)=> - @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[0]).should.equal true - @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[1]).should.equal true - @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[4]).should.equal true + return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { + this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[0]).should.equal(true); + this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[1]).should.equal(true); + this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[4]).should.equal(true); - @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[2]).should.equal false - @DocArchiveManager.archiveDoc.calledWith(@project_id, @mongoDocs[3]).should.equal false + this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[2]).should.equal(false); + this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[3]).should.equal(false); - should.not.exist err - done() + should.not.exist(err); + return done(); + }); + }); - it "should return error if have no docs", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null) + it("should return error if have no docs", function(done){ + this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null); - @DocArchiveManager.archiveAllDocs @project_id, (err)=> - should.exist err - done() + return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { + should.exist(err); + return done(); + }); + }); - it "should return the error", (done)-> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, @error, null) + it("should return the error", function(done){ + this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, this.error, null); - @DocArchiveManager.archiveAllDocs @project_id, (err)=> - err.should.equal @error - done() + return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { + err.should.equal(this.error); + return done(); + }); + }); - describe "when most have been already put in s3", -> + return describe("when most have been already put in s3", function() { - beforeEach -> - numberOfDocs = 10 * 1000 - @mongoDocs = [] - while --numberOfDocs != 0 - @mongoDocs.push({inS3:true, _id: ObjectId()}) + beforeEach(function() { + let numberOfDocs = 10 * 1000; + this.mongoDocs = []; + while (--numberOfDocs !== 0) { + this.mongoDocs.push({inS3:true, _id: ObjectId()}); + } - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @mongoDocs) - @DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) + this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.mongoDocs); + return this.DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null); + }); - it "should not throw and error", (done)-> - @DocArchiveManager.archiveAllDocs @project_id, (err)=> - should.not.exist err - done() + return it("should not throw and error", function(done){ + return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { + should.not.exist(err); + return done(); + }); + }); + }); + }); - describe "unArchiveAllDocs", -> + describe("unArchiveAllDocs", function() { - it "should unarchive all inS3 docs", (done)-> - @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, @archivedDocs) - @DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null) - @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> - for doc in @archivedDocs - @DocArchiveManager.unarchiveDoc.calledWith(@project_id, doc._id).should.equal true - should.not.exist err - done() + it("should unarchive all inS3 docs", function(done){ + this.MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, this.archivedDocs); + this.DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null); + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err=> { + for (let doc of Array.from(this.archivedDocs)) { + this.DocArchiveManager.unarchiveDoc.calledWith(this.project_id, doc._id).should.equal(true); + } + should.not.exist(err); + return done(); + }); + }); - it "should return error if have no docs", (done)-> - @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, null) - @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> - should.exist err - done() + it("should return error if have no docs", function(done){ + this.MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, null); + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err=> { + should.exist(err); + return done(); + }); + }); - it "should return the error", (done)-> - @MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, @error, null) - @DocArchiveManager.unArchiveAllDocs @project_id, (err)=> - err.should.equal @error - done() + return it("should return the error", function(done){ + this.MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, this.error, null); + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err=> { + err.should.equal(this.error); + return done(); + }); + }); + }); - describe "destroyAllDocs", -> - beforeEach -> - @request.del = sinon.stub().callsArgWith(1, null, statusCode:204, {}) - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @mixedDocs) - @MongoManager.findDoc = sinon.stub().callsArgWith(3, null, null) - @MongoManager.destroyDoc = sinon.stub().yields() - for doc in @mixedDocs - @MongoManager.findDoc.withArgs(@project_id, doc._id).callsArgWith(3, null, doc) + describe("destroyAllDocs", function() { + beforeEach(function() { + this.request.del = sinon.stub().callsArgWith(1, null, {statusCode:204}, {}); + this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.mixedDocs); + this.MongoManager.findDoc = sinon.stub().callsArgWith(3, null, null); + this.MongoManager.destroyDoc = sinon.stub().yields(); + return Array.from(this.mixedDocs).map((doc) => + this.MongoManager.findDoc.withArgs(this.project_id, doc._id).callsArgWith(3, null, doc)); + }); - it "should destroy all the docs", (done)-> - @DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null) - @DocArchiveManager.destroyAllDocs @project_id, (err)=> - for doc in @mixedDocs - @DocArchiveManager.destroyDoc.calledWith(@project_id, doc._id).should.equal true - should.not.exist err - done() + it("should destroy all the docs", function(done){ + this.DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null); + return this.DocArchiveManager.destroyAllDocs(this.project_id, err=> { + for (let doc of Array.from(this.mixedDocs)) { + this.DocArchiveManager.destroyDoc.calledWith(this.project_id, doc._id).should.equal(true); + } + should.not.exist(err); + return done(); + }); + }); - it "should only the s3 docs from s3", (done)-> - docOpts = (doc) => - JSON.parse(JSON.stringify({ - aws: {key:@settings.docstore.s3.key, secret:@settings.docstore.s3.secret, bucket:@settings.docstore.s3.bucket}, + it("should only the s3 docs from s3", function(done){ + const docOpts = doc => { + return JSON.parse(JSON.stringify({ + aws: {key:this.settings.docstore.s3.key, secret:this.settings.docstore.s3.secret, bucket:this.settings.docstore.s3.bucket}, json: true, - timeout: 30 * 1000 - uri:"https://#{@settings.docstore.s3.bucket}.s3.amazonaws.com/#{@project_id}/#{doc._id}" - })) + timeout: 30 * 1000, + uri:`https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${doc._id}` + })); + }; - @DocArchiveManager.destroyAllDocs @project_id, (err)=> - expect(err).not.to.exist + return this.DocArchiveManager.destroyAllDocs(this.project_id, err=> { + let doc; + expect(err).not.to.exist; - for doc in @archivedDocs - sinon.assert.calledWith(@request.del, docOpts(doc)) - for doc in @unarchivedDocs - expect(@request.del.calledWith(docOpts(doc))).to.equal false # no notCalledWith + for (doc of Array.from(this.archivedDocs)) { + sinon.assert.calledWith(this.request.del, docOpts(doc)); + } + for (doc of Array.from(this.unarchivedDocs)) { + expect(this.request.del.calledWith(docOpts(doc))).to.equal(false); + } // no notCalledWith - done() + return done(); + }); + }); - it "should remove the docs from mongo", (done)-> - @DocArchiveManager.destroyAllDocs @project_id, (err)=> - expect(err).not.to.exist + return it("should remove the docs from mongo", function(done){ + this.DocArchiveManager.destroyAllDocs(this.project_id, err=> { + return expect(err).not.to.exist; + }); - for doc in @mixedDocs - sinon.assert.calledWith(@MongoManager.destroyDoc, doc._id) + for (let doc of Array.from(this.mixedDocs)) { + sinon.assert.calledWith(this.MongoManager.destroyDoc, doc._id); + } - done() + return done(); + }); + }); - describe "_s3DocToMongoDoc", -> - describe "with the old schema", -> - it "should return the docs lines", (done) -> - @DocArchiveManager._s3DocToMongoDoc ["doc", "lines"], (error, doc) -> - expect(doc).to.deep.equal { - lines: ["doc", "lines"] - } - done() + describe("_s3DocToMongoDoc", function() { + describe("with the old schema", () => it("should return the docs lines", function(done) { + return this.DocArchiveManager._s3DocToMongoDoc(["doc", "lines"], function(error, doc) { + expect(doc).to.deep.equal({ + lines: ["doc", "lines"] + }); + return done(); + }); + })); - describe "with the new schema", -> - it "should return the doc lines and ranges", (done) -> - @RangeManager.jsonRangesToMongo = sinon.stub().returns {"mongo": "ranges"} - @DocArchiveManager._s3DocToMongoDoc { - lines: ["doc", "lines"] - ranges: {"json": "ranges"} + describe("with the new schema", function() { + it("should return the doc lines and ranges", function(done) { + this.RangeManager.jsonRangesToMongo = sinon.stub().returns({"mongo": "ranges"}); + return this.DocArchiveManager._s3DocToMongoDoc({ + lines: ["doc", "lines"], + ranges: {"json": "ranges"}, schema_v: 1 - }, (error, doc) -> - expect(doc).to.deep.equal { - lines: ["doc", "lines"] + }, function(error, doc) { + expect(doc).to.deep.equal({ + lines: ["doc", "lines"], ranges: {"mongo": "ranges"} - } - done() + }); + return done(); + }); + }); - it "should return just the doc lines when there are no ranges", (done) -> - @DocArchiveManager._s3DocToMongoDoc { - lines: ["doc", "lines"] + return it("should return just the doc lines when there are no ranges", function(done) { + return this.DocArchiveManager._s3DocToMongoDoc({ + lines: ["doc", "lines"], schema_v: 1 - }, (error, doc) -> - expect(doc).to.deep.equal { + }, function(error, doc) { + expect(doc).to.deep.equal({ lines: ["doc", "lines"] - } - done() + }); + return done(); + }); + }); + }); - describe "with an unrecognised schema", -> - it "should return an error", (done) -> - @DocArchiveManager._s3DocToMongoDoc { - schema_v: 2 - }, (error, doc) -> - expect(error).to.exist - done() + return describe("with an unrecognised schema", () => it("should return an error", function(done) { + return this.DocArchiveManager._s3DocToMongoDoc({ + schema_v: 2 + }, function(error, doc) { + expect(error).to.exist; + return done(); + }); + })); + }); - describe "_mongoDocToS3Doc", -> - describe "with a valid doc", -> - it "should return the json version", (done) -> - @DocArchiveManager._mongoDocToS3Doc doc = { - lines: ["doc", "lines"] - ranges: { "mock": "ranges" } - }, (err, s3_doc) -> - expect(s3_doc).to.equal JSON.stringify({ - lines: ["doc", "lines"] - ranges: { "mock": "ranges" } - schema_v: 1 - }) - done() + return describe("_mongoDocToS3Doc", function() { + describe("with a valid doc", () => it("should return the json version", function(done) { + let doc; + return this.DocArchiveManager._mongoDocToS3Doc((doc = { + lines: ["doc", "lines"], + ranges: { "mock": "ranges" } + }), function(err, s3_doc) { + expect(s3_doc).to.equal(JSON.stringify({ + lines: ["doc", "lines"], + ranges: { "mock": "ranges" }, + schema_v: 1 + }) + ); + return done(); + }); + })); - describe "with null bytes in the result", -> - beforeEach -> - @_stringify = JSON.stringify - JSON.stringify = sinon.stub().returns '{"bad": "\u0000"}' + describe("with null bytes in the result", function() { + beforeEach(function() { + this._stringify = JSON.stringify; + return JSON.stringify = sinon.stub().returns('{"bad": "\u0000"}'); + }); - afterEach -> - JSON.stringify = @_stringify + afterEach(function() { + return JSON.stringify = this._stringify; + }); - it "should return an error", (done) -> - @DocArchiveManager._mongoDocToS3Doc { - lines: ["doc", "lines"] + return it("should return an error", function(done) { + return this.DocArchiveManager._mongoDocToS3Doc({ + lines: ["doc", "lines"], ranges: { "mock": "ranges" } - }, (err, s3_doc) -> - expect(err).to.exist - done() + }, function(err, s3_doc) { + expect(err).to.exist; + return done(); + }); + }); + }); - describe "without doc lines", -> - it "should return an error", (done) -> - @DocArchiveManager._mongoDocToS3Doc {}, (err, s3_doc) -> - expect(err).to.exist - done() + return describe("without doc lines", () => it("should return an error", function(done) { + return this.DocArchiveManager._mongoDocToS3Doc({}, function(err, s3_doc) { + expect(err).to.exist; + return done(); + }); + })); + }); +}); diff --git a/services/docstore/test/unit/coffee/DocManagerTests.js b/services/docstore/test/unit/coffee/DocManagerTests.js index 70cea2e2c8..bdeb97c98d 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.js +++ b/services/docstore/test/unit/coffee/DocManagerTests.js @@ -1,407 +1,537 @@ -SandboxedModule = require('sandboxed-module') -sinon = require('sinon') -chai = require('chai') -assert = require("chai").assert -chai.should() -expect = chai.expect -modulePath = require('path').join __dirname, '../../../app/js/DocManager' -ObjectId = require("mongojs").ObjectId -Errors = require "../../../app/js/Errors" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const SandboxedModule = require('sandboxed-module'); +const sinon = require('sinon'); +const chai = require('chai'); +const { + assert +} = require("chai"); +chai.should(); +const { + expect +} = chai; +const modulePath = require('path').join(__dirname, '../../../app/js/DocManager'); +const { + ObjectId +} = require("mongojs"); +const Errors = require("../../../app/js/Errors"); -describe "DocManager", -> - beforeEach -> - @DocManager = SandboxedModule.require modulePath, requires: - "./MongoManager": @MongoManager = {} - "./DocArchiveManager": @DocArchiveManager = {} - "./RangeManager": @RangeManager = { - jsonRangesToMongo: (r) -> r - shouldUpdateRanges: sinon.stub().returns false - } - "logger-sharelatex": @logger = - log: sinon.stub() - warn:-> - err:-> - @doc_id = ObjectId().toString() - @project_id = ObjectId().toString() - @another_project_id = ObjectId().toString() - @callback = sinon.stub() - @stubbedError = new Error("blew up") +describe("DocManager", function() { + beforeEach(function() { + this.DocManager = SandboxedModule.require(modulePath, { requires: { + "./MongoManager": (this.MongoManager = {}), + "./DocArchiveManager": (this.DocArchiveManager = {}), + "./RangeManager": (this.RangeManager = { + jsonRangesToMongo(r) { return r; }, + shouldUpdateRanges: sinon.stub().returns(false) + }), + "logger-sharelatex": (this.logger = { + log: sinon.stub(), + warn() {}, + err() {} + }) + } + } + ); + this.doc_id = ObjectId().toString(); + this.project_id = ObjectId().toString(); + this.another_project_id = ObjectId().toString(); + this.callback = sinon.stub(); + return this.stubbedError = new Error("blew up"); + }); - describe "checkDocExists", -> - beforeEach -> - @DocManager._getDoc = sinon.stub() + describe("checkDocExists", function() { + beforeEach(function() { + return this.DocManager._getDoc = sinon.stub(); + }); - it "should call get doc with a quick filter", (done)-> - @DocManager._getDoc.callsArgWith(3, null, {_id:@doc_id}) - @DocManager.checkDocExists @project_id, @doc_id, (err, exist)=> - exist.should.equal true - @DocManager._getDoc.calledWith(@project_id, @doc_id, {_id:1, inS3:true}).should.equal true - done() + it("should call get doc with a quick filter", function(done){ + this.DocManager._getDoc.callsArgWith(3, null, {_id:this.doc_id}); + return this.DocManager.checkDocExists(this.project_id, this.doc_id, (err, exist)=> { + exist.should.equal(true); + this.DocManager._getDoc.calledWith(this.project_id, this.doc_id, {_id:1, inS3:true}).should.equal(true); + return done(); + }); + }); - it "should return false when doc is not there", (done)-> - @DocManager._getDoc.callsArgWith(3, null) - @DocManager.checkDocExists @project_id, @doc_id, (err, exist)=> - exist.should.equal false - done() + it("should return false when doc is not there", function(done){ + this.DocManager._getDoc.callsArgWith(3, null); + return this.DocManager.checkDocExists(this.project_id, this.doc_id, (err, exist)=> { + exist.should.equal(false); + return done(); + }); + }); - it "should return error when get doc errors", (done)-> - @DocManager._getDoc.callsArgWith(3, "error") - @DocManager.checkDocExists @project_id, @doc_id, (err, exist)=> - err.should.equal "error" - done() + return it("should return error when get doc errors", function(done){ + this.DocManager._getDoc.callsArgWith(3, "error"); + return this.DocManager.checkDocExists(this.project_id, this.doc_id, (err, exist)=> { + err.should.equal("error"); + return done(); + }); + }); + }); - describe "getFullDoc", -> - beforeEach -> - @DocManager._getDoc = sinon.stub() - @doc = - _id: @doc_id + describe("getFullDoc", function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub(); + return this.doc = { + _id: this.doc_id, lines:["2134"] + };}); - it "should call get doc with a quick filter", (done)-> - @DocManager._getDoc.callsArgWith(3, null, @doc) - @DocManager.getFullDoc @project_id, @doc_id, (err, doc)=> - doc.should.equal @doc - @DocManager._getDoc.calledWith(@project_id, @doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}).should.equal true - done() + it("should call get doc with a quick filter", function(done){ + this.DocManager._getDoc.callsArgWith(3, null, this.doc); + return this.DocManager.getFullDoc(this.project_id, this.doc_id, (err, doc)=> { + doc.should.equal(this.doc); + this.DocManager._getDoc.calledWith(this.project_id, this.doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}).should.equal(true); + return done(); + }); + }); - it "should return error when get doc errors", (done)-> - @DocManager._getDoc.callsArgWith(3, "error") - @DocManager.getFullDoc @project_id, @doc_id, (err, exist)=> - err.should.equal "error" - done() + return it("should return error when get doc errors", function(done){ + this.DocManager._getDoc.callsArgWith(3, "error"); + return this.DocManager.getFullDoc(this.project_id, this.doc_id, (err, exist)=> { + err.should.equal("error"); + return done(); + }); + }); + }); - describe "getRawDoc", -> + describe("getRawDoc", function() { - beforeEach -> - @DocManager._getDoc = sinon.stub() - @doc = - lines:["2134"] + beforeEach(function() { + this.DocManager._getDoc = sinon.stub(); + return this.doc = + {lines:["2134"]};}); - it "should call get doc with a quick filter", (done)-> - @DocManager._getDoc.callsArgWith(3, null, @doc) - @DocManager.getDocLines @project_id, @doc_id, (err, doc)=> - doc.should.equal @doc - @DocManager._getDoc.calledWith(@project_id, @doc_id, {lines: true, inS3:true}).should.equal true - done() + it("should call get doc with a quick filter", function(done){ + this.DocManager._getDoc.callsArgWith(3, null, this.doc); + return this.DocManager.getDocLines(this.project_id, this.doc_id, (err, doc)=> { + doc.should.equal(this.doc); + this.DocManager._getDoc.calledWith(this.project_id, this.doc_id, {lines: true, inS3:true}).should.equal(true); + return done(); + }); + }); - it "should return error when get doc errors", (done)-> - @DocManager._getDoc.callsArgWith(3, "error") - @DocManager.getDocLines @project_id, @doc_id, (err, exist)=> - err.should.equal "error" - done() + return it("should return error when get doc errors", function(done){ + this.DocManager._getDoc.callsArgWith(3, "error"); + return this.DocManager.getDocLines(this.project_id, this.doc_id, (err, exist)=> { + err.should.equal("error"); + return done(); + }); + }); + }); - describe "getDoc", -> - beforeEach -> - @project = { name: "mock-project" } - @doc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] } - @version = 42 - @MongoManager.findDoc = sinon.stub() - @MongoManager.getDocVersion = sinon.stub().yields(null, @version) + describe("getDoc", function() { + beforeEach(function() { + this.project = { name: "mock-project" }; + this.doc = { _id: this.doc_id, project_id: this.project_id, lines: ["mock-lines"] }; + this.version = 42; + this.MongoManager.findDoc = sinon.stub(); + return this.MongoManager.getDocVersion = sinon.stub().yields(null, this.version); + }); - describe "when using a filter", -> - beforeEach -> - @MongoManager.findDoc.yields(null, @doc) + describe("when using a filter", function() { + beforeEach(function() { + return this.MongoManager.findDoc.yields(null, this.doc); + }); - it "should error if inS3 is not set to true", (done)-> - @DocManager._getDoc @project_id, @doc_id, {inS3: false}, (err)-> - expect(err).to.exist - done() + it("should error if inS3 is not set to true", function(done){ + return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: false}, function(err){ + expect(err).to.exist; + return done(); + }); + }); - it "should always get inS3 even when no filter is passed", (done)-> - @DocManager._getDoc @project_id, @doc_id, undefined, (err)=> - @MongoManager.findDoc.called.should.equal false - expect(err).to.exist - done() + it("should always get inS3 even when no filter is passed", function(done){ + return this.DocManager._getDoc(this.project_id, this.doc_id, undefined, err=> { + this.MongoManager.findDoc.called.should.equal(false); + expect(err).to.exist; + return done(); + }); + }); - it "should not error if inS3 is set to true", (done)-> - @DocManager._getDoc @project_id, @doc_id, {inS3: true}, (err)-> - expect(err).to.not.exist - done() + return it("should not error if inS3 is set to true", function(done){ + return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: true}, function(err){ + expect(err).to.not.exist; + return done(); + }); + }); + }); - describe "when the doc is in the doc collection", -> - beforeEach -> - @MongoManager.findDoc.yields(null, @doc) - @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback + describe("when the doc is in the doc collection", function() { + beforeEach(function() { + this.MongoManager.findDoc.yields(null, this.doc); + return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); + }); - it "should get the doc from the doc collection", -> - @MongoManager.findDoc - .calledWith(@project_id, @doc_id) - .should.equal true + it("should get the doc from the doc collection", function() { + return this.MongoManager.findDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true); + }); - it "should get the doc version from the docOps collection", -> - @MongoManager.getDocVersion - .calledWith(@doc_id) - .should.equal true + it("should get the doc version from the docOps collection", function() { + return this.MongoManager.getDocVersion + .calledWith(this.doc_id) + .should.equal(true); + }); - it "should return the callback with the doc with the version", -> - @callback.called.should.equal true - doc = @callback.args[0][1] - doc.lines.should.equal @doc.lines - doc.version.should.equal @version + return it("should return the callback with the doc with the version", function() { + this.callback.called.should.equal(true); + const doc = this.callback.args[0][1]; + doc.lines.should.equal(this.doc.lines); + return doc.version.should.equal(this.version); + }); + }); - describe "without the version filter", -> - beforeEach -> - @MongoManager.findDoc.yields(null, @doc) - @DocManager._getDoc @project_id, @doc_id, {version: false, inS3:true}, @callback + describe("without the version filter", function() { + beforeEach(function() { + this.MongoManager.findDoc.yields(null, this.doc); + return this.DocManager._getDoc(this.project_id, this.doc_id, {version: false, inS3:true}, this.callback); + }); - it "should not get the doc version from the docOps collection", -> - @MongoManager.getDocVersion.called.should.equal false + return it("should not get the doc version from the docOps collection", function() { + return this.MongoManager.getDocVersion.called.should.equal(false); + }); + }); - describe "when MongoManager.findDoc errors", -> - beforeEach -> - @MongoManager.findDoc.yields(@stubbedError) - @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback + describe("when MongoManager.findDoc errors", function() { + beforeEach(function() { + this.MongoManager.findDoc.yields(this.stubbedError); + return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); + }); - it "should return the error", -> - @callback.calledWith(@stubbedError).should.equal true + return it("should return the error", function() { + return this.callback.calledWith(this.stubbedError).should.equal(true); + }); + }); - describe "when the doc is archived", -> - beforeEach -> - @doc = { _id: @doc_id, project_id: @project_id, lines: ["mock-lines"], inS3: true } - @MongoManager.findDoc.yields(null, @doc) - @DocArchiveManager.unarchiveDoc = (project_id, doc_id, callback) => - @doc.inS3 = false - callback() - sinon.spy @DocArchiveManager, "unarchiveDoc" - @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback + describe("when the doc is archived", function() { + beforeEach(function() { + this.doc = { _id: this.doc_id, project_id: this.project_id, lines: ["mock-lines"], inS3: true }; + this.MongoManager.findDoc.yields(null, this.doc); + this.DocArchiveManager.unarchiveDoc = (project_id, doc_id, callback) => { + this.doc.inS3 = false; + return callback(); + }; + sinon.spy(this.DocArchiveManager, "unarchiveDoc"); + return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); + }); - it "should call the DocArchive to unarchive the doc", -> - @DocArchiveManager.unarchiveDoc.calledWith(@project_id, @doc_id).should.equal true + it("should call the DocArchive to unarchive the doc", function() { + return this.DocArchiveManager.unarchiveDoc.calledWith(this.project_id, this.doc_id).should.equal(true); + }); - it "should look up the doc twice", -> - @MongoManager.findDoc.calledTwice.should.equal true + it("should look up the doc twice", function() { + return this.MongoManager.findDoc.calledTwice.should.equal(true); + }); - it "should return the doc", -> - @callback.calledWith(null, @doc).should.equal true + return it("should return the doc", function() { + return this.callback.calledWith(null, this.doc).should.equal(true); + }); + }); - describe "when the doc does not exist in the docs collection", -> - beforeEach -> - @MongoManager.findDoc = sinon.stub().yields(null, null) - @DocManager._getDoc @project_id, @doc_id, {version: true, inS3:true}, @callback + return describe("when the doc does not exist in the docs collection", function() { + beforeEach(function() { + this.MongoManager.findDoc = sinon.stub().yields(null, null); + return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); + }); - it "should return a NotFoundError", -> - @callback - .calledWith(sinon.match.has('message', "No such doc: #{@doc_id} in project #{@project_id}")) - .should.equal true + return it("should return a NotFoundError", function() { + return this.callback + .calledWith(sinon.match.has('message', `No such doc: ${this.doc_id} in project ${this.project_id}`)) + .should.equal(true); + }); + }); + }); - describe "getAllNonDeletedDocs", -> - describe "when the project exists", -> - beforeEach -> - @docs = [{ _id: @doc_id, project_id: @project_id, lines: ["mock-lines"] }] - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, @docs) - @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, @docs) - @filter = { lines: true } - @DocManager.getAllNonDeletedDocs @project_id, @filter, @callback + describe("getAllNonDeletedDocs", function() { + describe("when the project exists", function() { + beforeEach(function() { + this.docs = [{ _id: this.doc_id, project_id: this.project_id, lines: ["mock-lines"] }]; + this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.docs); + this.DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, this.docs); + this.filter = { lines: true }; + return this.DocManager.getAllNonDeletedDocs(this.project_id, this.filter, this.callback); + }); - it "should get the project from the database", -> - @MongoManager.getProjectsDocs - .calledWith(@project_id, {include_deleted: false}, @filter) - .should.equal true + it("should get the project from the database", function() { + return this.MongoManager.getProjectsDocs + .calledWith(this.project_id, {include_deleted: false}, this.filter) + .should.equal(true); + }); - it "should return the docs", -> - @callback.calledWith(null, @docs).should.equal true + return it("should return the docs", function() { + return this.callback.calledWith(null, this.docs).should.equal(true); + }); + }); - describe "when there are no docs for the project", -> - beforeEach -> - @MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null) - @DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null) - @DocManager.getAllNonDeletedDocs @project_id, @filter, @callback + return describe("when there are no docs for the project", function() { + beforeEach(function() { + this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null); + this.DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null); + return this.DocManager.getAllNonDeletedDocs(this.project_id, this.filter, this.callback); + }); - it "should return a NotFoundError", -> - @callback - .calledWith(sinon.match.has('message', "No docs for project #{@project_id}")) - .should.equal true + return it("should return a NotFoundError", function() { + return this.callback + .calledWith(sinon.match.has('message', `No docs for project ${this.project_id}`)) + .should.equal(true); + }); + }); + }); - describe "deleteDoc", -> - describe "when the doc exists", -> - beforeEach -> - @lines = ["mock", "doc", "lines"] - @rev = 77 - @DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, true) - @MongoManager.markDocAsDeleted = sinon.stub().callsArg(2) - @DocManager.deleteDoc @project_id, @doc_id, @callback + describe("deleteDoc", function() { + describe("when the doc exists", function() { + beforeEach(function() { + this.lines = ["mock", "doc", "lines"]; + this.rev = 77; + this.DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, true); + this.MongoManager.markDocAsDeleted = sinon.stub().callsArg(2); + return this.DocManager.deleteDoc(this.project_id, this.doc_id, this.callback); + }); - it "should get the doc", -> - @DocManager.checkDocExists - .calledWith(@project_id, @doc_id) - .should.equal true + it("should get the doc", function() { + return this.DocManager.checkDocExists + .calledWith(this.project_id, this.doc_id) + .should.equal(true); + }); - it "should mark doc as deleted", -> - @MongoManager.markDocAsDeleted - .calledWith(@project_id, @doc_id) - .should.equal true + it("should mark doc as deleted", function() { + return this.MongoManager.markDocAsDeleted + .calledWith(this.project_id, this.doc_id) + .should.equal(true); + }); - it "should return the callback", -> - @callback.called.should.equal true + return it("should return the callback", function() { + return this.callback.called.should.equal(true); + }); + }); - describe "when the doc does not exist", -> - beforeEach -> - @DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, false) - @DocManager.deleteDoc @project_id, @doc_id, @callback + return describe("when the doc does not exist", function() { + beforeEach(function() { + this.DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, false); + return this.DocManager.deleteDoc(this.project_id, this.doc_id, this.callback); + }); - it "should return a NotFoundError", -> - @callback - .calledWith(sinon.match.has('message', "No such project/doc to delete: #{@project_id}/#{@doc_id}")) - .should.equal true + return it("should return a NotFoundError", function() { + return this.callback + .calledWith(sinon.match.has('message', `No such project/doc to delete: ${this.project_id}/${this.doc_id}`)) + .should.equal(true); + }); + }); + }); - describe "updateDoc", -> - beforeEach -> - @oldDocLines = ["old", "doc", "lines"] - @newDocLines = ["new", "doc", "lines"] - @originalRanges = { + return describe("updateDoc", function() { + beforeEach(function() { + this.oldDocLines = ["old", "doc", "lines"]; + this.newDocLines = ["new", "doc", "lines"]; + this.originalRanges = { changes: [{ - id: ObjectId().toString() - op: { i: "foo", p: 3 } - meta: - user_id: ObjectId().toString() + id: ObjectId().toString(), + op: { i: "foo", p: 3 }, + meta: { + user_id: ObjectId().toString(), ts: new Date().toString() + } }] - } - @newRanges = { + }; + this.newRanges = { changes: [{ - id: ObjectId().toString() - op: { i: "bar", p: 6 } - meta: - user_id: ObjectId().toString() + id: ObjectId().toString(), + op: { i: "bar", p: 6 }, + meta: { + user_id: ObjectId().toString(), ts: new Date().toString() + } }] - } - @version = 42 - @doc = { _id: @doc_id, project_id: @project_id, lines: @oldDocLines, rev: @rev = 5, version: @version, ranges: @originalRanges } + }; + this.version = 42; + this.doc = { _id: this.doc_id, project_id: this.project_id, lines: this.oldDocLines, rev: (this.rev = 5), version: this.version, ranges: this.originalRanges }; - @MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) - @MongoManager.setDocVersion = sinon.stub().yields() - @DocManager._getDoc = sinon.stub() + this.MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3); + this.MongoManager.setDocVersion = sinon.stub().yields(); + return this.DocManager._getDoc = sinon.stub(); + }); - describe "when only the doc lines have changed", -> - beforeEach -> - @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback + describe("when only the doc lines have changed", function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, this.originalRanges, this.callback); + }); - it "should get the existing doc", -> - @DocManager._getDoc - .calledWith(@project_id, @doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}) - .should.equal true + it("should get the existing doc", function() { + return this.DocManager._getDoc + .calledWith(this.project_id, this.doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}) + .should.equal(true); + }); - it "should upsert the document to the doc collection", -> - @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, {lines: @newDocLines}) - .should.equal true + it("should upsert the document to the doc collection", function() { + return this.MongoManager.upsertIntoDocCollection + .calledWith(this.project_id, this.doc_id, {lines: this.newDocLines}) + .should.equal(true); + }); - it "should not update the version", -> - @MongoManager.setDocVersion.called.should.equal false + it("should not update the version", function() { + return this.MongoManager.setDocVersion.called.should.equal(false); + }); - it "should return the callback with the new rev", -> - @callback.calledWith(null, true, @rev + 1).should.equal true + return it("should return the callback with the new rev", function() { + return this.callback.calledWith(null, true, this.rev + 1).should.equal(true); + }); + }); - describe "when the doc ranges have changed", -> - beforeEach -> - @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) - @RangeManager.shouldUpdateRanges.returns true - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @newRanges, @callback + describe("when the doc ranges have changed", function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); + this.RangeManager.shouldUpdateRanges.returns(true); + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines, this.version, this.newRanges, this.callback); + }); - it "should upsert the ranges", -> - @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, {ranges: @newRanges}) - .should.equal true + it("should upsert the ranges", function() { + return this.MongoManager.upsertIntoDocCollection + .calledWith(this.project_id, this.doc_id, {ranges: this.newRanges}) + .should.equal(true); + }); - it "should not update the version", -> - @MongoManager.setDocVersion.called.should.equal false + it("should not update the version", function() { + return this.MongoManager.setDocVersion.called.should.equal(false); + }); - it "should return the callback with the new rev", -> - @callback.calledWith(null, true, @rev + 1).should.equal true + return it("should return the callback with the new rev", function() { + return this.callback.calledWith(null, true, this.rev + 1).should.equal(true); + }); + }); - describe "when only the version has changed", -> - beforeEach -> - @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version + 1, @originalRanges, @callback + describe("when only the version has changed", function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines, this.version + 1, this.originalRanges, this.callback); + }); - it "should not change the lines or ranges", -> - @MongoManager.upsertIntoDocCollection.called.should.equal false + it("should not change the lines or ranges", function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); + }); - it "should update the version", -> - @MongoManager.setDocVersion - .calledWith(@doc_id, @version + 1) - .should.equal true + it("should update the version", function() { + return this.MongoManager.setDocVersion + .calledWith(this.doc_id, this.version + 1) + .should.equal(true); + }); - it "should return the callback with the old rev", -> - @callback.calledWith(null, true, @rev).should.equal true + return it("should return the callback with the old rev", function() { + return this.callback.calledWith(null, true, this.rev).should.equal(true); + }); + }); - describe "when the doc has not changed at all", -> - beforeEach -> - @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines, @version, @originalRanges, @callback + describe("when the doc has not changed at all", function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines, this.version, this.originalRanges, this.callback); + }); - it "should not update the ranges or lines", -> - @MongoManager.upsertIntoDocCollection.called.should.equal false + it("should not update the ranges or lines", function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); + }); - it "should not update the version", -> - @MongoManager.setDocVersion.called.should.equal false + it("should not update the version", function() { + return this.MongoManager.setDocVersion.called.should.equal(false); + }); - it "should return the callback with the old rev and modified == false", -> - @callback.calledWith(null, false, @rev).should.equal true + return it("should return the callback with the old rev and modified == false", function() { + return this.callback.calledWith(null, false, this.rev).should.equal(true); + }); + }); - describe "when the version is null", -> - beforeEach -> - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, null, @originalRanges, @callback + describe("when the version is null", function() { + beforeEach(function() { + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, null, this.originalRanges, this.callback); + }); - it "should return an error", -> - @callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal true + return it("should return an error", function() { + return this.callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal(true); + }); + }); - describe "when the lines are null", -> - beforeEach -> - @DocManager.updateDoc @project_id, @doc_id, null, @version, @originalRanges, @callback + describe("when the lines are null", function() { + beforeEach(function() { + return this.DocManager.updateDoc(this.project_id, this.doc_id, null, this.version, this.originalRanges, this.callback); + }); - it "should return an error", -> - @callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal true + return it("should return an error", function() { + return this.callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal(true); + }); + }); - describe "when the ranges are null", -> - beforeEach -> - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, null, @callback + describe("when the ranges are null", function() { + beforeEach(function() { + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, null, this.callback); + }); - it "should return an error", -> - @callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal true + return it("should return an error", function() { + return this.callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal(true); + }); + }); - describe "when there is a generic error getting the doc", -> - beforeEach -> - @error = new Error("doc could not be found") - @DocManager._getDoc = sinon.stub().callsArgWith(3, @error, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback + describe("when there is a generic error getting the doc", function() { + beforeEach(function() { + this.error = new Error("doc could not be found"); + this.DocManager._getDoc = sinon.stub().callsArgWith(3, this.error, null, null); + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, this.originalRanges, this.callback); + }); - it "should not upsert the document to the doc collection", -> - @MongoManager.upsertIntoDocCollection.called.should.equal false + it("should not upsert the document to the doc collection", function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); + }); - it "should return the callback with the error", -> - @callback.calledWith(@error).should.equal true + return it("should return the callback with the error", function() { + return this.callback.calledWith(this.error).should.equal(true); + }); + }); - describe "when the doc lines have not changed", -> - beforeEach -> - @DocManager._getDoc = sinon.stub().callsArgWith(3, null, @doc) - @DocManager.updateDoc @project_id, @doc_id, @oldDocLines.slice(), @version, @originalRanges, @callback + describe("when the doc lines have not changed", function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines.slice(), this.version, this.originalRanges, this.callback); + }); - it "should not update the doc", -> - @MongoManager.upsertIntoDocCollection.called.should.equal false + it("should not update the doc", function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); + }); - it "should return the callback with the existing rev", -> - @callback.calledWith(null, false, @rev).should.equal true + return it("should return the callback with the existing rev", function() { + return this.callback.calledWith(null, false, this.rev).should.equal(true); + }); + }); - describe "when the doc does not exist", -> - beforeEach -> - @DocManager._getDoc = sinon.stub().callsArgWith(3, null, null, null) - @DocManager.updateDoc @project_id, @doc_id, @newDocLines, @version, @originalRanges, @callback + return describe("when the doc does not exist", function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, null, null); + return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, this.originalRanges, this.callback); + }); - it "should upsert the document to the doc collection", -> - @MongoManager.upsertIntoDocCollection - .calledWith(@project_id, @doc_id, {lines: @newDocLines, ranges: @originalRanges}) - .should.equal true + it("should upsert the document to the doc collection", function() { + return this.MongoManager.upsertIntoDocCollection + .calledWith(this.project_id, this.doc_id, {lines: this.newDocLines, ranges: this.originalRanges}) + .should.equal(true); + }); - it "should set the version", -> - @MongoManager.setDocVersion - .calledWith(@doc_id, @version) - .should.equal true + it("should set the version", function() { + return this.MongoManager.setDocVersion + .calledWith(this.doc_id, this.version) + .should.equal(true); + }); - it "should return the callback with the new rev", -> - @callback.calledWith(null, true, 1).should.equal true + return it("should return the callback with the new rev", function() { + return this.callback.calledWith(null, true, 1).should.equal(true); + }); + }); + }); +}); diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.js b/services/docstore/test/unit/coffee/HttpControllerTests.js index 3b7ffbbe8d..615ed5c798 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.js +++ b/services/docstore/test/unit/coffee/HttpControllerTests.js @@ -1,357 +1,444 @@ -SandboxedModule = require('sandboxed-module') -assert = require("chai").assert -sinon = require('sinon') -chai = require('chai') -chai.should() -expect = chai.expect -modulePath = require('path').join __dirname, '../../../app/js/HttpController' -ObjectId = require("mongojs").ObjectId +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const SandboxedModule = require('sandboxed-module'); +const { + assert +} = require("chai"); +const sinon = require('sinon'); +const chai = require('chai'); +chai.should(); +const { + expect +} = chai; +const modulePath = require('path').join(__dirname, '../../../app/js/HttpController'); +const { + ObjectId +} = require("mongojs"); -describe "HttpController", -> - beforeEach -> - @HttpController = SandboxedModule.require modulePath, requires: - "./DocManager": @DocManager = {} - "./DocArchiveManager": @DocArchiveManager = {} - "logger-sharelatex": @logger = { log: sinon.stub(), error: sinon.stub() } +describe("HttpController", function() { + beforeEach(function() { + this.HttpController = SandboxedModule.require(modulePath, { requires: { + "./DocManager": (this.DocManager = {}), + "./DocArchiveManager": (this.DocArchiveManager = {}), + "logger-sharelatex": (this.logger = { log: sinon.stub(), error: sinon.stub() }), "./HealthChecker": {} - @res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() } - @res.status = sinon.stub().returns(@res) - @req = { query:{}} - @next = sinon.stub() - @project_id = "mock-project-id" - @doc_id = "mock-doc-id" - @doc = { - _id: @doc_id - lines: ["mock", "lines", " here", "", "", " spaces "] - version: 42 - rev: 5 } - @deletedDoc = { - deleted:true - _id: @doc_id - lines: ["mock", "lines", " here", "", "", " spaces "] - version: 42 + }); + this.res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() }; + this.res.status = sinon.stub().returns(this.res); + this.req = { query:{}}; + this.next = sinon.stub(); + this.project_id = "mock-project-id"; + this.doc_id = "mock-doc-id"; + this.doc = { + _id: this.doc_id, + lines: ["mock", "lines", " here", "", "", " spaces "], + version: 42, rev: 5 - } + }; + return this.deletedDoc = { + deleted:true, + _id: this.doc_id, + lines: ["mock", "lines", " here", "", "", " spaces "], + version: 42, + rev: 5 + };}); - describe "getDoc", -> + describe("getDoc", function() { - describe "without deleted docs", -> - beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id - @DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, @doc) - @HttpController.getDoc @req, @res, @next + describe("without deleted docs", function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + }; + this.DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, this.doc); + return this.HttpController.getDoc(this.req, this.res, this.next); + }); - it "should get the document with the version (including deleted)", -> - @DocManager.getFullDoc - .calledWith(@project_id, @doc_id) - .should.equal true + it("should get the document with the version (including deleted)", function() { + return this.DocManager.getFullDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true); + }); - it "should return the doc as JSON", -> - @res.json + return it("should return the doc as JSON", function() { + return this.res.json .calledWith({ - _id: @doc_id - lines: @doc.lines - rev: @doc.rev - version: @doc.version + _id: this.doc_id, + lines: this.doc.lines, + rev: this.doc.rev, + version: this.doc.version }) - .should.equal true + .should.equal(true); + }); + }); - describe "which is deleted", -> - beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id - @DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, @deletedDoc) + return describe("which is deleted", function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + }; + return this.DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, this.deletedDoc); + }); - it "should get the doc from the doc manager", -> - @HttpController.getDoc @req, @res, @next - @DocManager.getFullDoc.calledWith(@project_id, @doc_id).should.equal true + it("should get the doc from the doc manager", function() { + this.HttpController.getDoc(this.req, this.res, this.next); + return this.DocManager.getFullDoc.calledWith(this.project_id, this.doc_id).should.equal(true); + }); - it "should return 404 if the query string delete is not set ", -> - @HttpController.getDoc @req, @res, @next - @res.send.calledWith(404).should.equal true + it("should return 404 if the query string delete is not set ", function() { + this.HttpController.getDoc(this.req, this.res, this.next); + return this.res.send.calledWith(404).should.equal(true); + }); - it "should return the doc as JSON if include_deleted is set to true", -> - @req.query.include_deleted = "true" - @HttpController.getDoc @req, @res, @next - @res.json + return it("should return the doc as JSON if include_deleted is set to true", function() { + this.req.query.include_deleted = "true"; + this.HttpController.getDoc(this.req, this.res, this.next); + return this.res.json .calledWith({ - _id: @doc_id - lines: @doc.lines - rev: @doc.rev - deleted: true - version: @doc.version + _id: this.doc_id, + lines: this.doc.lines, + rev: this.doc.rev, + deleted: true, + version: this.doc.version }) - .should.equal true + .should.equal(true); + }); + }); + }); - describe "getRawDoc", -> - beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id - @DocManager.getDocLines = sinon.stub().callsArgWith(2, null, @doc) - @HttpController.getRawDoc @req, @res, @next + describe("getRawDoc", function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + }; + this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc); + return this.HttpController.getRawDoc(this.req, this.res, this.next); + }); - it "should get the document without the version", -> - @DocManager.getDocLines - .calledWith(@project_id, @doc_id) - .should.equal true + it("should get the document without the version", function() { + return this.DocManager.getDocLines + .calledWith(this.project_id, this.doc_id) + .should.equal(true); + }); - it "should set the content type header", -> - @res.setHeader.calledWith('content-type', 'text/plain').should.equal true + it("should set the content type header", function() { + return this.res.setHeader.calledWith('content-type', 'text/plain').should.equal(true); + }); - it "should send the raw version of the doc", -> - assert.deepEqual @res.send.args[0][0], "#{@doc.lines[0]}\n#{@doc.lines[1]}\n#{@doc.lines[2]}\n#{@doc.lines[3]}\n#{@doc.lines[4]}\n#{@doc.lines[5]}" + return it("should send the raw version of the doc", function() { + return assert.deepEqual(this.res.send.args[0][0], `${this.doc.lines[0]}\n${this.doc.lines[1]}\n${this.doc.lines[2]}\n${this.doc.lines[3]}\n${this.doc.lines[4]}\n${this.doc.lines[5]}`); + }); + }); - describe "getAllDocs", -> - describe "normally", -> - beforeEach -> - @req.params = - project_id: @project_id - @docs = [{ - _id: ObjectId() - lines: ["mock", "lines", "one"] + describe("getAllDocs", function() { + describe("normally", function() { + beforeEach(function() { + this.req.params = + {project_id: this.project_id}; + this.docs = [{ + _id: ObjectId(), + lines: ["mock", "lines", "one"], rev: 2 }, { - _id: ObjectId() - lines: ["mock", "lines", "two"] + _id: ObjectId(), + lines: ["mock", "lines", "two"], rev: 4 - }] - @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, @docs) - @HttpController.getAllDocs @req, @res, @next + }]; + this.DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, this.docs); + return this.HttpController.getAllDocs(this.req, this.res, this.next); + }); - it "should get all the (non-deleted) docs", -> - @DocManager.getAllNonDeletedDocs - .calledWith(@project_id, {lines: true, rev: true}) - .should.equal true + it("should get all the (non-deleted) docs", function() { + return this.DocManager.getAllNonDeletedDocs + .calledWith(this.project_id, {lines: true, rev: true}) + .should.equal(true); + }); - it "should return the doc as JSON", -> - @res.json + return it("should return the doc as JSON", function() { + return this.res.json .calledWith([{ - _id: @docs[0]._id.toString() - lines: @docs[0].lines - rev: @docs[0].rev + _id: this.docs[0]._id.toString(), + lines: this.docs[0].lines, + rev: this.docs[0].rev }, { - _id: @docs[1]._id.toString() - lines: @docs[1].lines - rev: @docs[1].rev + _id: this.docs[1]._id.toString(), + lines: this.docs[1].lines, + rev: this.docs[1].rev }]) - .should.equal true + .should.equal(true); + }); + }); - describe "with a null doc", -> - beforeEach -> - @req.params = - project_id: @project_id - @docs = [{ - _id: ObjectId() - lines: ["mock", "lines", "one"] + return describe("with a null doc", function() { + beforeEach(function() { + this.req.params = + {project_id: this.project_id}; + this.docs = [{ + _id: ObjectId(), + lines: ["mock", "lines", "one"], rev: 2 }, null, { - _id: ObjectId() - lines: ["mock", "lines", "two"] + _id: ObjectId(), + lines: ["mock", "lines", "two"], rev: 4 - }] - @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, @docs) - @HttpController.getAllDocs @req, @res, @next + }]; + this.DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, this.docs); + return this.HttpController.getAllDocs(this.req, this.res, this.next); + }); - it "should return the non null docs as JSON", -> - @res.json + it("should return the non null docs as JSON", function() { + return this.res.json .calledWith([{ - _id: @docs[0]._id.toString() - lines: @docs[0].lines - rev: @docs[0].rev + _id: this.docs[0]._id.toString(), + lines: this.docs[0].lines, + rev: this.docs[0].rev }, { - _id: @docs[2]._id.toString() - lines: @docs[2].lines - rev: @docs[2].rev + _id: this.docs[2]._id.toString(), + lines: this.docs[2].lines, + rev: this.docs[2].rev }]) - .should.equal true + .should.equal(true); + }); - it "should log out an error", -> - @logger.error - .calledWith( - err: sinon.match.has('message', "null doc") - project_id: @project_id + return it("should log out an error", function() { + return this.logger.error + .calledWith({ + err: sinon.match.has('message', "null doc"), + project_id: this.project_id + }, "encountered null doc" ) - .should.equal true + .should.equal(true); + }); + }); + }); - describe "getAllRanges", -> - describe "normally", -> - beforeEach -> - @req.params = - project_id: @project_id - @docs = [{ - _id: ObjectId() - ranges: {"mock_ranges": "one"} - }, { - _id: ObjectId() - ranges: {"mock_ranges": "two"} - }] - @DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, @docs) - @HttpController.getAllRanges @req, @res, @next + describe("getAllRanges", () => describe("normally", function() { + beforeEach(function() { + this.req.params = + {project_id: this.project_id}; + this.docs = [{ + _id: ObjectId(), + ranges: {"mock_ranges": "one"} + }, { + _id: ObjectId(), + ranges: {"mock_ranges": "two"} + }]; + this.DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, this.docs); + return this.HttpController.getAllRanges(this.req, this.res, this.next); + }); - it "should get all the (non-deleted) doc ranges", -> - @DocManager.getAllNonDeletedDocs - .calledWith(@project_id, {ranges: true}) - .should.equal true + it("should get all the (non-deleted) doc ranges", function() { + return this.DocManager.getAllNonDeletedDocs + .calledWith(this.project_id, {ranges: true}) + .should.equal(true); + }); - it "should return the doc as JSON", -> - @res.json - .calledWith([{ - _id: @docs[0]._id.toString() - ranges: @docs[0].ranges - }, { - _id: @docs[1]._id.toString() - ranges: @docs[1].ranges - }]) - .should.equal true + return it("should return the doc as JSON", function() { + return this.res.json + .calledWith([{ + _id: this.docs[0]._id.toString(), + ranges: this.docs[0].ranges + }, { + _id: this.docs[1]._id.toString(), + ranges: this.docs[1].ranges + }]) + .should.equal(true); + }); + })); - describe "updateDoc", -> - beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id + describe("updateDoc", function() { + beforeEach(function() { + return this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + }; + }); - describe "when the doc lines exist and were updated", -> - beforeEach -> - @req.body = - lines: @lines = ["hello", "world"] - version: @version = 42 - ranges: @ranges = { changes: "mock" } - @DocManager.updateDoc = sinon.stub().yields(null, true, @rev = 5) - @HttpController.updateDoc @req, @res, @next + describe("when the doc lines exist and were updated", function() { + beforeEach(function() { + this.req.body = { + lines: (this.lines = ["hello", "world"]), + version: (this.version = 42), + ranges: (this.ranges = { changes: "mock" }) + }; + this.DocManager.updateDoc = sinon.stub().yields(null, true, (this.rev = 5)); + return this.HttpController.updateDoc(this.req, this.res, this.next); + }); - it "should update the document", -> - @DocManager.updateDoc - .calledWith(@project_id, @doc_id, @lines, @version, @ranges) - .should.equal true + it("should update the document", function() { + return this.DocManager.updateDoc + .calledWith(this.project_id, this.doc_id, this.lines, this.version, this.ranges) + .should.equal(true); + }); - it "should return a modified status", -> - @res.json - .calledWith(modified: true, rev: @rev) - .should.equal true + return it("should return a modified status", function() { + return this.res.json + .calledWith({modified: true, rev: this.rev}) + .should.equal(true); + }); + }); - describe "when the doc lines exist and were not updated", -> - beforeEach -> - @req.body = - lines: @lines = ["hello", "world"] - version: @version = 42 + describe("when the doc lines exist and were not updated", function() { + beforeEach(function() { + this.req.body = { + lines: (this.lines = ["hello", "world"]), + version: (this.version = 42), ranges: {} - @DocManager.updateDoc = sinon.stub().yields(null, false, @rev = 5) - @HttpController.updateDoc @req, @res, @next + }; + this.DocManager.updateDoc = sinon.stub().yields(null, false, (this.rev = 5)); + return this.HttpController.updateDoc(this.req, this.res, this.next); + }); - it "should return a modified status", -> - @res.json - .calledWith(modified: false, rev: @rev) - .should.equal true + return it("should return a modified status", function() { + return this.res.json + .calledWith({modified: false, rev: this.rev}) + .should.equal(true); + }); + }); - describe "when the doc lines are not provided", -> - beforeEach -> - @req.body = { version: 42, ranges: {} } - @DocManager.updateDoc = sinon.stub().yields(null, false) - @HttpController.updateDoc @req, @res, @next + describe("when the doc lines are not provided", function() { + beforeEach(function() { + this.req.body = { version: 42, ranges: {} }; + this.DocManager.updateDoc = sinon.stub().yields(null, false); + return this.HttpController.updateDoc(this.req, this.res, this.next); + }); - it "should not update the document", -> - @DocManager.updateDoc.called.should.equal false + it("should not update the document", function() { + return this.DocManager.updateDoc.called.should.equal(false); + }); - it "should return a 400 (bad request) response", -> - @res.send + return it("should return a 400 (bad request) response", function() { + return this.res.send .calledWith(400) - .should.equal true + .should.equal(true); + }); + }); - describe "when the doc version are not provided", -> - beforeEach -> - @req.body = { version: 42, lines: ["hello world"] } - @DocManager.updateDoc = sinon.stub().yields(null, false) - @HttpController.updateDoc @req, @res, @next + describe("when the doc version are not provided", function() { + beforeEach(function() { + this.req.body = { version: 42, lines: ["hello world"] }; + this.DocManager.updateDoc = sinon.stub().yields(null, false); + return this.HttpController.updateDoc(this.req, this.res, this.next); + }); - it "should not update the document", -> - @DocManager.updateDoc.called.should.equal false + it("should not update the document", function() { + return this.DocManager.updateDoc.called.should.equal(false); + }); - it "should return a 400 (bad request) response", -> - @res.send + return it("should return a 400 (bad request) response", function() { + return this.res.send .calledWith(400) - .should.equal true + .should.equal(true); + }); + }); - describe "when the doc ranges is not provided", -> - beforeEach -> - @req.body = { lines : [ "foo" ], version: 42 } - @DocManager.updateDoc = sinon.stub().yields(null, false) - @HttpController.updateDoc @req, @res, @next + describe("when the doc ranges is not provided", function() { + beforeEach(function() { + this.req.body = { lines : [ "foo" ], version: 42 }; + this.DocManager.updateDoc = sinon.stub().yields(null, false); + return this.HttpController.updateDoc(this.req, this.res, this.next); + }); - it "should not update the document", -> - @DocManager.updateDoc.called.should.equal false + it("should not update the document", function() { + return this.DocManager.updateDoc.called.should.equal(false); + }); - it "should return a 400 (bad request) response", -> - @res.send + return it("should return a 400 (bad request) response", function() { + return this.res.send .calledWith(400) - .should.equal true + .should.equal(true); + }); + }); - describe "when the doc body is too large", -> - beforeEach -> - @req.body = - lines: @lines = Array(2049).fill('a'.repeat(1024)) - version: @version = 42 - ranges: @ranges = { changes: "mock" } - @HttpController.updateDoc @req, @res, @next + return describe("when the doc body is too large", function() { + beforeEach(function() { + this.req.body = { + lines: (this.lines = Array(2049).fill('a'.repeat(1024))), + version: (this.version = 42), + ranges: (this.ranges = { changes: "mock" }) + }; + return this.HttpController.updateDoc(this.req, this.res, this.next); + }); - it "should return a 413 (too large) response", -> - sinon.assert.calledWith(@res.status, 413) + it("should return a 413 (too large) response", function() { + return sinon.assert.calledWith(this.res.status, 413); + }); - it "should report that the document body is too large", -> - sinon.assert.calledWith(@res.send, "document body too large") + return it("should report that the document body is too large", function() { + return sinon.assert.calledWith(this.res.send, "document body too large"); + }); + }); + }); - describe "deleteDoc", -> - beforeEach -> - @req.params = - project_id: @project_id - doc_id: @doc_id - @DocManager.deleteDoc = sinon.stub().callsArg(2) - @HttpController.deleteDoc @req, @res, @next + describe("deleteDoc", function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + }; + this.DocManager.deleteDoc = sinon.stub().callsArg(2); + return this.HttpController.deleteDoc(this.req, this.res, this.next); + }); - it "should delete the document", -> - @DocManager.deleteDoc - .calledWith(@project_id, @doc_id) - .should.equal true + it("should delete the document", function() { + return this.DocManager.deleteDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true); + }); - it "should return a 204 (No Content)", -> - @res.send + return it("should return a 204 (No Content)", function() { + return this.res.send .calledWith(204) - .should.equal true + .should.equal(true); + }); + }); - describe "archiveAllDocs", -> - beforeEach -> - @req.params = - project_id: @project_id - @DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1) - @HttpController.archiveAllDocs @req, @res, @next + describe("archiveAllDocs", function() { + beforeEach(function() { + this.req.params = + {project_id: this.project_id}; + this.DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1); + return this.HttpController.archiveAllDocs(this.req, this.res, this.next); + }); - it "should archive the project", -> - @DocArchiveManager.archiveAllDocs - .calledWith(@project_id) - .should.equal true + it("should archive the project", function() { + return this.DocArchiveManager.archiveAllDocs + .calledWith(this.project_id) + .should.equal(true); + }); - it "should return a 204 (No Content)", -> - @res.send + return it("should return a 204 (No Content)", function() { + return this.res.send .calledWith(204) - .should.equal true + .should.equal(true); + }); + }); - describe "destroyAllDocs", -> - beforeEach -> - @req.params = - project_id: @project_id - @DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1) - @HttpController.destroyAllDocs @req, @res, @next + return describe("destroyAllDocs", function() { + beforeEach(function() { + this.req.params = + {project_id: this.project_id}; + this.DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1); + return this.HttpController.destroyAllDocs(this.req, this.res, this.next); + }); - it "should destroy the docs", -> - sinon.assert.calledWith(@DocArchiveManager.destroyAllDocs, @project_id) + it("should destroy the docs", function() { + return sinon.assert.calledWith(this.DocArchiveManager.destroyAllDocs, this.project_id); + }); - it "should return 204", -> - sinon.assert.calledWith(@res.send, 204) + return it("should return 204", function() { + return sinon.assert.calledWith(this.res.send, 204); + }); + }); +}); diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.js b/services/docstore/test/unit/coffee/MongoManagerTests.js index 842a3c8884..0832c89d21 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.js +++ b/services/docstore/test/unit/coffee/MongoManagerTests.js @@ -1,168 +1,225 @@ -SandboxedModule = require('sandboxed-module') -sinon = require('sinon') -require('chai').should() -modulePath = require('path').join __dirname, '../../../app/js/MongoManager' -ObjectId = require("mongojs").ObjectId -assert = require("chai").assert +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const SandboxedModule = require('sandboxed-module'); +const sinon = require('sinon'); +require('chai').should(); +const modulePath = require('path').join(__dirname, '../../../app/js/MongoManager'); +const { + ObjectId +} = require("mongojs"); +const { + assert +} = require("chai"); -describe "MongoManager", -> - beforeEach -> - @MongoManager = SandboxedModule.require modulePath, requires: - "./mongojs": - db: @db = { docs: {}, docOps: {} } - ObjectId: ObjectId - 'metrics-sharelatex': {timeAsyncMethod: sinon.stub()} - 'logger-sharelatex': {log: ()->} - @project_id = ObjectId().toString() - @doc_id = ObjectId().toString() - @callback = sinon.stub() - @stubbedErr = new Error("hello world") +describe("MongoManager", function() { + beforeEach(function() { + this.MongoManager = SandboxedModule.require(modulePath, { requires: { + "./mongojs": { + db: (this.db = { docs: {}, docOps: {} }), + ObjectId + }, + 'metrics-sharelatex': {timeAsyncMethod: sinon.stub()}, + 'logger-sharelatex': {log(){}} + } + }); + this.project_id = ObjectId().toString(); + this.doc_id = ObjectId().toString(); + this.callback = sinon.stub(); + return this.stubbedErr = new Error("hello world"); + }); - describe "findDoc", -> - beforeEach -> - @doc = { name: "mock-doc"} - @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc]) - @filter = { lines: true } - @MongoManager.findDoc @project_id, @doc_id, @filter, @callback + describe("findDoc", function() { + beforeEach(function() { + this.doc = { name: "mock-doc"}; + this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc]); + this.filter = { lines: true }; + return this.MongoManager.findDoc(this.project_id, this.doc_id, this.filter, this.callback); + }); - it "should find the doc", -> - @db.docs.find + it("should find the doc", function() { + return this.db.docs.find .calledWith({ - _id: ObjectId(@doc_id) - project_id: ObjectId(@project_id) - }, @filter) - .should.equal true + _id: ObjectId(this.doc_id), + project_id: ObjectId(this.project_id) + }, this.filter) + .should.equal(true); + }); - it "should call the callback with the doc", -> - @callback.calledWith(null, @doc).should.equal true + return it("should call the callback with the doc", function() { + return this.callback.calledWith(null, this.doc).should.equal(true); + }); + }); - describe "getProjectsDocs", -> - beforeEach -> - @filter = {lines: true} - @doc1 = { name: "mock-doc1" } - @doc2 = { name: "mock-doc2" } - @doc3 = { name: "mock-doc3" } - @doc4 = { name: "mock-doc4" } - @db.docs.find = sinon.stub().callsArgWith(2, null, [@doc, @doc3, @doc4]) + describe("getProjectsDocs", function() { + beforeEach(function() { + this.filter = {lines: true}; + this.doc1 = { name: "mock-doc1" }; + this.doc2 = { name: "mock-doc2" }; + this.doc3 = { name: "mock-doc3" }; + this.doc4 = { name: "mock-doc4" }; + return this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc, this.doc3, this.doc4]); + }); - describe "with included_deleted = false", -> - beforeEach -> - @MongoManager.getProjectsDocs @project_id, include_deleted: false, @filter, @callback + describe("with included_deleted = false", function() { + beforeEach(function() { + return this.MongoManager.getProjectsDocs(this.project_id, {include_deleted: false}, this.filter, this.callback); + }); - it "should find the non-deleted docs via the project_id", -> - @db.docs.find + it("should find the non-deleted docs via the project_id", function() { + return this.db.docs.find .calledWith({ - project_id: ObjectId(@project_id) + project_id: ObjectId(this.project_id), deleted: { $ne: true } - }, @filter) - .should.equal true + }, this.filter) + .should.equal(true); + }); - it "should call the callback with the docs", -> - @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true + return it("should call the callback with the docs", function() { + return this.callback.calledWith(null, [this.doc, this.doc3, this.doc4]).should.equal(true); + }); + }); - describe "with included_deleted = true", -> - beforeEach -> - @MongoManager.getProjectsDocs @project_id, include_deleted: true, @filter, @callback + return describe("with included_deleted = true", function() { + beforeEach(function() { + return this.MongoManager.getProjectsDocs(this.project_id, {include_deleted: true}, this.filter, this.callback); + }); - it "should find all via the project_id", -> - @db.docs.find + it("should find all via the project_id", function() { + return this.db.docs.find .calledWith({ - project_id: ObjectId(@project_id) - }, @filter) - .should.equal true + project_id: ObjectId(this.project_id) + }, this.filter) + .should.equal(true); + }); - it "should call the callback with the docs", -> - @callback.calledWith(null, [@doc, @doc3, @doc4]).should.equal true + return it("should call the callback with the docs", function() { + return this.callback.calledWith(null, [this.doc, this.doc3, this.doc4]).should.equal(true); + }); + }); + }); - describe "upsertIntoDocCollection", -> - beforeEach -> - @db.docs.update = sinon.stub().callsArgWith(3, @stubbedErr) - @oldRev = 77 + describe("upsertIntoDocCollection", function() { + beforeEach(function() { + this.db.docs.update = sinon.stub().callsArgWith(3, this.stubbedErr); + return this.oldRev = 77; + }); - it "should upsert the document", (done)-> - @MongoManager.upsertIntoDocCollection @project_id, @doc_id, {@lines}, (err)=> - args = @db.docs.update.args[0] - assert.deepEqual args[0], {_id: ObjectId(@doc_id)} - assert.equal args[1]["$set"]["lines"], @lines - assert.equal args[1]["$inc"]["rev"], 1 - assert.deepEqual args[1]["$set"]["project_id"], ObjectId(@project_id) - done() + it("should upsert the document", function(done){ + return this.MongoManager.upsertIntoDocCollection(this.project_id, this.doc_id, {lines: this.lines}, err=> { + const args = this.db.docs.update.args[0]; + assert.deepEqual(args[0], {_id: ObjectId(this.doc_id)}); + assert.equal(args[1]["$set"]["lines"], this.lines); + assert.equal(args[1]["$inc"]["rev"], 1); + assert.deepEqual(args[1]["$set"]["project_id"], ObjectId(this.project_id)); + return done(); + }); + }); - it "should return the error", (done)-> - @MongoManager.upsertIntoDocCollection @project_id, @doc_id, {@lines}, (err)=> - err.should.equal @stubbedErr - done() + return it("should return the error", function(done){ + return this.MongoManager.upsertIntoDocCollection(this.project_id, this.doc_id, {lines: this.lines}, err=> { + err.should.equal(this.stubbedErr); + return done(); + }); + }); + }); - describe "markDocAsDeleted", -> - beforeEach -> - @db.docs.update = sinon.stub().callsArgWith(2, @stubbedErr) - @oldRev = 77 + describe("markDocAsDeleted", function() { + beforeEach(function() { + this.db.docs.update = sinon.stub().callsArgWith(2, this.stubbedErr); + return this.oldRev = 77; + }); - it "should process the update", (done) -> - @MongoManager.markDocAsDeleted @project_id, @doc_id, (err)=> - args = @db.docs.update.args[0] - assert.deepEqual args[0], {_id: ObjectId(@doc_id), project_id: ObjectId(@project_id)} - assert.equal args[1]["$set"]["deleted"], true - done() + it("should process the update", function(done) { + return this.MongoManager.markDocAsDeleted(this.project_id, this.doc_id, err=> { + const args = this.db.docs.update.args[0]; + assert.deepEqual(args[0], {_id: ObjectId(this.doc_id), project_id: ObjectId(this.project_id)}); + assert.equal(args[1]["$set"]["deleted"], true); + return done(); + }); + }); - it "should return the error", (done)-> - @MongoManager.markDocAsDeleted @project_id, @doc_id, (err)=> - err.should.equal @stubbedErr - done() + return it("should return the error", function(done){ + return this.MongoManager.markDocAsDeleted(this.project_id, this.doc_id, err=> { + err.should.equal(this.stubbedErr); + return done(); + }); + }); + }); - describe "destroyDoc", -> - beforeEach (done) -> - @db.docs.remove = sinon.stub().yields() - @db.docOps.remove = sinon.stub().yields() - @MongoManager.destroyDoc '123456789012', done + describe("destroyDoc", function() { + beforeEach(function(done) { + this.db.docs.remove = sinon.stub().yields(); + this.db.docOps.remove = sinon.stub().yields(); + return this.MongoManager.destroyDoc('123456789012', done); + }); - it "should destroy the doc", -> - sinon.assert.calledWith(@db.docs.remove, {_id: ObjectId('123456789012')}) + it("should destroy the doc", function() { + return sinon.assert.calledWith(this.db.docs.remove, {_id: ObjectId('123456789012')}); + }); - it "should destroy the docOps", -> - sinon.assert.calledWith(@db.docOps.remove, {doc_id: ObjectId('123456789012')}) + return it("should destroy the docOps", function() { + return sinon.assert.calledWith(this.db.docOps.remove, {doc_id: ObjectId('123456789012')}); + }); + }); - describe "getDocVersion", -> - describe "when the doc exists", -> - beforeEach -> - @doc = - version: @version = 42 - @db.docOps.find = sinon.stub().callsArgWith(2, null, [@doc]) - @MongoManager.getDocVersion @doc_id, @callback + describe("getDocVersion", function() { + describe("when the doc exists", function() { + beforeEach(function() { + this.doc = + {version: (this.version = 42)}; + this.db.docOps.find = sinon.stub().callsArgWith(2, null, [this.doc]); + return this.MongoManager.getDocVersion(this.doc_id, this.callback); + }); - it "should look for the doc in the database", -> - @db.docOps.find - .calledWith({ doc_id: ObjectId(@doc_id) }, {version: 1}) - .should.equal true + it("should look for the doc in the database", function() { + return this.db.docOps.find + .calledWith({ doc_id: ObjectId(this.doc_id) }, {version: 1}) + .should.equal(true); + }); - it "should call the callback with the version", -> - @callback.calledWith(null, @version).should.equal true + return it("should call the callback with the version", function() { + return this.callback.calledWith(null, this.version).should.equal(true); + }); + }); - describe "when the doc doesn't exist", -> - beforeEach -> - @db.docOps.find = sinon.stub().callsArgWith(2, null, []) - @MongoManager.getDocVersion @doc_id, @callback + return describe("when the doc doesn't exist", function() { + beforeEach(function() { + this.db.docOps.find = sinon.stub().callsArgWith(2, null, []); + return this.MongoManager.getDocVersion(this.doc_id, this.callback); + }); - it "should call the callback with 0", -> - @callback.calledWith(null, 0).should.equal true + return it("should call the callback with 0", function() { + return this.callback.calledWith(null, 0).should.equal(true); + }); + }); + }); - describe "setDocVersion", -> - beforeEach -> - @version = 42 - @db.docOps.update = sinon.stub().callsArg(3) - @MongoManager.setDocVersion @doc_id, @version, @callback + return describe("setDocVersion", function() { + beforeEach(function() { + this.version = 42; + this.db.docOps.update = sinon.stub().callsArg(3); + return this.MongoManager.setDocVersion(this.doc_id, this.version, this.callback); + }); - it "should update the doc version", -> - @db.docOps.update + it("should update the doc version", function() { + return this.db.docOps.update .calledWith({ - doc_id: ObjectId(@doc_id) + doc_id: ObjectId(this.doc_id) }, { - $set: - version: @version + $set: { + version: this.version + } }, { upsert: true }) - .should.equal true + .should.equal(true); + }); - it "should call the callback", -> - @callback.called.should.equal true + return it("should call the callback", function() { + return this.callback.called.should.equal(true); + }); + }); +}); diff --git a/services/docstore/test/unit/coffee/RangeManagerTests.js b/services/docstore/test/unit/coffee/RangeManagerTests.js index ea2416ab63..f98ca2cbe9 100644 --- a/services/docstore/test/unit/coffee/RangeManagerTests.js +++ b/services/docstore/test/unit/coffee/RangeManagerTests.js @@ -1,155 +1,192 @@ -SandboxedModule = require('sandboxed-module') -sinon = require('sinon') -require('chai').should() -expect = require('chai').expect -modulePath = require('path').join __dirname, '../../../app/js/RangeManager' -ObjectId = require("mongojs").ObjectId -assert = require("chai").assert -_ = require "underscore" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const SandboxedModule = require('sandboxed-module'); +const sinon = require('sinon'); +require('chai').should(); +const { + expect +} = require('chai'); +const modulePath = require('path').join(__dirname, '../../../app/js/RangeManager'); +const { + ObjectId +} = require("mongojs"); +const { + assert +} = require("chai"); +const _ = require("underscore"); -describe "RangeManager", -> - beforeEach -> - @RangeManager = SandboxedModule.require modulePath, requires: - "./mongojs": - ObjectId: ObjectId +describe("RangeManager", function() { + beforeEach(function() { + return this.RangeManager = SandboxedModule.require(modulePath, { requires: { + "./mongojs": { + ObjectId + } + } + } + ); + }); - describe "jsonRangesToMongo", -> - it "should convert ObjectIds and dates to proper objects", -> - change_id = ObjectId().toString() - comment_id = ObjectId().toString() - user_id = ObjectId().toString() - thread_id = ObjectId().toString() - ts = new Date().toJSON() - @RangeManager.jsonRangesToMongo({ + describe("jsonRangesToMongo", function() { + it("should convert ObjectIds and dates to proper objects", function() { + const change_id = ObjectId().toString(); + const comment_id = ObjectId().toString(); + const user_id = ObjectId().toString(); + const thread_id = ObjectId().toString(); + const ts = new Date().toJSON(); + return this.RangeManager.jsonRangesToMongo({ changes: [{ - id: change_id - op: { i: "foo", p: 3 } - metadata: - user_id: user_id - ts: ts - }] + id: change_id, + op: { i: "foo", p: 3 }, + metadata: { + user_id, + ts + } + }], comments: [{ - id: comment_id + id: comment_id, op: { c: "foo", p: 3, t: thread_id } }] - }).should.deep.equal { + }).should.deep.equal({ changes: [{ - id: ObjectId(change_id) - op: { i: "foo", p: 3 } - metadata: - user_id: ObjectId(user_id) + id: ObjectId(change_id), + op: { i: "foo", p: 3 }, + metadata: { + user_id: ObjectId(user_id), ts: new Date(ts) - }] + } + }], comments: [{ - id: ObjectId(comment_id) + id: ObjectId(comment_id), op: { c: "foo", p: 3, t: ObjectId(thread_id) } }] - } + }); + }); - it "should leave malformed ObjectIds as they are", -> - change_id = "foo" - comment_id = "bar" - user_id = "baz" - @RangeManager.jsonRangesToMongo({ + it("should leave malformed ObjectIds as they are", function() { + const change_id = "foo"; + const comment_id = "bar"; + const user_id = "baz"; + return this.RangeManager.jsonRangesToMongo({ changes: [{ - id: change_id - metadata: - user_id: user_id - }] + id: change_id, + metadata: { + user_id + } + }], comments: [{ id: comment_id }] - }).should.deep.equal { + }).should.deep.equal({ changes: [{ - id: change_id - metadata: - user_id: user_id - }] + id: change_id, + metadata: { + user_id + } + }], comments: [{ id: comment_id }] - } + }); + }); - it "should be consistent when transformed through json -> mongo -> json", -> - change_id = ObjectId().toString() - comment_id = ObjectId().toString() - user_id = ObjectId().toString() - thread_id = ObjectId().toString() - ts = new Date().toJSON() - ranges1 = { + return it("should be consistent when transformed through json -> mongo -> json", function() { + const change_id = ObjectId().toString(); + const comment_id = ObjectId().toString(); + const user_id = ObjectId().toString(); + const thread_id = ObjectId().toString(); + const ts = new Date().toJSON(); + const ranges1 = { changes: [{ - id: change_id - op: { i: "foo", p: 3 } - metadata: - user_id: user_id - ts: ts - }] + id: change_id, + op: { i: "foo", p: 3 }, + metadata: { + user_id, + ts + } + }], comments: [{ - id: comment_id + id: comment_id, op: { c: "foo", p: 3, t: thread_id } }] - } - ranges1_copy = JSON.parse(JSON.stringify(ranges1)) # jsonRangesToMongo modifies in place - ranges2 = JSON.parse(JSON.stringify(@RangeManager.jsonRangesToMongo(ranges1_copy))) - ranges1.should.deep.equal ranges2 + }; + const ranges1_copy = JSON.parse(JSON.stringify(ranges1)); // jsonRangesToMongo modifies in place + const ranges2 = JSON.parse(JSON.stringify(this.RangeManager.jsonRangesToMongo(ranges1_copy))); + return ranges1.should.deep.equal(ranges2); + }); + }); - describe "shouldUpdateRanges", -> - beforeEach () -> - @ranges = { + return describe("shouldUpdateRanges", function() { + beforeEach(function() { + this.ranges = { changes: [{ - id: ObjectId() - op: { i: "foo", p: 3 } - metadata: - user_id: ObjectId() + id: ObjectId(), + op: { i: "foo", p: 3 }, + metadata: { + user_id: ObjectId(), ts: new Date() - }] + } + }], comments: [{ - id: ObjectId() + id: ObjectId(), op: { c: "foo", p: 3, t: ObjectId() } }] - } - @ranges_copy = @RangeManager.jsonRangesToMongo(JSON.parse(JSON.stringify(@ranges))) + }; + return this.ranges_copy = this.RangeManager.jsonRangesToMongo(JSON.parse(JSON.stringify(this.ranges))); + }); - describe "with a blank new range", -> - it "should throw an error", -> - expect(() => - @RangeManager.shouldUpdateRanges(@ranges, null) - ).to.throw(Error) + describe("with a blank new range", () => it("should throw an error", function() { + return expect(() => { + return this.RangeManager.shouldUpdateRanges(this.ranges, null); + }).to.throw(Error); + })); - describe "with a blank old range", -> - it "should treat it like {}", -> - @RangeManager.shouldUpdateRanges(null, {}).should.equal false - @RangeManager.shouldUpdateRanges(null, @ranges).should.equal true + describe("with a blank old range", () => it("should treat it like {}", function() { + this.RangeManager.shouldUpdateRanges(null, {}).should.equal(false); + return this.RangeManager.shouldUpdateRanges(null, this.ranges).should.equal(true); + })); - describe "with no changes", -> - it "should return false", -> - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal false + describe("with no changes", () => it("should return false", function() { + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(false); + })); - describe "with changes", -> - it "should return true when the change id changes", -> - @ranges_copy.changes[0].id = ObjectId() - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + return describe("with changes", function() { + it("should return true when the change id changes", function() { + this.ranges_copy.changes[0].id = ObjectId(); + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); + }); - it "should return true when the change user id changes", -> - @ranges_copy.changes[0].metadata.user_id = ObjectId() - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + it("should return true when the change user id changes", function() { + this.ranges_copy.changes[0].metadata.user_id = ObjectId(); + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); + }); - it "should return true when the change ts changes", -> - @ranges_copy.changes[0].metadata.ts = new Date(Date.now() + 1000) - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + it("should return true when the change ts changes", function() { + this.ranges_copy.changes[0].metadata.ts = new Date(Date.now() + 1000); + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); + }); - it "should return true when the change op changes", -> - @ranges_copy.changes[0].op.i = "bar" - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + it("should return true when the change op changes", function() { + this.ranges_copy.changes[0].op.i = "bar"; + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); + }); - it "should return true when the comment id changes", -> - @ranges_copy.comments[0].id = ObjectId() - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + it("should return true when the comment id changes", function() { + this.ranges_copy.comments[0].id = ObjectId(); + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); + }); - it "should return true when the comment offset changes", -> - @ranges_copy.comments[0].op.p = 17 - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true + it("should return true when the comment offset changes", function() { + this.ranges_copy.comments[0].op.p = 17; + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); + }); - it "should return true when the comment content changes", -> - @ranges_copy.comments[0].op.c = "bar" - @RangeManager.shouldUpdateRanges(@ranges, @ranges_copy).should.equal true \ No newline at end of file + return it("should return true when the comment content changes", function() { + this.ranges_copy.comments[0].op.c = "bar"; + return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); + }); + }); + }); +}); \ No newline at end of file From 6e498152fdac29c2f5d31d3e3d7ecb43713ca5e3 Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:02:49 +0000 Subject: [PATCH 220/349] decaffeinate: Run post-processing cleanups on DocArchiveManagerTests.coffee and 4 other files --- .../unit/coffee/DocArchiveManagerTests.js | 44 +++++++++++-------- .../test/unit/coffee/DocManagerTests.js | 13 +++++- .../test/unit/coffee/HttpControllerTests.js | 10 ++++- .../test/unit/coffee/MongoManagerTests.js | 14 ++++-- .../test/unit/coffee/RangeManagerTests.js | 19 +++++--- 5 files changed, 68 insertions(+), 32 deletions(-) diff --git a/services/docstore/test/unit/coffee/DocArchiveManagerTests.js b/services/docstore/test/unit/coffee/DocArchiveManagerTests.js index a6602405bd..97cfa73140 100644 --- a/services/docstore/test/unit/coffee/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/coffee/DocArchiveManagerTests.js @@ -1,3 +1,11 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-return-assign, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from @@ -261,7 +269,7 @@ describe("DocArchiveManager", function() { this.MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, this.archivedDocs); this.DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null); return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err=> { - for (let doc of Array.from(this.archivedDocs)) { + for (const doc of Array.from(this.archivedDocs)) { this.DocArchiveManager.unarchiveDoc.calledWith(this.project_id, doc._id).should.equal(true); } should.not.exist(err); @@ -299,7 +307,7 @@ describe("DocArchiveManager", function() { it("should destroy all the docs", function(done){ this.DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null); return this.DocArchiveManager.destroyAllDocs(this.project_id, err=> { - for (let doc of Array.from(this.mixedDocs)) { + for (const doc of Array.from(this.mixedDocs)) { this.DocArchiveManager.destroyDoc.calledWith(this.project_id, doc._id).should.equal(true); } should.not.exist(err); @@ -337,7 +345,7 @@ describe("DocArchiveManager", function() { return expect(err).not.to.exist; }); - for (let doc of Array.from(this.mixedDocs)) { + for (const doc of Array.from(this.mixedDocs)) { sinon.assert.calledWith(this.MongoManager.destroyDoc, doc._id); } @@ -346,14 +354,14 @@ describe("DocArchiveManager", function() { }); describe("_s3DocToMongoDoc", function() { - describe("with the old schema", () => it("should return the docs lines", function(done) { - return this.DocArchiveManager._s3DocToMongoDoc(["doc", "lines"], function(error, doc) { + describe("with the old schema", function() { return it("should return the docs lines", function(done) { + return this.DocArchiveManager._s3DocToMongoDoc(["doc", "lines"], (error, doc) => { expect(doc).to.deep.equal({ lines: ["doc", "lines"] }); return done(); }); - })); + }); }); describe("with the new schema", function() { it("should return the doc lines and ranges", function(done) { @@ -362,7 +370,7 @@ describe("DocArchiveManager", function() { lines: ["doc", "lines"], ranges: {"json": "ranges"}, schema_v: 1 - }, function(error, doc) { + }, (error, doc) => { expect(doc).to.deep.equal({ lines: ["doc", "lines"], ranges: {"mongo": "ranges"} @@ -375,7 +383,7 @@ describe("DocArchiveManager", function() { return this.DocArchiveManager._s3DocToMongoDoc({ lines: ["doc", "lines"], schema_v: 1 - }, function(error, doc) { + }, (error, doc) => { expect(doc).to.deep.equal({ lines: ["doc", "lines"] }); @@ -384,23 +392,23 @@ describe("DocArchiveManager", function() { }); }); - return describe("with an unrecognised schema", () => it("should return an error", function(done) { + return describe("with an unrecognised schema", function() { return it("should return an error", function(done) { return this.DocArchiveManager._s3DocToMongoDoc({ schema_v: 2 - }, function(error, doc) { + }, (error, doc) => { expect(error).to.exist; return done(); }); - })); + }); }); }); return describe("_mongoDocToS3Doc", function() { - describe("with a valid doc", () => it("should return the json version", function(done) { + describe("with a valid doc", function() { return it("should return the json version", function(done) { let doc; return this.DocArchiveManager._mongoDocToS3Doc((doc = { lines: ["doc", "lines"], ranges: { "mock": "ranges" } - }), function(err, s3_doc) { + }), (err, s3_doc) => { expect(s3_doc).to.equal(JSON.stringify({ lines: ["doc", "lines"], ranges: { "mock": "ranges" }, @@ -409,7 +417,7 @@ describe("DocArchiveManager", function() { ); return done(); }); - })); + }); }); describe("with null bytes in the result", function() { beforeEach(function() { @@ -425,19 +433,19 @@ describe("DocArchiveManager", function() { return this.DocArchiveManager._mongoDocToS3Doc({ lines: ["doc", "lines"], ranges: { "mock": "ranges" } - }, function(err, s3_doc) { + }, (err, s3_doc) => { expect(err).to.exist; return done(); }); }); }); - return describe("without doc lines", () => it("should return an error", function(done) { - return this.DocArchiveManager._mongoDocToS3Doc({}, function(err, s3_doc) { + return describe("without doc lines", function() { return it("should return an error", function(done) { + return this.DocArchiveManager._mongoDocToS3Doc({}, (err, s3_doc) => { expect(err).to.exist; return done(); }); - })); + }); }); }); }); diff --git a/services/docstore/test/unit/coffee/DocManagerTests.js b/services/docstore/test/unit/coffee/DocManagerTests.js index bdeb97c98d..4130818601 100644 --- a/services/docstore/test/unit/coffee/DocManagerTests.js +++ b/services/docstore/test/unit/coffee/DocManagerTests.js @@ -1,3 +1,12 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-dupe-keys, + no-return-assign, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -143,7 +152,7 @@ describe("DocManager", function() { }); it("should error if inS3 is not set to true", function(done){ - return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: false}, function(err){ + return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: false}, (err) => { expect(err).to.exist; return done(); }); @@ -158,7 +167,7 @@ describe("DocManager", function() { }); return it("should not error if inS3 is set to true", function(done){ - return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: true}, function(err){ + return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: true}, (err) => { expect(err).to.not.exist; return done(); }); diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.js b/services/docstore/test/unit/coffee/HttpControllerTests.js index 615ed5c798..27bb31a325 100644 --- a/services/docstore/test/unit/coffee/HttpControllerTests.js +++ b/services/docstore/test/unit/coffee/HttpControllerTests.js @@ -1,3 +1,9 @@ +/* eslint-disable + no-return-assign, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -222,7 +228,7 @@ describe("HttpController", function() { }); }); - describe("getAllRanges", () => describe("normally", function() { + describe("getAllRanges", function() { return describe("normally", function() { beforeEach(function() { this.req.params = {project_id: this.project_id}; @@ -254,7 +260,7 @@ describe("HttpController", function() { }]) .should.equal(true); }); - })); + }); }); describe("updateDoc", function() { beforeEach(function() { diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.js b/services/docstore/test/unit/coffee/MongoManagerTests.js index 0832c89d21..d7dabe3afb 100644 --- a/services/docstore/test/unit/coffee/MongoManagerTests.js +++ b/services/docstore/test/unit/coffee/MongoManagerTests.js @@ -1,3 +1,9 @@ +/* eslint-disable + handle-callback-err, + no-return-assign, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -111,9 +117,9 @@ describe("MongoManager", function() { return this.MongoManager.upsertIntoDocCollection(this.project_id, this.doc_id, {lines: this.lines}, err=> { const args = this.db.docs.update.args[0]; assert.deepEqual(args[0], {_id: ObjectId(this.doc_id)}); - assert.equal(args[1]["$set"]["lines"], this.lines); - assert.equal(args[1]["$inc"]["rev"], 1); - assert.deepEqual(args[1]["$set"]["project_id"], ObjectId(this.project_id)); + assert.equal(args[1].$set.lines, this.lines); + assert.equal(args[1].$inc.rev, 1); + assert.deepEqual(args[1].$set.project_id, ObjectId(this.project_id)); return done(); }); }); @@ -136,7 +142,7 @@ describe("MongoManager", function() { return this.MongoManager.markDocAsDeleted(this.project_id, this.doc_id, err=> { const args = this.db.docs.update.args[0]; assert.deepEqual(args[0], {_id: ObjectId(this.doc_id), project_id: ObjectId(this.project_id)}); - assert.equal(args[1]["$set"]["deleted"], true); + assert.equal(args[1].$set.deleted, true); return done(); }); }); diff --git a/services/docstore/test/unit/coffee/RangeManagerTests.js b/services/docstore/test/unit/coffee/RangeManagerTests.js index f98ca2cbe9..b67e535181 100644 --- a/services/docstore/test/unit/coffee/RangeManagerTests.js +++ b/services/docstore/test/unit/coffee/RangeManagerTests.js @@ -1,3 +1,10 @@ +/* eslint-disable + camelcase, + no-return-assign, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -137,20 +144,20 @@ describe("RangeManager", function() { return this.ranges_copy = this.RangeManager.jsonRangesToMongo(JSON.parse(JSON.stringify(this.ranges))); }); - describe("with a blank new range", () => it("should throw an error", function() { + describe("with a blank new range", function() { return it("should throw an error", function() { return expect(() => { return this.RangeManager.shouldUpdateRanges(this.ranges, null); }).to.throw(Error); - })); + }); }); - describe("with a blank old range", () => it("should treat it like {}", function() { + describe("with a blank old range", function() { return it("should treat it like {}", function() { this.RangeManager.shouldUpdateRanges(null, {}).should.equal(false); return this.RangeManager.shouldUpdateRanges(null, this.ranges).should.equal(true); - })); + }); }); - describe("with no changes", () => it("should return false", function() { + describe("with no changes", function() { return it("should return false", function() { return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(false); - })); + }); }); return describe("with changes", function() { it("should return true when the change id changes", function() { From 75f12456105b0253c2b4940af2a2539d7f670f08 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:02:52 +0000 Subject: [PATCH 221/349] decaffeinate: rename test/unit/coffee to test/unit/js --- .../docstore/test/unit/{coffee => js}/DocArchiveManagerTests.js | 0 services/docstore/test/unit/{coffee => js}/DocManagerTests.js | 0 services/docstore/test/unit/{coffee => js}/HttpControllerTests.js | 0 services/docstore/test/unit/{coffee => js}/MongoManagerTests.js | 0 services/docstore/test/unit/{coffee => js}/RangeManagerTests.js | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename services/docstore/test/unit/{coffee => js}/DocArchiveManagerTests.js (100%) rename services/docstore/test/unit/{coffee => js}/DocManagerTests.js (100%) rename services/docstore/test/unit/{coffee => js}/HttpControllerTests.js (100%) rename services/docstore/test/unit/{coffee => js}/MongoManagerTests.js (100%) rename services/docstore/test/unit/{coffee => js}/RangeManagerTests.js (100%) diff --git a/services/docstore/test/unit/coffee/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/DocArchiveManagerTests.js rename to services/docstore/test/unit/js/DocArchiveManagerTests.js diff --git a/services/docstore/test/unit/coffee/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/DocManagerTests.js rename to services/docstore/test/unit/js/DocManagerTests.js diff --git a/services/docstore/test/unit/coffee/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/HttpControllerTests.js rename to services/docstore/test/unit/js/HttpControllerTests.js diff --git a/services/docstore/test/unit/coffee/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/MongoManagerTests.js rename to services/docstore/test/unit/js/MongoManagerTests.js diff --git a/services/docstore/test/unit/coffee/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js similarity index 100% rename from services/docstore/test/unit/coffee/RangeManagerTests.js rename to services/docstore/test/unit/js/RangeManagerTests.js From 088fd29391335b9b7323e4e2d49362dcc09901e0 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:02:55 +0000 Subject: [PATCH 222/349] prettier: convert test/unit decaffeinated files to Prettier format --- .../test/unit/js/DocArchiveManagerTests.js | 911 +++++++----- .../docstore/test/unit/js/DocManagerTests.js | 1325 ++++++++++------- .../test/unit/js/HttpControllerTests.js | 821 +++++----- .../test/unit/js/MongoManagerTests.js | 450 +++--- .../test/unit/js/RangeManagerTests.js | 414 ++--- 5 files changed, 2233 insertions(+), 1688 deletions(-) diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 97cfa73140..06bd6db8aa 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -12,441 +12,566 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const { - assert -} = require("chai"); -const sinon = require('sinon'); -const chai = require('chai'); -const should = chai.should(); -const { - expect -} = chai; -const modulePath = "../../../app/js/DocArchiveManager.js"; -const SandboxedModule = require('sandboxed-module'); -const { - ObjectId -} = require("mongojs"); -const Errors = require("../../../app/js/Errors"); -const crypto = require("crypto"); +const { assert } = require('chai') +const sinon = require('sinon') +const chai = require('chai') +const should = chai.should() +const { expect } = chai +const modulePath = '../../../app/js/DocArchiveManager.js' +const SandboxedModule = require('sandboxed-module') +const { ObjectId } = require('mongojs') +const Errors = require('../../../app/js/Errors') +const crypto = require('crypto') -describe("DocArchiveManager", function() { +describe('DocArchiveManager', function() { + beforeEach(function() { + this.settings = { + docstore: { + s3: { + secret: 'secret', + key: 'this_key', + bucket: 'doc-archive-unit-test' + } + } + } - beforeEach(function() { + this.request = { + put: {}, + get: {}, + del: {} + } - this.settings = { - docstore: { - s3: { - secret: "secret", - key: "this_key", - bucket:"doc-archive-unit-test" - } - } - }; + this.archivedDocs = [ + { + _id: ObjectId(), + inS3: true, + rev: 2 + }, + { + _id: ObjectId(), + inS3: true, + rev: 4 + }, + { + _id: ObjectId(), + inS3: true, + rev: 6 + } + ] - this.request = { - put: {}, - get: {}, - del: {} - }; + this.mongoDocs = [ + { + _id: ObjectId(), + lines: ['one', 'two', 'three'], + rev: 2 + }, + { + _id: ObjectId(), + lines: ['aaa', 'bbb', 'ccc'], + rev: 4 + }, + { + _id: ObjectId(), + inS3: true, + rev: 6 + }, + { + _id: ObjectId(), + inS3: true, + rev: 6 + }, + { + _id: ObjectId(), + lines: ['111', '222', '333'], + rev: 6 + } + ] - this.archivedDocs = [{ - _id: ObjectId(), - inS3:true, - rev: 2 - }, { - _id: ObjectId(), - inS3:true, - rev: 4 - }, { - _id: ObjectId(), - inS3:true, - rev: 6 - }]; + this.unarchivedDocs = [ + { + _id: ObjectId(), + lines: ['wombat', 'potato', 'banana'], + rev: 2 + }, + { + _id: ObjectId(), + lines: ['llama', 'turnip', 'apple'], + rev: 4 + }, + { + _id: ObjectId(), + lines: ['elephant', 'swede', 'nectarine'], + rev: 6 + } + ] - this.mongoDocs = [{ - _id: ObjectId(), - lines: ["one", "two", "three"], - rev: 2 - }, { - _id: ObjectId(), - lines: ["aaa", "bbb", "ccc"], - rev: 4 - }, { - _id: ObjectId(), - inS3: true, - rev: 6 - }, { - _id: ObjectId(), - inS3: true, - rev: 6 - }, { - _id: ObjectId(), - lines: ["111", "222", "333"], - rev: 6 - }]; + this.mixedDocs = this.archivedDocs.concat(this.unarchivedDocs) - this.unarchivedDocs = [{ - _id: ObjectId(), - lines: ["wombat", "potato", "banana"], - rev: 2 - }, { - _id: ObjectId(), - lines: ["llama", "turnip", "apple"], - rev: 4 - }, { - _id: ObjectId(), - lines: ["elephant", "swede", "nectarine"], - rev: 6 - }]; + this.MongoManager = { + markDocAsArchived: sinon.stub().callsArgWith(2, null), + upsertIntoDocCollection: sinon.stub().callsArgWith(3, null), + getProjectsDocs: sinon.stub().callsArgWith(3, null, this.mongoDocs), + getArchivedProjectDocs: sinon.stub().callsArgWith(2, null, this.mongoDocs) + } - this.mixedDocs = this.archivedDocs.concat(this.unarchivedDocs); + this.requires = { + 'settings-sharelatex': this.settings, + './MongoManager': this.MongoManager, + request: this.request, + './RangeManager': (this.RangeManager = {}), + 'logger-sharelatex': { + log() {}, + err() {} + } + } + this.globals = { JSON } - this.MongoManager = { - markDocAsArchived: sinon.stub().callsArgWith(2, null), - upsertIntoDocCollection: sinon.stub().callsArgWith(3, null), - getProjectsDocs: sinon.stub().callsArgWith(3, null, this.mongoDocs), - getArchivedProjectDocs: sinon.stub().callsArgWith(2, null, this.mongoDocs) - }; + this.error = 'my errror' + this.project_id = ObjectId().toString() + this.stubbedError = new Errors.NotFoundError('Error in S3 request') + return (this.DocArchiveManager = SandboxedModule.require(modulePath, { + requires: this.requires, + globals: this.globals + })) + }) - this.requires = { - "settings-sharelatex": this.settings, - "./MongoManager": this.MongoManager, - "request": this.request, - "./RangeManager": (this.RangeManager = {}), - "logger-sharelatex": { - log() {}, - err() {} - } - }; - this.globals = - {JSON}; + describe('archiveDoc', function() { + it('should use correct options', function(done) { + this.request.put = sinon + .stub() + .callsArgWith(1, null, { statusCode: 200, headers: { etag: '' } }) + return this.DocArchiveManager.archiveDoc( + this.project_id, + this.mongoDocs[0], + err => { + const opts = this.request.put.args[0][0] + assert.deepEqual(opts.aws, { + key: this.settings.docstore.s3.key, + secret: this.settings.docstore.s3.secret, + bucket: this.settings.docstore.s3.bucket + }) + opts.body.should.equal( + JSON.stringify({ + lines: this.mongoDocs[0].lines, + ranges: this.mongoDocs[0].ranges, + schema_v: 1 + }) + ) + opts.timeout.should.equal(30 * 1000) + opts.uri.should.equal( + `https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}` + ) + return done() + } + ) + }) - this.error = "my errror"; - this.project_id = ObjectId().toString(); - this.stubbedError = new Errors.NotFoundError("Error in S3 request"); - return this.DocArchiveManager = SandboxedModule.require(modulePath, {requires: this.requires, globals: this.globals}); - }); + it('should return no md5 error', function(done) { + const data = JSON.stringify({ + lines: this.mongoDocs[0].lines, + ranges: this.mongoDocs[0].ranges, + schema_v: 1 + }) + this.md5 = crypto + .createHash('md5') + .update(data) + .digest('hex') + this.request.put = sinon + .stub() + .callsArgWith(1, null, { statusCode: 200, headers: { etag: this.md5 } }) + return this.DocArchiveManager.archiveDoc( + this.project_id, + this.mongoDocs[0], + err => { + should.not.exist(err) + return done() + } + ) + }) - describe("archiveDoc", function() { + return it('should return the error', function(done) { + this.request.put = sinon.stub().callsArgWith(1, this.stubbedError, { + statusCode: 400, + headers: { etag: '' } + }) + return this.DocArchiveManager.archiveDoc( + this.project_id, + this.mongoDocs[0], + err => { + should.exist(err) + return done() + } + ) + }) + }) - it("should use correct options", function(done){ - this.request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:""}}); - return this.DocArchiveManager.archiveDoc(this.project_id, this.mongoDocs[0], err=> { - const opts = this.request.put.args[0][0]; - assert.deepEqual(opts.aws, {key:this.settings.docstore.s3.key, secret:this.settings.docstore.s3.secret, bucket:this.settings.docstore.s3.bucket}); - opts.body.should.equal(JSON.stringify({ - lines: this.mongoDocs[0].lines, - ranges: this.mongoDocs[0].ranges, - schema_v: 1 - }) - ); - opts.timeout.should.equal((30*1000)); - opts.uri.should.equal(`https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}`); - return done(); - }); - }); + describe('unarchiveDoc', function() { + it('should use correct options', function(done) { + this.request.get = sinon + .stub() + .callsArgWith(1, null, { statusCode: 200 }, this.mongoDocs[0].lines) + this.request.del = sinon + .stub() + .callsArgWith(1, null, { statusCode: 204 }, {}) + return this.DocArchiveManager.unarchiveDoc( + this.project_id, + this.mongoDocs[0]._id, + err => { + const opts = this.request.get.args[0][0] + assert.deepEqual(opts.aws, { + key: this.settings.docstore.s3.key, + secret: this.settings.docstore.s3.secret, + bucket: this.settings.docstore.s3.bucket + }) + opts.json.should.equal(true) + opts.timeout.should.equal(30 * 1000) + opts.uri.should.equal( + `https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}` + ) + return done() + } + ) + }) - it("should return no md5 error", function(done){ - const data = JSON.stringify({ - lines: this.mongoDocs[0].lines, - ranges: this.mongoDocs[0].ranges, - schema_v: 1 - }); - this.md5 = crypto.createHash("md5").update(data).digest("hex"); - this.request.put = sinon.stub().callsArgWith(1, null, {statusCode:200,headers:{etag:this.md5}}); - return this.DocArchiveManager.archiveDoc(this.project_id, this.mongoDocs[0], err=> { - should.not.exist(err); - return done(); - }); - }); + it('should return the error', function(done) { + this.request.get = sinon.stub().callsArgWith(1, this.stubbedError, {}, {}) + return this.DocArchiveManager.unarchiveDoc( + this.project_id, + this.mongoDocs[0], + err => { + should.exist(err) + return done() + } + ) + }) - return it("should return the error", function(done){ - this.request.put = sinon.stub().callsArgWith(1, this.stubbedError, {statusCode:400,headers:{etag:""}}); - return this.DocArchiveManager.archiveDoc(this.project_id, this.mongoDocs[0], err=> { - should.exist(err); - return done(); - }); - }); - }); + return it('should error if the doc lines are a string not an array', function(done) { + this.request.get = sinon + .stub() + .callsArgWith(1, null, { statusCode: 200 }, 'this is a string') + this.request.del = sinon.stub() + return this.DocArchiveManager.unarchiveDoc( + this.project_id, + this.mongoDocs[0], + err => { + should.exist(err) + this.request.del.called.should.equal(false) + return done() + } + ) + }) + }) - describe("unarchiveDoc", function() { + describe('archiveAllDocs', function() { + it('should archive all project docs which are not in s3', function(done) { + this.MongoManager.getProjectsDocs = sinon + .stub() + .callsArgWith(3, null, this.mongoDocs) + this.DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) - it("should use correct options", function(done){ - this.request.get = sinon.stub().callsArgWith(1, null, {statusCode:200}, this.mongoDocs[0].lines); - this.request.del = sinon.stub().callsArgWith(1, null, {statusCode:204}, {}); - return this.DocArchiveManager.unarchiveDoc(this.project_id, this.mongoDocs[0]._id, err=> { - const opts = this.request.get.args[0][0]; - assert.deepEqual(opts.aws, {key:this.settings.docstore.s3.key, secret:this.settings.docstore.s3.secret, bucket:this.settings.docstore.s3.bucket}); - opts.json.should.equal(true); - opts.timeout.should.equal((30*1000)); - opts.uri.should.equal(`https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}`); - return done(); - }); - }); + return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + this.DocArchiveManager.archiveDoc + .calledWith(this.project_id, this.mongoDocs[0]) + .should.equal(true) + this.DocArchiveManager.archiveDoc + .calledWith(this.project_id, this.mongoDocs[1]) + .should.equal(true) + this.DocArchiveManager.archiveDoc + .calledWith(this.project_id, this.mongoDocs[4]) + .should.equal(true) - it("should return the error", function(done){ - this.request.get = sinon.stub().callsArgWith(1, this.stubbedError, {}, {}); - return this.DocArchiveManager.unarchiveDoc(this.project_id, this.mongoDocs[0], err=> { - should.exist(err); - return done(); - }); - }); + this.DocArchiveManager.archiveDoc + .calledWith(this.project_id, this.mongoDocs[2]) + .should.equal(false) + this.DocArchiveManager.archiveDoc + .calledWith(this.project_id, this.mongoDocs[3]) + .should.equal(false) - return it("should error if the doc lines are a string not an array", function(done){ - this.request.get = sinon.stub().callsArgWith(1, null, {statusCode:200}, "this is a string"); - this.request.del = sinon.stub(); - return this.DocArchiveManager.unarchiveDoc(this.project_id, this.mongoDocs[0], err=> { - should.exist(err); - this.request.del.called.should.equal(false); - return done(); - }); - }); - }); + should.not.exist(err) + return done() + }) + }) - describe("archiveAllDocs", function() { + it('should return error if have no docs', function(done) { + this.MongoManager.getProjectsDocs = sinon + .stub() + .callsArgWith(3, null, null) - it("should archive all project docs which are not in s3", function(done){ - this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.mongoDocs); - this.DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null); + return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + should.exist(err) + return done() + }) + }) - return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { - this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[0]).should.equal(true); - this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[1]).should.equal(true); - this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[4]).should.equal(true); + it('should return the error', function(done) { + this.MongoManager.getProjectsDocs = sinon + .stub() + .callsArgWith(3, this.error, null) - this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[2]).should.equal(false); - this.DocArchiveManager.archiveDoc.calledWith(this.project_id, this.mongoDocs[3]).should.equal(false); - - should.not.exist(err); - return done(); - }); - }); + return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + err.should.equal(this.error) + return done() + }) + }) - it("should return error if have no docs", function(done){ - this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null); + return describe('when most have been already put in s3', function() { + beforeEach(function() { + let numberOfDocs = 10 * 1000 + this.mongoDocs = [] + while (--numberOfDocs !== 0) { + this.mongoDocs.push({ inS3: true, _id: ObjectId() }) + } - return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { - should.exist(err); - return done(); - }); - }); + this.MongoManager.getProjectsDocs = sinon + .stub() + .callsArgWith(3, null, this.mongoDocs) + return (this.DocArchiveManager.archiveDoc = sinon + .stub() + .callsArgWith(2, null)) + }) - it("should return the error", function(done){ - this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, this.error, null); + return it('should not throw and error', function(done) { + return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + should.not.exist(err) + return done() + }) + }) + }) + }) - return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { - err.should.equal(this.error); - return done(); - }); - }); + describe('unArchiveAllDocs', function() { + it('should unarchive all inS3 docs', function(done) { + this.MongoManager.getArchivedProjectDocs = sinon + .stub() + .callsArgWith(1, null, this.archivedDocs) + this.DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null) + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err => { + for (const doc of Array.from(this.archivedDocs)) { + this.DocArchiveManager.unarchiveDoc + .calledWith(this.project_id, doc._id) + .should.equal(true) + } + should.not.exist(err) + return done() + }) + }) - return describe("when most have been already put in s3", function() { + it('should return error if have no docs', function(done) { + this.MongoManager.getArchivedProjectDocs = sinon + .stub() + .callsArgWith(1, null, null) + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err => { + should.exist(err) + return done() + }) + }) - beforeEach(function() { - let numberOfDocs = 10 * 1000; - this.mongoDocs = []; - while (--numberOfDocs !== 0) { - this.mongoDocs.push({inS3:true, _id: ObjectId()}); - } + return it('should return the error', function(done) { + this.MongoManager.getArchivedProjectDocs = sinon + .stub() + .callsArgWith(1, this.error, null) + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err => { + err.should.equal(this.error) + return done() + }) + }) + }) - this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.mongoDocs); - return this.DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null); - }); + describe('destroyAllDocs', function() { + beforeEach(function() { + this.request.del = sinon + .stub() + .callsArgWith(1, null, { statusCode: 204 }, {}) + this.MongoManager.getProjectsDocs = sinon + .stub() + .callsArgWith(3, null, this.mixedDocs) + this.MongoManager.findDoc = sinon.stub().callsArgWith(3, null, null) + this.MongoManager.destroyDoc = sinon.stub().yields() + return Array.from(this.mixedDocs).map(doc => + this.MongoManager.findDoc + .withArgs(this.project_id, doc._id) + .callsArgWith(3, null, doc) + ) + }) - return it("should not throw and error", function(done){ - return this.DocArchiveManager.archiveAllDocs(this.project_id, err=> { - should.not.exist(err); - return done(); - }); - }); - }); - }); + it('should destroy all the docs', function(done) { + this.DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null) + return this.DocArchiveManager.destroyAllDocs(this.project_id, err => { + for (const doc of Array.from(this.mixedDocs)) { + this.DocArchiveManager.destroyDoc + .calledWith(this.project_id, doc._id) + .should.equal(true) + } + should.not.exist(err) + return done() + }) + }) + it('should only the s3 docs from s3', function(done) { + const docOpts = doc => { + return JSON.parse( + JSON.stringify({ + aws: { + key: this.settings.docstore.s3.key, + secret: this.settings.docstore.s3.secret, + bucket: this.settings.docstore.s3.bucket + }, + json: true, + timeout: 30 * 1000, + uri: `https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${doc._id}` + }) + ) + } - describe("unArchiveAllDocs", function() { + return this.DocArchiveManager.destroyAllDocs(this.project_id, err => { + let doc + expect(err).not.to.exist - it("should unarchive all inS3 docs", function(done){ - this.MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, this.archivedDocs); - this.DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null); - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err=> { - for (const doc of Array.from(this.archivedDocs)) { - this.DocArchiveManager.unarchiveDoc.calledWith(this.project_id, doc._id).should.equal(true); - } - should.not.exist(err); - return done(); - }); - }); + for (doc of Array.from(this.archivedDocs)) { + sinon.assert.calledWith(this.request.del, docOpts(doc)) + } + for (doc of Array.from(this.unarchivedDocs)) { + expect(this.request.del.calledWith(docOpts(doc))).to.equal(false) + } // no notCalledWith - it("should return error if have no docs", function(done){ - this.MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, null, null); - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err=> { - should.exist(err); - return done(); - }); - }); + return done() + }) + }) - return it("should return the error", function(done){ - this.MongoManager.getArchivedProjectDocs = sinon.stub().callsArgWith(1, this.error, null); - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err=> { - err.should.equal(this.error); - return done(); - }); - }); - }); + return it('should remove the docs from mongo', function(done) { + this.DocArchiveManager.destroyAllDocs(this.project_id, err => { + return expect(err).not.to.exist + }) - describe("destroyAllDocs", function() { - beforeEach(function() { - this.request.del = sinon.stub().callsArgWith(1, null, {statusCode:204}, {}); - this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.mixedDocs); - this.MongoManager.findDoc = sinon.stub().callsArgWith(3, null, null); - this.MongoManager.destroyDoc = sinon.stub().yields(); - return Array.from(this.mixedDocs).map((doc) => - this.MongoManager.findDoc.withArgs(this.project_id, doc._id).callsArgWith(3, null, doc)); - }); + for (const doc of Array.from(this.mixedDocs)) { + sinon.assert.calledWith(this.MongoManager.destroyDoc, doc._id) + } - it("should destroy all the docs", function(done){ - this.DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null); - return this.DocArchiveManager.destroyAllDocs(this.project_id, err=> { - for (const doc of Array.from(this.mixedDocs)) { - this.DocArchiveManager.destroyDoc.calledWith(this.project_id, doc._id).should.equal(true); - } - should.not.exist(err); - return done(); - }); - }); + return done() + }) + }) - it("should only the s3 docs from s3", function(done){ - const docOpts = doc => { - return JSON.parse(JSON.stringify({ - aws: {key:this.settings.docstore.s3.key, secret:this.settings.docstore.s3.secret, bucket:this.settings.docstore.s3.bucket}, - json: true, - timeout: 30 * 1000, - uri:`https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${doc._id}` - })); - }; + describe('_s3DocToMongoDoc', function() { + describe('with the old schema', function() { + return it('should return the docs lines', function(done) { + return this.DocArchiveManager._s3DocToMongoDoc( + ['doc', 'lines'], + (error, doc) => { + expect(doc).to.deep.equal({ + lines: ['doc', 'lines'] + }) + return done() + } + ) + }) + }) - return this.DocArchiveManager.destroyAllDocs(this.project_id, err=> { - let doc; - expect(err).not.to.exist; + describe('with the new schema', function() { + it('should return the doc lines and ranges', function(done) { + this.RangeManager.jsonRangesToMongo = sinon + .stub() + .returns({ mongo: 'ranges' }) + return this.DocArchiveManager._s3DocToMongoDoc( + { + lines: ['doc', 'lines'], + ranges: { json: 'ranges' }, + schema_v: 1 + }, + (error, doc) => { + expect(doc).to.deep.equal({ + lines: ['doc', 'lines'], + ranges: { mongo: 'ranges' } + }) + return done() + } + ) + }) - for (doc of Array.from(this.archivedDocs)) { - sinon.assert.calledWith(this.request.del, docOpts(doc)); - } - for (doc of Array.from(this.unarchivedDocs)) { - expect(this.request.del.calledWith(docOpts(doc))).to.equal(false); - } // no notCalledWith + return it('should return just the doc lines when there are no ranges', function(done) { + return this.DocArchiveManager._s3DocToMongoDoc( + { + lines: ['doc', 'lines'], + schema_v: 1 + }, + (error, doc) => { + expect(doc).to.deep.equal({ + lines: ['doc', 'lines'] + }) + return done() + } + ) + }) + }) - return done(); - }); - }); + return describe('with an unrecognised schema', function() { + return it('should return an error', function(done) { + return this.DocArchiveManager._s3DocToMongoDoc( + { + schema_v: 2 + }, + (error, doc) => { + expect(error).to.exist + return done() + } + ) + }) + }) + }) - return it("should remove the docs from mongo", function(done){ - this.DocArchiveManager.destroyAllDocs(this.project_id, err=> { - return expect(err).not.to.exist; - }); + return describe('_mongoDocToS3Doc', function() { + describe('with a valid doc', function() { + return it('should return the json version', function(done) { + let doc + return this.DocArchiveManager._mongoDocToS3Doc( + (doc = { + lines: ['doc', 'lines'], + ranges: { mock: 'ranges' } + }), + (err, s3_doc) => { + expect(s3_doc).to.equal( + JSON.stringify({ + lines: ['doc', 'lines'], + ranges: { mock: 'ranges' }, + schema_v: 1 + }) + ) + return done() + } + ) + }) + }) - for (const doc of Array.from(this.mixedDocs)) { - sinon.assert.calledWith(this.MongoManager.destroyDoc, doc._id); - } + describe('with null bytes in the result', function() { + beforeEach(function() { + this._stringify = JSON.stringify + return (JSON.stringify = sinon.stub().returns('{"bad": "\u0000"}')) + }) - return done(); - }); - }); - - describe("_s3DocToMongoDoc", function() { - describe("with the old schema", function() { return it("should return the docs lines", function(done) { - return this.DocArchiveManager._s3DocToMongoDoc(["doc", "lines"], (error, doc) => { - expect(doc).to.deep.equal({ - lines: ["doc", "lines"] - }); - return done(); - }); - }); }); - - describe("with the new schema", function() { - it("should return the doc lines and ranges", function(done) { - this.RangeManager.jsonRangesToMongo = sinon.stub().returns({"mongo": "ranges"}); - return this.DocArchiveManager._s3DocToMongoDoc({ - lines: ["doc", "lines"], - ranges: {"json": "ranges"}, - schema_v: 1 - }, (error, doc) => { - expect(doc).to.deep.equal({ - lines: ["doc", "lines"], - ranges: {"mongo": "ranges"} - }); - return done(); - }); - }); - - return it("should return just the doc lines when there are no ranges", function(done) { - return this.DocArchiveManager._s3DocToMongoDoc({ - lines: ["doc", "lines"], - schema_v: 1 - }, (error, doc) => { - expect(doc).to.deep.equal({ - lines: ["doc", "lines"] - }); - return done(); - }); - }); - }); - - return describe("with an unrecognised schema", function() { return it("should return an error", function(done) { - return this.DocArchiveManager._s3DocToMongoDoc({ - schema_v: 2 - }, (error, doc) => { - expect(error).to.exist; - return done(); - }); - }); }); - }); - - return describe("_mongoDocToS3Doc", function() { - describe("with a valid doc", function() { return it("should return the json version", function(done) { - let doc; - return this.DocArchiveManager._mongoDocToS3Doc((doc = { - lines: ["doc", "lines"], - ranges: { "mock": "ranges" } - }), (err, s3_doc) => { - expect(s3_doc).to.equal(JSON.stringify({ - lines: ["doc", "lines"], - ranges: { "mock": "ranges" }, - schema_v: 1 - }) - ); - return done(); - }); - }); }); - - describe("with null bytes in the result", function() { - beforeEach(function() { - this._stringify = JSON.stringify; - return JSON.stringify = sinon.stub().returns('{"bad": "\u0000"}'); - }); - - afterEach(function() { - return JSON.stringify = this._stringify; - }); - - return it("should return an error", function(done) { - return this.DocArchiveManager._mongoDocToS3Doc({ - lines: ["doc", "lines"], - ranges: { "mock": "ranges" } - }, (err, s3_doc) => { - expect(err).to.exist; - return done(); - }); - }); - }); - - return describe("without doc lines", function() { return it("should return an error", function(done) { - return this.DocArchiveManager._mongoDocToS3Doc({}, (err, s3_doc) => { - expect(err).to.exist; - return done(); - }); - }); }); - }); -}); - - + afterEach(function() { + return (JSON.stringify = this._stringify) + }) + + return it('should return an error', function(done) { + return this.DocArchiveManager._mongoDocToS3Doc( + { + lines: ['doc', 'lines'], + ranges: { mock: 'ranges' } + }, + (err, s3_doc) => { + expect(err).to.exist + return done() + } + ) + }) + }) + + return describe('without doc lines', function() { + return it('should return an error', function(done) { + return this.DocArchiveManager._mongoDocToS3Doc({}, (err, s3_doc) => { + expect(err).to.exist + return done() + }) + }) + }) + }) +}) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 4130818601..9508e74f2e 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -12,535 +12,796 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const SandboxedModule = require('sandboxed-module'); -const sinon = require('sinon'); -const chai = require('chai'); -const { - assert -} = require("chai"); -chai.should(); -const { - expect -} = chai; -const modulePath = require('path').join(__dirname, '../../../app/js/DocManager'); -const { - ObjectId -} = require("mongojs"); -const Errors = require("../../../app/js/Errors"); - -describe("DocManager", function() { - beforeEach(function() { - this.DocManager = SandboxedModule.require(modulePath, { requires: { - "./MongoManager": (this.MongoManager = {}), - "./DocArchiveManager": (this.DocArchiveManager = {}), - "./RangeManager": (this.RangeManager = { - jsonRangesToMongo(r) { return r; }, - shouldUpdateRanges: sinon.stub().returns(false) - }), - "logger-sharelatex": (this.logger = { - log: sinon.stub(), - warn() {}, - err() {} - }) - } - } - ); - this.doc_id = ObjectId().toString(); - this.project_id = ObjectId().toString(); - this.another_project_id = ObjectId().toString(); - this.callback = sinon.stub(); - return this.stubbedError = new Error("blew up"); - }); - - - describe("checkDocExists", function() { - beforeEach(function() { - return this.DocManager._getDoc = sinon.stub(); - }); - - it("should call get doc with a quick filter", function(done){ - this.DocManager._getDoc.callsArgWith(3, null, {_id:this.doc_id}); - return this.DocManager.checkDocExists(this.project_id, this.doc_id, (err, exist)=> { - exist.should.equal(true); - this.DocManager._getDoc.calledWith(this.project_id, this.doc_id, {_id:1, inS3:true}).should.equal(true); - return done(); - }); - }); - - it("should return false when doc is not there", function(done){ - this.DocManager._getDoc.callsArgWith(3, null); - return this.DocManager.checkDocExists(this.project_id, this.doc_id, (err, exist)=> { - exist.should.equal(false); - return done(); - }); - }); - - return it("should return error when get doc errors", function(done){ - this.DocManager._getDoc.callsArgWith(3, "error"); - return this.DocManager.checkDocExists(this.project_id, this.doc_id, (err, exist)=> { - err.should.equal("error"); - return done(); - }); - }); - }); - - describe("getFullDoc", function() { - beforeEach(function() { - this.DocManager._getDoc = sinon.stub(); - return this.doc = { - _id: this.doc_id, - lines:["2134"] - };}); - - it("should call get doc with a quick filter", function(done){ - this.DocManager._getDoc.callsArgWith(3, null, this.doc); - return this.DocManager.getFullDoc(this.project_id, this.doc_id, (err, doc)=> { - doc.should.equal(this.doc); - this.DocManager._getDoc.calledWith(this.project_id, this.doc_id, {lines: true, rev: true, deleted: true, version: true, ranges: true, inS3:true}).should.equal(true); - return done(); - }); - }); - - return it("should return error when get doc errors", function(done){ - this.DocManager._getDoc.callsArgWith(3, "error"); - return this.DocManager.getFullDoc(this.project_id, this.doc_id, (err, exist)=> { - err.should.equal("error"); - return done(); - }); - }); - }); - - describe("getRawDoc", function() { - - beforeEach(function() { - this.DocManager._getDoc = sinon.stub(); - return this.doc = - {lines:["2134"]};}); - - it("should call get doc with a quick filter", function(done){ - this.DocManager._getDoc.callsArgWith(3, null, this.doc); - return this.DocManager.getDocLines(this.project_id, this.doc_id, (err, doc)=> { - doc.should.equal(this.doc); - this.DocManager._getDoc.calledWith(this.project_id, this.doc_id, {lines: true, inS3:true}).should.equal(true); - return done(); - }); - }); - - return it("should return error when get doc errors", function(done){ - this.DocManager._getDoc.callsArgWith(3, "error"); - return this.DocManager.getDocLines(this.project_id, this.doc_id, (err, exist)=> { - err.should.equal("error"); - return done(); - }); - }); - }); - - - - describe("getDoc", function() { - beforeEach(function() { - this.project = { name: "mock-project" }; - this.doc = { _id: this.doc_id, project_id: this.project_id, lines: ["mock-lines"] }; - this.version = 42; - this.MongoManager.findDoc = sinon.stub(); - return this.MongoManager.getDocVersion = sinon.stub().yields(null, this.version); - }); - - describe("when using a filter", function() { - beforeEach(function() { - return this.MongoManager.findDoc.yields(null, this.doc); - }); - - it("should error if inS3 is not set to true", function(done){ - return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: false}, (err) => { - expect(err).to.exist; - return done(); - }); - }); - - it("should always get inS3 even when no filter is passed", function(done){ - return this.DocManager._getDoc(this.project_id, this.doc_id, undefined, err=> { - this.MongoManager.findDoc.called.should.equal(false); - expect(err).to.exist; - return done(); - }); - }); - - return it("should not error if inS3 is set to true", function(done){ - return this.DocManager._getDoc(this.project_id, this.doc_id, {inS3: true}, (err) => { - expect(err).to.not.exist; - return done(); - }); - }); - }); - - describe("when the doc is in the doc collection", function() { - beforeEach(function() { - this.MongoManager.findDoc.yields(null, this.doc); - return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); - }); - - it("should get the doc from the doc collection", function() { - return this.MongoManager.findDoc - .calledWith(this.project_id, this.doc_id) - .should.equal(true); - }); - - it("should get the doc version from the docOps collection", function() { - return this.MongoManager.getDocVersion - .calledWith(this.doc_id) - .should.equal(true); - }); - - return it("should return the callback with the doc with the version", function() { - this.callback.called.should.equal(true); - const doc = this.callback.args[0][1]; - doc.lines.should.equal(this.doc.lines); - return doc.version.should.equal(this.version); - }); - }); - - describe("without the version filter", function() { - beforeEach(function() { - this.MongoManager.findDoc.yields(null, this.doc); - return this.DocManager._getDoc(this.project_id, this.doc_id, {version: false, inS3:true}, this.callback); - }); - - return it("should not get the doc version from the docOps collection", function() { - return this.MongoManager.getDocVersion.called.should.equal(false); - }); - }); - - describe("when MongoManager.findDoc errors", function() { - beforeEach(function() { - this.MongoManager.findDoc.yields(this.stubbedError); - return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); - }); - - return it("should return the error", function() { - return this.callback.calledWith(this.stubbedError).should.equal(true); - }); - }); - - describe("when the doc is archived", function() { - beforeEach(function() { - this.doc = { _id: this.doc_id, project_id: this.project_id, lines: ["mock-lines"], inS3: true }; - this.MongoManager.findDoc.yields(null, this.doc); - this.DocArchiveManager.unarchiveDoc = (project_id, doc_id, callback) => { - this.doc.inS3 = false; - return callback(); - }; - sinon.spy(this.DocArchiveManager, "unarchiveDoc"); - return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); - }); - - it("should call the DocArchive to unarchive the doc", function() { - return this.DocArchiveManager.unarchiveDoc.calledWith(this.project_id, this.doc_id).should.equal(true); - }); - - it("should look up the doc twice", function() { - return this.MongoManager.findDoc.calledTwice.should.equal(true); - }); - - return it("should return the doc", function() { - return this.callback.calledWith(null, this.doc).should.equal(true); - }); - }); - - return describe("when the doc does not exist in the docs collection", function() { - beforeEach(function() { - this.MongoManager.findDoc = sinon.stub().yields(null, null); - return this.DocManager._getDoc(this.project_id, this.doc_id, {version: true, inS3:true}, this.callback); - }); - - return it("should return a NotFoundError", function() { - return this.callback - .calledWith(sinon.match.has('message', `No such doc: ${this.doc_id} in project ${this.project_id}`)) - .should.equal(true); - }); - }); - }); - - describe("getAllNonDeletedDocs", function() { - describe("when the project exists", function() { - beforeEach(function() { - this.docs = [{ _id: this.doc_id, project_id: this.project_id, lines: ["mock-lines"] }]; - this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, this.docs); - this.DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null, this.docs); - this.filter = { lines: true }; - return this.DocManager.getAllNonDeletedDocs(this.project_id, this.filter, this.callback); - }); - - it("should get the project from the database", function() { - return this.MongoManager.getProjectsDocs - .calledWith(this.project_id, {include_deleted: false}, this.filter) - .should.equal(true); - }); - - return it("should return the docs", function() { - return this.callback.calledWith(null, this.docs).should.equal(true); - }); - }); - - return describe("when there are no docs for the project", function() { - beforeEach(function() { - this.MongoManager.getProjectsDocs = sinon.stub().callsArgWith(3, null, null); - this.DocArchiveManager.unArchiveAllDocs = sinon.stub().callsArgWith(1, null); - return this.DocManager.getAllNonDeletedDocs(this.project_id, this.filter, this.callback); - }); - - return it("should return a NotFoundError", function() { - return this.callback - .calledWith(sinon.match.has('message', `No docs for project ${this.project_id}`)) - .should.equal(true); - }); - }); - }); - - describe("deleteDoc", function() { - describe("when the doc exists", function() { - beforeEach(function() { - this.lines = ["mock", "doc", "lines"]; - this.rev = 77; - this.DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, true); - this.MongoManager.markDocAsDeleted = sinon.stub().callsArg(2); - return this.DocManager.deleteDoc(this.project_id, this.doc_id, this.callback); - }); - - it("should get the doc", function() { - return this.DocManager.checkDocExists - .calledWith(this.project_id, this.doc_id) - .should.equal(true); - }); - - it("should mark doc as deleted", function() { - return this.MongoManager.markDocAsDeleted - .calledWith(this.project_id, this.doc_id) - .should.equal(true); - }); - - return it("should return the callback", function() { - return this.callback.called.should.equal(true); - }); - }); - - return describe("when the doc does not exist", function() { - beforeEach(function() { - this.DocManager.checkDocExists = sinon.stub().callsArgWith(2, null, false); - return this.DocManager.deleteDoc(this.project_id, this.doc_id, this.callback); - }); - - return it("should return a NotFoundError", function() { - return this.callback - .calledWith(sinon.match.has('message', `No such project/doc to delete: ${this.project_id}/${this.doc_id}`)) - .should.equal(true); - }); - }); - }); - - return describe("updateDoc", function() { - beforeEach(function() { - this.oldDocLines = ["old", "doc", "lines"]; - this.newDocLines = ["new", "doc", "lines"]; - this.originalRanges = { - changes: [{ - id: ObjectId().toString(), - op: { i: "foo", p: 3 }, - meta: { - user_id: ObjectId().toString(), - ts: new Date().toString() - } - }] - }; - this.newRanges = { - changes: [{ - id: ObjectId().toString(), - op: { i: "bar", p: 6 }, - meta: { - user_id: ObjectId().toString(), - ts: new Date().toString() - } - }] - }; - this.version = 42; - this.doc = { _id: this.doc_id, project_id: this.project_id, lines: this.oldDocLines, rev: (this.rev = 5), version: this.version, ranges: this.originalRanges }; - - this.MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3); - this.MongoManager.setDocVersion = sinon.stub().yields(); - return this.DocManager._getDoc = sinon.stub(); - }); - - describe("when only the doc lines have changed", function() { - beforeEach(function() { - this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, this.originalRanges, this.callback); - }); - - it("should get the existing doc", function() { - return this.DocManager._getDoc - .calledWith(this.project_id, this.doc_id, {version: true, rev: true, lines: true, version: true, ranges: true, inS3:true}) - .should.equal(true); - }); - - it("should upsert the document to the doc collection", function() { - return this.MongoManager.upsertIntoDocCollection - .calledWith(this.project_id, this.doc_id, {lines: this.newDocLines}) - .should.equal(true); - }); - - it("should not update the version", function() { - return this.MongoManager.setDocVersion.called.should.equal(false); - }); - - return it("should return the callback with the new rev", function() { - return this.callback.calledWith(null, true, this.rev + 1).should.equal(true); - }); - }); - - describe("when the doc ranges have changed", function() { - beforeEach(function() { - this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); - this.RangeManager.shouldUpdateRanges.returns(true); - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines, this.version, this.newRanges, this.callback); - }); - - it("should upsert the ranges", function() { - return this.MongoManager.upsertIntoDocCollection - .calledWith(this.project_id, this.doc_id, {ranges: this.newRanges}) - .should.equal(true); - }); - - it("should not update the version", function() { - return this.MongoManager.setDocVersion.called.should.equal(false); - }); - - return it("should return the callback with the new rev", function() { - return this.callback.calledWith(null, true, this.rev + 1).should.equal(true); - }); - }); - - describe("when only the version has changed", function() { - beforeEach(function() { - this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines, this.version + 1, this.originalRanges, this.callback); - }); - - it("should not change the lines or ranges", function() { - return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); - }); - - it("should update the version", function() { - return this.MongoManager.setDocVersion - .calledWith(this.doc_id, this.version + 1) - .should.equal(true); - }); - - return it("should return the callback with the old rev", function() { - return this.callback.calledWith(null, true, this.rev).should.equal(true); - }); - }); - - describe("when the doc has not changed at all", function() { - beforeEach(function() { - this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines, this.version, this.originalRanges, this.callback); - }); - - it("should not update the ranges or lines", function() { - return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); - }); - - it("should not update the version", function() { - return this.MongoManager.setDocVersion.called.should.equal(false); - }); - - return it("should return the callback with the old rev and modified == false", function() { - return this.callback.calledWith(null, false, this.rev).should.equal(true); - }); - }); - - describe("when the version is null", function() { - beforeEach(function() { - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, null, this.originalRanges, this.callback); - }); - - return it("should return an error", function() { - return this.callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal(true); - }); - }); - - describe("when the lines are null", function() { - beforeEach(function() { - return this.DocManager.updateDoc(this.project_id, this.doc_id, null, this.version, this.originalRanges, this.callback); - }); - - return it("should return an error", function() { - return this.callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal(true); - }); - }); - - describe("when the ranges are null", function() { - beforeEach(function() { - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, null, this.callback); - }); - - return it("should return an error", function() { - return this.callback.calledWith(sinon.match.has('message', "no lines, version or ranges provided")).should.equal(true); - }); - }); - - describe("when there is a generic error getting the doc", function() { - beforeEach(function() { - this.error = new Error("doc could not be found"); - this.DocManager._getDoc = sinon.stub().callsArgWith(3, this.error, null, null); - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, this.originalRanges, this.callback); - }); - - it("should not upsert the document to the doc collection", function() { - return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); - }); - - return it("should return the callback with the error", function() { - return this.callback.calledWith(this.error).should.equal(true); - }); - }); - - describe("when the doc lines have not changed", function() { - beforeEach(function() { - this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc); - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.oldDocLines.slice(), this.version, this.originalRanges, this.callback); - }); - - it("should not update the doc", function() { - return this.MongoManager.upsertIntoDocCollection.called.should.equal(false); - }); - - return it("should return the callback with the existing rev", function() { - return this.callback.calledWith(null, false, this.rev).should.equal(true); - }); - }); - - return describe("when the doc does not exist", function() { - beforeEach(function() { - this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, null, null); - return this.DocManager.updateDoc(this.project_id, this.doc_id, this.newDocLines, this.version, this.originalRanges, this.callback); - }); - - it("should upsert the document to the doc collection", function() { - return this.MongoManager.upsertIntoDocCollection - .calledWith(this.project_id, this.doc_id, {lines: this.newDocLines, ranges: this.originalRanges}) - .should.equal(true); - }); - - it("should set the version", function() { - return this.MongoManager.setDocVersion - .calledWith(this.doc_id, this.version) - .should.equal(true); - }); - - return it("should return the callback with the new rev", function() { - return this.callback.calledWith(null, true, 1).should.equal(true); - }); - }); - }); -}); +const SandboxedModule = require('sandboxed-module') +const sinon = require('sinon') +const chai = require('chai') +const { assert } = require('chai') +chai.should() +const { expect } = chai +const modulePath = require('path').join(__dirname, '../../../app/js/DocManager') +const { ObjectId } = require('mongojs') +const Errors = require('../../../app/js/Errors') + +describe('DocManager', function() { + beforeEach(function() { + this.DocManager = SandboxedModule.require(modulePath, { + requires: { + './MongoManager': (this.MongoManager = {}), + './DocArchiveManager': (this.DocArchiveManager = {}), + './RangeManager': (this.RangeManager = { + jsonRangesToMongo(r) { + return r + }, + shouldUpdateRanges: sinon.stub().returns(false) + }), + 'logger-sharelatex': (this.logger = { + log: sinon.stub(), + warn() {}, + err() {} + }) + } + }) + this.doc_id = ObjectId().toString() + this.project_id = ObjectId().toString() + this.another_project_id = ObjectId().toString() + this.callback = sinon.stub() + return (this.stubbedError = new Error('blew up')) + }) + + describe('checkDocExists', function() { + beforeEach(function() { + return (this.DocManager._getDoc = sinon.stub()) + }) + + it('should call get doc with a quick filter', function(done) { + this.DocManager._getDoc.callsArgWith(3, null, { _id: this.doc_id }) + return this.DocManager.checkDocExists( + this.project_id, + this.doc_id, + (err, exist) => { + exist.should.equal(true) + this.DocManager._getDoc + .calledWith(this.project_id, this.doc_id, { _id: 1, inS3: true }) + .should.equal(true) + return done() + } + ) + }) + + it('should return false when doc is not there', function(done) { + this.DocManager._getDoc.callsArgWith(3, null) + return this.DocManager.checkDocExists( + this.project_id, + this.doc_id, + (err, exist) => { + exist.should.equal(false) + return done() + } + ) + }) + + return it('should return error when get doc errors', function(done) { + this.DocManager._getDoc.callsArgWith(3, 'error') + return this.DocManager.checkDocExists( + this.project_id, + this.doc_id, + (err, exist) => { + err.should.equal('error') + return done() + } + ) + }) + }) + + describe('getFullDoc', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub() + return (this.doc = { + _id: this.doc_id, + lines: ['2134'] + }) + }) + + it('should call get doc with a quick filter', function(done) { + this.DocManager._getDoc.callsArgWith(3, null, this.doc) + return this.DocManager.getFullDoc( + this.project_id, + this.doc_id, + (err, doc) => { + doc.should.equal(this.doc) + this.DocManager._getDoc + .calledWith(this.project_id, this.doc_id, { + lines: true, + rev: true, + deleted: true, + version: true, + ranges: true, + inS3: true + }) + .should.equal(true) + return done() + } + ) + }) + + return it('should return error when get doc errors', function(done) { + this.DocManager._getDoc.callsArgWith(3, 'error') + return this.DocManager.getFullDoc( + this.project_id, + this.doc_id, + (err, exist) => { + err.should.equal('error') + return done() + } + ) + }) + }) + + describe('getRawDoc', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub() + return (this.doc = { lines: ['2134'] }) + }) + + it('should call get doc with a quick filter', function(done) { + this.DocManager._getDoc.callsArgWith(3, null, this.doc) + return this.DocManager.getDocLines( + this.project_id, + this.doc_id, + (err, doc) => { + doc.should.equal(this.doc) + this.DocManager._getDoc + .calledWith(this.project_id, this.doc_id, { + lines: true, + inS3: true + }) + .should.equal(true) + return done() + } + ) + }) + + return it('should return error when get doc errors', function(done) { + this.DocManager._getDoc.callsArgWith(3, 'error') + return this.DocManager.getDocLines( + this.project_id, + this.doc_id, + (err, exist) => { + err.should.equal('error') + return done() + } + ) + }) + }) + + describe('getDoc', function() { + beforeEach(function() { + this.project = { name: 'mock-project' } + this.doc = { + _id: this.doc_id, + project_id: this.project_id, + lines: ['mock-lines'] + } + this.version = 42 + this.MongoManager.findDoc = sinon.stub() + return (this.MongoManager.getDocVersion = sinon + .stub() + .yields(null, this.version)) + }) + + describe('when using a filter', function() { + beforeEach(function() { + return this.MongoManager.findDoc.yields(null, this.doc) + }) + + it('should error if inS3 is not set to true', function(done) { + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + { inS3: false }, + err => { + expect(err).to.exist + return done() + } + ) + }) + + it('should always get inS3 even when no filter is passed', function(done) { + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + undefined, + err => { + this.MongoManager.findDoc.called.should.equal(false) + expect(err).to.exist + return done() + } + ) + }) + + return it('should not error if inS3 is set to true', function(done) { + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + { inS3: true }, + err => { + expect(err).to.not.exist + return done() + } + ) + }) + }) + + describe('when the doc is in the doc collection', function() { + beforeEach(function() { + this.MongoManager.findDoc.yields(null, this.doc) + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + { version: true, inS3: true }, + this.callback + ) + }) + + it('should get the doc from the doc collection', function() { + return this.MongoManager.findDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) + + it('should get the doc version from the docOps collection', function() { + return this.MongoManager.getDocVersion + .calledWith(this.doc_id) + .should.equal(true) + }) + + return it('should return the callback with the doc with the version', function() { + this.callback.called.should.equal(true) + const doc = this.callback.args[0][1] + doc.lines.should.equal(this.doc.lines) + return doc.version.should.equal(this.version) + }) + }) + + describe('without the version filter', function() { + beforeEach(function() { + this.MongoManager.findDoc.yields(null, this.doc) + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + { version: false, inS3: true }, + this.callback + ) + }) + + return it('should not get the doc version from the docOps collection', function() { + return this.MongoManager.getDocVersion.called.should.equal(false) + }) + }) + + describe('when MongoManager.findDoc errors', function() { + beforeEach(function() { + this.MongoManager.findDoc.yields(this.stubbedError) + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + { version: true, inS3: true }, + this.callback + ) + }) + + return it('should return the error', function() { + return this.callback.calledWith(this.stubbedError).should.equal(true) + }) + }) + + describe('when the doc is archived', function() { + beforeEach(function() { + this.doc = { + _id: this.doc_id, + project_id: this.project_id, + lines: ['mock-lines'], + inS3: true + } + this.MongoManager.findDoc.yields(null, this.doc) + this.DocArchiveManager.unarchiveDoc = ( + project_id, + doc_id, + callback + ) => { + this.doc.inS3 = false + return callback() + } + sinon.spy(this.DocArchiveManager, 'unarchiveDoc') + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + { version: true, inS3: true }, + this.callback + ) + }) + + it('should call the DocArchive to unarchive the doc', function() { + return this.DocArchiveManager.unarchiveDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) + + it('should look up the doc twice', function() { + return this.MongoManager.findDoc.calledTwice.should.equal(true) + }) + + return it('should return the doc', function() { + return this.callback.calledWith(null, this.doc).should.equal(true) + }) + }) + + return describe('when the doc does not exist in the docs collection', function() { + beforeEach(function() { + this.MongoManager.findDoc = sinon.stub().yields(null, null) + return this.DocManager._getDoc( + this.project_id, + this.doc_id, + { version: true, inS3: true }, + this.callback + ) + }) + + return it('should return a NotFoundError', function() { + return this.callback + .calledWith( + sinon.match.has( + 'message', + `No such doc: ${this.doc_id} in project ${this.project_id}` + ) + ) + .should.equal(true) + }) + }) + }) + + describe('getAllNonDeletedDocs', function() { + describe('when the project exists', function() { + beforeEach(function() { + this.docs = [ + { + _id: this.doc_id, + project_id: this.project_id, + lines: ['mock-lines'] + } + ] + this.MongoManager.getProjectsDocs = sinon + .stub() + .callsArgWith(3, null, this.docs) + this.DocArchiveManager.unArchiveAllDocs = sinon + .stub() + .callsArgWith(1, null, this.docs) + this.filter = { lines: true } + return this.DocManager.getAllNonDeletedDocs( + this.project_id, + this.filter, + this.callback + ) + }) + + it('should get the project from the database', function() { + return this.MongoManager.getProjectsDocs + .calledWith(this.project_id, { include_deleted: false }, this.filter) + .should.equal(true) + }) + + return it('should return the docs', function() { + return this.callback.calledWith(null, this.docs).should.equal(true) + }) + }) + + return describe('when there are no docs for the project', function() { + beforeEach(function() { + this.MongoManager.getProjectsDocs = sinon + .stub() + .callsArgWith(3, null, null) + this.DocArchiveManager.unArchiveAllDocs = sinon + .stub() + .callsArgWith(1, null) + return this.DocManager.getAllNonDeletedDocs( + this.project_id, + this.filter, + this.callback + ) + }) + + return it('should return a NotFoundError', function() { + return this.callback + .calledWith( + sinon.match.has('message', `No docs for project ${this.project_id}`) + ) + .should.equal(true) + }) + }) + }) + + describe('deleteDoc', function() { + describe('when the doc exists', function() { + beforeEach(function() { + this.lines = ['mock', 'doc', 'lines'] + this.rev = 77 + this.DocManager.checkDocExists = sinon + .stub() + .callsArgWith(2, null, true) + this.MongoManager.markDocAsDeleted = sinon.stub().callsArg(2) + return this.DocManager.deleteDoc( + this.project_id, + this.doc_id, + this.callback + ) + }) + + it('should get the doc', function() { + return this.DocManager.checkDocExists + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) + + it('should mark doc as deleted', function() { + return this.MongoManager.markDocAsDeleted + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) + + return it('should return the callback', function() { + return this.callback.called.should.equal(true) + }) + }) + + return describe('when the doc does not exist', function() { + beforeEach(function() { + this.DocManager.checkDocExists = sinon + .stub() + .callsArgWith(2, null, false) + return this.DocManager.deleteDoc( + this.project_id, + this.doc_id, + this.callback + ) + }) + + return it('should return a NotFoundError', function() { + return this.callback + .calledWith( + sinon.match.has( + 'message', + `No such project/doc to delete: ${this.project_id}/${this.doc_id}` + ) + ) + .should.equal(true) + }) + }) + }) + + return describe('updateDoc', function() { + beforeEach(function() { + this.oldDocLines = ['old', 'doc', 'lines'] + this.newDocLines = ['new', 'doc', 'lines'] + this.originalRanges = { + changes: [ + { + id: ObjectId().toString(), + op: { i: 'foo', p: 3 }, + meta: { + user_id: ObjectId().toString(), + ts: new Date().toString() + } + } + ] + } + this.newRanges = { + changes: [ + { + id: ObjectId().toString(), + op: { i: 'bar', p: 6 }, + meta: { + user_id: ObjectId().toString(), + ts: new Date().toString() + } + } + ] + } + this.version = 42 + this.doc = { + _id: this.doc_id, + project_id: this.project_id, + lines: this.oldDocLines, + rev: (this.rev = 5), + version: this.version, + ranges: this.originalRanges + } + + this.MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) + this.MongoManager.setDocVersion = sinon.stub().yields() + return (this.DocManager._getDoc = sinon.stub()) + }) + + describe('when only the doc lines have changed', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.newDocLines, + this.version, + this.originalRanges, + this.callback + ) + }) + + it('should get the existing doc', function() { + return this.DocManager._getDoc + .calledWith(this.project_id, this.doc_id, { + version: true, + rev: true, + lines: true, + version: true, + ranges: true, + inS3: true + }) + .should.equal(true) + }) + + it('should upsert the document to the doc collection', function() { + return this.MongoManager.upsertIntoDocCollection + .calledWith(this.project_id, this.doc_id, { lines: this.newDocLines }) + .should.equal(true) + }) + + it('should not update the version', function() { + return this.MongoManager.setDocVersion.called.should.equal(false) + }) + + return it('should return the callback with the new rev', function() { + return this.callback + .calledWith(null, true, this.rev + 1) + .should.equal(true) + }) + }) + + describe('when the doc ranges have changed', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) + this.RangeManager.shouldUpdateRanges.returns(true) + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.oldDocLines, + this.version, + this.newRanges, + this.callback + ) + }) + + it('should upsert the ranges', function() { + return this.MongoManager.upsertIntoDocCollection + .calledWith(this.project_id, this.doc_id, { ranges: this.newRanges }) + .should.equal(true) + }) + + it('should not update the version', function() { + return this.MongoManager.setDocVersion.called.should.equal(false) + }) + + return it('should return the callback with the new rev', function() { + return this.callback + .calledWith(null, true, this.rev + 1) + .should.equal(true) + }) + }) + + describe('when only the version has changed', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.oldDocLines, + this.version + 1, + this.originalRanges, + this.callback + ) + }) + + it('should not change the lines or ranges', function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal( + false + ) + }) + + it('should update the version', function() { + return this.MongoManager.setDocVersion + .calledWith(this.doc_id, this.version + 1) + .should.equal(true) + }) + + return it('should return the callback with the old rev', function() { + return this.callback.calledWith(null, true, this.rev).should.equal(true) + }) + }) + + describe('when the doc has not changed at all', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.oldDocLines, + this.version, + this.originalRanges, + this.callback + ) + }) + + it('should not update the ranges or lines', function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal( + false + ) + }) + + it('should not update the version', function() { + return this.MongoManager.setDocVersion.called.should.equal(false) + }) + + return it('should return the callback with the old rev and modified == false', function() { + return this.callback + .calledWith(null, false, this.rev) + .should.equal(true) + }) + }) + + describe('when the version is null', function() { + beforeEach(function() { + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.newDocLines, + null, + this.originalRanges, + this.callback + ) + }) + + return it('should return an error', function() { + return this.callback + .calledWith( + sinon.match.has('message', 'no lines, version or ranges provided') + ) + .should.equal(true) + }) + }) + + describe('when the lines are null', function() { + beforeEach(function() { + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + null, + this.version, + this.originalRanges, + this.callback + ) + }) + + return it('should return an error', function() { + return this.callback + .calledWith( + sinon.match.has('message', 'no lines, version or ranges provided') + ) + .should.equal(true) + }) + }) + + describe('when the ranges are null', function() { + beforeEach(function() { + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.newDocLines, + this.version, + null, + this.callback + ) + }) + + return it('should return an error', function() { + return this.callback + .calledWith( + sinon.match.has('message', 'no lines, version or ranges provided') + ) + .should.equal(true) + }) + }) + + describe('when there is a generic error getting the doc', function() { + beforeEach(function() { + this.error = new Error('doc could not be found') + this.DocManager._getDoc = sinon + .stub() + .callsArgWith(3, this.error, null, null) + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.newDocLines, + this.version, + this.originalRanges, + this.callback + ) + }) + + it('should not upsert the document to the doc collection', function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal( + false + ) + }) + + return it('should return the callback with the error', function() { + return this.callback.calledWith(this.error).should.equal(true) + }) + }) + + describe('when the doc lines have not changed', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.oldDocLines.slice(), + this.version, + this.originalRanges, + this.callback + ) + }) + + it('should not update the doc', function() { + return this.MongoManager.upsertIntoDocCollection.called.should.equal( + false + ) + }) + + return it('should return the callback with the existing rev', function() { + return this.callback + .calledWith(null, false, this.rev) + .should.equal(true) + }) + }) + + return describe('when the doc does not exist', function() { + beforeEach(function() { + this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, null, null) + return this.DocManager.updateDoc( + this.project_id, + this.doc_id, + this.newDocLines, + this.version, + this.originalRanges, + this.callback + ) + }) + + it('should upsert the document to the doc collection', function() { + return this.MongoManager.upsertIntoDocCollection + .calledWith(this.project_id, this.doc_id, { + lines: this.newDocLines, + ranges: this.originalRanges + }) + .should.equal(true) + }) + + it('should set the version', function() { + return this.MongoManager.setDocVersion + .calledWith(this.doc_id, this.version) + .should.equal(true) + }) + + return it('should return the callback with the new rev', function() { + return this.callback.calledWith(null, true, 1).should.equal(true) + }) + }) + }) +}) diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 27bb31a325..e282c247ff 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -9,442 +9,481 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const SandboxedModule = require('sandboxed-module'); -const { - assert -} = require("chai"); -const sinon = require('sinon'); -const chai = require('chai'); -chai.should(); -const { - expect -} = chai; -const modulePath = require('path').join(__dirname, '../../../app/js/HttpController'); -const { - ObjectId -} = require("mongojs"); +const SandboxedModule = require('sandboxed-module') +const { assert } = require('chai') +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { expect } = chai +const modulePath = require('path').join( + __dirname, + '../../../app/js/HttpController' +) +const { ObjectId } = require('mongojs') -describe("HttpController", function() { - beforeEach(function() { - this.HttpController = SandboxedModule.require(modulePath, { requires: { - "./DocManager": (this.DocManager = {}), - "./DocArchiveManager": (this.DocArchiveManager = {}), - "logger-sharelatex": (this.logger = { log: sinon.stub(), error: sinon.stub() }), - "./HealthChecker": {} - } - }); - this.res = { send: sinon.stub(), json: sinon.stub(), setHeader:sinon.stub() }; - this.res.status = sinon.stub().returns(this.res); - this.req = { query:{}}; - this.next = sinon.stub(); - this.project_id = "mock-project-id"; - this.doc_id = "mock-doc-id"; - this.doc = { - _id: this.doc_id, - lines: ["mock", "lines", " here", "", "", " spaces "], - version: 42, - rev: 5 - }; - return this.deletedDoc = { - deleted:true, - _id: this.doc_id, - lines: ["mock", "lines", " here", "", "", " spaces "], - version: 42, - rev: 5 - };}); +describe('HttpController', function() { + beforeEach(function() { + this.HttpController = SandboxedModule.require(modulePath, { + requires: { + './DocManager': (this.DocManager = {}), + './DocArchiveManager': (this.DocArchiveManager = {}), + 'logger-sharelatex': (this.logger = { + log: sinon.stub(), + error: sinon.stub() + }), + './HealthChecker': {} + } + }) + this.res = { + send: sinon.stub(), + json: sinon.stub(), + setHeader: sinon.stub() + } + this.res.status = sinon.stub().returns(this.res) + this.req = { query: {} } + this.next = sinon.stub() + this.project_id = 'mock-project-id' + this.doc_id = 'mock-doc-id' + this.doc = { + _id: this.doc_id, + lines: ['mock', 'lines', ' here', '', '', ' spaces '], + version: 42, + rev: 5 + } + return (this.deletedDoc = { + deleted: true, + _id: this.doc_id, + lines: ['mock', 'lines', ' here', '', '', ' spaces '], + version: 42, + rev: 5 + }) + }) - describe("getDoc", function() { + describe('getDoc', function() { + describe('without deleted docs', function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + } + this.DocManager.getFullDoc = sinon + .stub() + .callsArgWith(2, null, this.doc) + return this.HttpController.getDoc(this.req, this.res, this.next) + }) - describe("without deleted docs", function() { - beforeEach(function() { - this.req.params = { - project_id: this.project_id, - doc_id: this.doc_id - }; - this.DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, this.doc); - return this.HttpController.getDoc(this.req, this.res, this.next); - }); + it('should get the document with the version (including deleted)', function() { + return this.DocManager.getFullDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) - it("should get the document with the version (including deleted)", function() { - return this.DocManager.getFullDoc - .calledWith(this.project_id, this.doc_id) - .should.equal(true); - }); + return it('should return the doc as JSON', function() { + return this.res.json + .calledWith({ + _id: this.doc_id, + lines: this.doc.lines, + rev: this.doc.rev, + version: this.doc.version + }) + .should.equal(true) + }) + }) - return it("should return the doc as JSON", function() { - return this.res.json - .calledWith({ - _id: this.doc_id, - lines: this.doc.lines, - rev: this.doc.rev, - version: this.doc.version - }) - .should.equal(true); - }); - }); + return describe('which is deleted', function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + } + return (this.DocManager.getFullDoc = sinon + .stub() + .callsArgWith(2, null, this.deletedDoc)) + }) - return describe("which is deleted", function() { - beforeEach(function() { - this.req.params = { - project_id: this.project_id, - doc_id: this.doc_id - }; - return this.DocManager.getFullDoc = sinon.stub().callsArgWith(2, null, this.deletedDoc); - }); + it('should get the doc from the doc manager', function() { + this.HttpController.getDoc(this.req, this.res, this.next) + return this.DocManager.getFullDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) - it("should get the doc from the doc manager", function() { - this.HttpController.getDoc(this.req, this.res, this.next); - return this.DocManager.getFullDoc.calledWith(this.project_id, this.doc_id).should.equal(true); - }); + it('should return 404 if the query string delete is not set ', function() { + this.HttpController.getDoc(this.req, this.res, this.next) + return this.res.send.calledWith(404).should.equal(true) + }) - it("should return 404 if the query string delete is not set ", function() { - this.HttpController.getDoc(this.req, this.res, this.next); - return this.res.send.calledWith(404).should.equal(true); - }); + return it('should return the doc as JSON if include_deleted is set to true', function() { + this.req.query.include_deleted = 'true' + this.HttpController.getDoc(this.req, this.res, this.next) + return this.res.json + .calledWith({ + _id: this.doc_id, + lines: this.doc.lines, + rev: this.doc.rev, + deleted: true, + version: this.doc.version + }) + .should.equal(true) + }) + }) + }) - return it("should return the doc as JSON if include_deleted is set to true", function() { - this.req.query.include_deleted = "true"; - this.HttpController.getDoc(this.req, this.res, this.next); - return this.res.json - .calledWith({ - _id: this.doc_id, - lines: this.doc.lines, - rev: this.doc.rev, - deleted: true, - version: this.doc.version - }) - .should.equal(true); - }); - }); - }); + describe('getRawDoc', function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + } + this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc) + return this.HttpController.getRawDoc(this.req, this.res, this.next) + }) - describe("getRawDoc", function() { - beforeEach(function() { - this.req.params = { - project_id: this.project_id, - doc_id: this.doc_id - }; - this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc); - return this.HttpController.getRawDoc(this.req, this.res, this.next); - }); + it('should get the document without the version', function() { + return this.DocManager.getDocLines + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) - it("should get the document without the version", function() { - return this.DocManager.getDocLines - .calledWith(this.project_id, this.doc_id) - .should.equal(true); - }); + it('should set the content type header', function() { + return this.res.setHeader + .calledWith('content-type', 'text/plain') + .should.equal(true) + }) - it("should set the content type header", function() { - return this.res.setHeader.calledWith('content-type', 'text/plain').should.equal(true); - }); + return it('should send the raw version of the doc', function() { + return assert.deepEqual( + this.res.send.args[0][0], + `${this.doc.lines[0]}\n${this.doc.lines[1]}\n${this.doc.lines[2]}\n${this.doc.lines[3]}\n${this.doc.lines[4]}\n${this.doc.lines[5]}` + ) + }) + }) - return it("should send the raw version of the doc", function() { - return assert.deepEqual(this.res.send.args[0][0], `${this.doc.lines[0]}\n${this.doc.lines[1]}\n${this.doc.lines[2]}\n${this.doc.lines[3]}\n${this.doc.lines[4]}\n${this.doc.lines[5]}`); - }); - }); + describe('getAllDocs', function() { + describe('normally', function() { + beforeEach(function() { + this.req.params = { project_id: this.project_id } + this.docs = [ + { + _id: ObjectId(), + lines: ['mock', 'lines', 'one'], + rev: 2 + }, + { + _id: ObjectId(), + lines: ['mock', 'lines', 'two'], + rev: 4 + } + ] + this.DocManager.getAllNonDeletedDocs = sinon + .stub() + .callsArgWith(2, null, this.docs) + return this.HttpController.getAllDocs(this.req, this.res, this.next) + }) - describe("getAllDocs", function() { - describe("normally", function() { - beforeEach(function() { - this.req.params = - {project_id: this.project_id}; - this.docs = [{ - _id: ObjectId(), - lines: ["mock", "lines", "one"], - rev: 2 - }, { - _id: ObjectId(), - lines: ["mock", "lines", "two"], - rev: 4 - }]; - this.DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, this.docs); - return this.HttpController.getAllDocs(this.req, this.res, this.next); - }); + it('should get all the (non-deleted) docs', function() { + return this.DocManager.getAllNonDeletedDocs + .calledWith(this.project_id, { lines: true, rev: true }) + .should.equal(true) + }) - it("should get all the (non-deleted) docs", function() { - return this.DocManager.getAllNonDeletedDocs - .calledWith(this.project_id, {lines: true, rev: true}) - .should.equal(true); - }); + return it('should return the doc as JSON', function() { + return this.res.json + .calledWith([ + { + _id: this.docs[0]._id.toString(), + lines: this.docs[0].lines, + rev: this.docs[0].rev + }, + { + _id: this.docs[1]._id.toString(), + lines: this.docs[1].lines, + rev: this.docs[1].rev + } + ]) + .should.equal(true) + }) + }) - return it("should return the doc as JSON", function() { - return this.res.json - .calledWith([{ - _id: this.docs[0]._id.toString(), - lines: this.docs[0].lines, - rev: this.docs[0].rev - }, { - _id: this.docs[1]._id.toString(), - lines: this.docs[1].lines, - rev: this.docs[1].rev - }]) - .should.equal(true); - }); - }); + return describe('with a null doc', function() { + beforeEach(function() { + this.req.params = { project_id: this.project_id } + this.docs = [ + { + _id: ObjectId(), + lines: ['mock', 'lines', 'one'], + rev: 2 + }, + null, + { + _id: ObjectId(), + lines: ['mock', 'lines', 'two'], + rev: 4 + } + ] + this.DocManager.getAllNonDeletedDocs = sinon + .stub() + .callsArgWith(2, null, this.docs) + return this.HttpController.getAllDocs(this.req, this.res, this.next) + }) - return describe("with a null doc", function() { - beforeEach(function() { - this.req.params = - {project_id: this.project_id}; - this.docs = [{ - _id: ObjectId(), - lines: ["mock", "lines", "one"], - rev: 2 - }, - null, - { - _id: ObjectId(), - lines: ["mock", "lines", "two"], - rev: 4 - }]; - this.DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, this.docs); - return this.HttpController.getAllDocs(this.req, this.res, this.next); - }); + it('should return the non null docs as JSON', function() { + return this.res.json + .calledWith([ + { + _id: this.docs[0]._id.toString(), + lines: this.docs[0].lines, + rev: this.docs[0].rev + }, + { + _id: this.docs[2]._id.toString(), + lines: this.docs[2].lines, + rev: this.docs[2].rev + } + ]) + .should.equal(true) + }) - it("should return the non null docs as JSON", function() { - return this.res.json - .calledWith([{ - _id: this.docs[0]._id.toString(), - lines: this.docs[0].lines, - rev: this.docs[0].rev - }, { - _id: this.docs[2]._id.toString(), - lines: this.docs[2].lines, - rev: this.docs[2].rev - }]) - .should.equal(true); - }); + return it('should log out an error', function() { + return this.logger.error + .calledWith( + { + err: sinon.match.has('message', 'null doc'), + project_id: this.project_id + }, + 'encountered null doc' + ) + .should.equal(true) + }) + }) + }) - return it("should log out an error", function() { - return this.logger.error - .calledWith({ - err: sinon.match.has('message', "null doc"), - project_id: this.project_id - }, - "encountered null doc" - ) - .should.equal(true); - }); - }); - }); + describe('getAllRanges', function() { + return describe('normally', function() { + beforeEach(function() { + this.req.params = { project_id: this.project_id } + this.docs = [ + { + _id: ObjectId(), + ranges: { mock_ranges: 'one' } + }, + { + _id: ObjectId(), + ranges: { mock_ranges: 'two' } + } + ] + this.DocManager.getAllNonDeletedDocs = sinon + .stub() + .callsArgWith(2, null, this.docs) + return this.HttpController.getAllRanges(this.req, this.res, this.next) + }) - describe("getAllRanges", function() { return describe("normally", function() { - beforeEach(function() { - this.req.params = - {project_id: this.project_id}; - this.docs = [{ - _id: ObjectId(), - ranges: {"mock_ranges": "one"} - }, { - _id: ObjectId(), - ranges: {"mock_ranges": "two"} - }]; - this.DocManager.getAllNonDeletedDocs = sinon.stub().callsArgWith(2, null, this.docs); - return this.HttpController.getAllRanges(this.req, this.res, this.next); - }); + it('should get all the (non-deleted) doc ranges', function() { + return this.DocManager.getAllNonDeletedDocs + .calledWith(this.project_id, { ranges: true }) + .should.equal(true) + }) - it("should get all the (non-deleted) doc ranges", function() { - return this.DocManager.getAllNonDeletedDocs - .calledWith(this.project_id, {ranges: true}) - .should.equal(true); - }); + return it('should return the doc as JSON', function() { + return this.res.json + .calledWith([ + { + _id: this.docs[0]._id.toString(), + ranges: this.docs[0].ranges + }, + { + _id: this.docs[1]._id.toString(), + ranges: this.docs[1].ranges + } + ]) + .should.equal(true) + }) + }) + }) - return it("should return the doc as JSON", function() { - return this.res.json - .calledWith([{ - _id: this.docs[0]._id.toString(), - ranges: this.docs[0].ranges - }, { - _id: this.docs[1]._id.toString(), - ranges: this.docs[1].ranges - }]) - .should.equal(true); - }); - }); }); + describe('updateDoc', function() { + beforeEach(function() { + return (this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + }) + }) - describe("updateDoc", function() { - beforeEach(function() { - return this.req.params = { - project_id: this.project_id, - doc_id: this.doc_id - }; - }); + describe('when the doc lines exist and were updated', function() { + beforeEach(function() { + this.req.body = { + lines: (this.lines = ['hello', 'world']), + version: (this.version = 42), + ranges: (this.ranges = { changes: 'mock' }) + } + this.DocManager.updateDoc = sinon + .stub() + .yields(null, true, (this.rev = 5)) + return this.HttpController.updateDoc(this.req, this.res, this.next) + }) - describe("when the doc lines exist and were updated", function() { - beforeEach(function() { - this.req.body = { - lines: (this.lines = ["hello", "world"]), - version: (this.version = 42), - ranges: (this.ranges = { changes: "mock" }) - }; - this.DocManager.updateDoc = sinon.stub().yields(null, true, (this.rev = 5)); - return this.HttpController.updateDoc(this.req, this.res, this.next); - }); + it('should update the document', function() { + return this.DocManager.updateDoc + .calledWith( + this.project_id, + this.doc_id, + this.lines, + this.version, + this.ranges + ) + .should.equal(true) + }) - it("should update the document", function() { - return this.DocManager.updateDoc - .calledWith(this.project_id, this.doc_id, this.lines, this.version, this.ranges) - .should.equal(true); - }); + return it('should return a modified status', function() { + return this.res.json + .calledWith({ modified: true, rev: this.rev }) + .should.equal(true) + }) + }) - return it("should return a modified status", function() { - return this.res.json - .calledWith({modified: true, rev: this.rev}) - .should.equal(true); - }); - }); + describe('when the doc lines exist and were not updated', function() { + beforeEach(function() { + this.req.body = { + lines: (this.lines = ['hello', 'world']), + version: (this.version = 42), + ranges: {} + } + this.DocManager.updateDoc = sinon + .stub() + .yields(null, false, (this.rev = 5)) + return this.HttpController.updateDoc(this.req, this.res, this.next) + }) - describe("when the doc lines exist and were not updated", function() { - beforeEach(function() { - this.req.body = { - lines: (this.lines = ["hello", "world"]), - version: (this.version = 42), - ranges: {} - }; - this.DocManager.updateDoc = sinon.stub().yields(null, false, (this.rev = 5)); - return this.HttpController.updateDoc(this.req, this.res, this.next); - }); + return it('should return a modified status', function() { + return this.res.json + .calledWith({ modified: false, rev: this.rev }) + .should.equal(true) + }) + }) - return it("should return a modified status", function() { - return this.res.json - .calledWith({modified: false, rev: this.rev}) - .should.equal(true); - }); - }); + describe('when the doc lines are not provided', function() { + beforeEach(function() { + this.req.body = { version: 42, ranges: {} } + this.DocManager.updateDoc = sinon.stub().yields(null, false) + return this.HttpController.updateDoc(this.req, this.res, this.next) + }) - describe("when the doc lines are not provided", function() { - beforeEach(function() { - this.req.body = { version: 42, ranges: {} }; - this.DocManager.updateDoc = sinon.stub().yields(null, false); - return this.HttpController.updateDoc(this.req, this.res, this.next); - }); + it('should not update the document', function() { + return this.DocManager.updateDoc.called.should.equal(false) + }) - it("should not update the document", function() { - return this.DocManager.updateDoc.called.should.equal(false); - }); + return it('should return a 400 (bad request) response', function() { + return this.res.send.calledWith(400).should.equal(true) + }) + }) - return it("should return a 400 (bad request) response", function() { - return this.res.send - .calledWith(400) - .should.equal(true); - }); - }); + describe('when the doc version are not provided', function() { + beforeEach(function() { + this.req.body = { version: 42, lines: ['hello world'] } + this.DocManager.updateDoc = sinon.stub().yields(null, false) + return this.HttpController.updateDoc(this.req, this.res, this.next) + }) - describe("when the doc version are not provided", function() { - beforeEach(function() { - this.req.body = { version: 42, lines: ["hello world"] }; - this.DocManager.updateDoc = sinon.stub().yields(null, false); - return this.HttpController.updateDoc(this.req, this.res, this.next); - }); + it('should not update the document', function() { + return this.DocManager.updateDoc.called.should.equal(false) + }) - it("should not update the document", function() { - return this.DocManager.updateDoc.called.should.equal(false); - }); + return it('should return a 400 (bad request) response', function() { + return this.res.send.calledWith(400).should.equal(true) + }) + }) - return it("should return a 400 (bad request) response", function() { - return this.res.send - .calledWith(400) - .should.equal(true); - }); - }); + describe('when the doc ranges is not provided', function() { + beforeEach(function() { + this.req.body = { lines: ['foo'], version: 42 } + this.DocManager.updateDoc = sinon.stub().yields(null, false) + return this.HttpController.updateDoc(this.req, this.res, this.next) + }) - describe("when the doc ranges is not provided", function() { - beforeEach(function() { - this.req.body = { lines : [ "foo" ], version: 42 }; - this.DocManager.updateDoc = sinon.stub().yields(null, false); - return this.HttpController.updateDoc(this.req, this.res, this.next); - }); + it('should not update the document', function() { + return this.DocManager.updateDoc.called.should.equal(false) + }) - it("should not update the document", function() { - return this.DocManager.updateDoc.called.should.equal(false); - }); + return it('should return a 400 (bad request) response', function() { + return this.res.send.calledWith(400).should.equal(true) + }) + }) - return it("should return a 400 (bad request) response", function() { - return this.res.send - .calledWith(400) - .should.equal(true); - }); - }); + return describe('when the doc body is too large', function() { + beforeEach(function() { + this.req.body = { + lines: (this.lines = Array(2049).fill('a'.repeat(1024))), + version: (this.version = 42), + ranges: (this.ranges = { changes: 'mock' }) + } + return this.HttpController.updateDoc(this.req, this.res, this.next) + }) - return describe("when the doc body is too large", function() { - beforeEach(function() { - this.req.body = { - lines: (this.lines = Array(2049).fill('a'.repeat(1024))), - version: (this.version = 42), - ranges: (this.ranges = { changes: "mock" }) - }; - return this.HttpController.updateDoc(this.req, this.res, this.next); - }); + it('should return a 413 (too large) response', function() { + return sinon.assert.calledWith(this.res.status, 413) + }) - it("should return a 413 (too large) response", function() { - return sinon.assert.calledWith(this.res.status, 413); - }); + return it('should report that the document body is too large', function() { + return sinon.assert.calledWith(this.res.send, 'document body too large') + }) + }) + }) - return it("should report that the document body is too large", function() { - return sinon.assert.calledWith(this.res.send, "document body too large"); - }); - }); - }); + describe('deleteDoc', function() { + beforeEach(function() { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + } + this.DocManager.deleteDoc = sinon.stub().callsArg(2) + return this.HttpController.deleteDoc(this.req, this.res, this.next) + }) - describe("deleteDoc", function() { - beforeEach(function() { - this.req.params = { - project_id: this.project_id, - doc_id: this.doc_id - }; - this.DocManager.deleteDoc = sinon.stub().callsArg(2); - return this.HttpController.deleteDoc(this.req, this.res, this.next); - }); + it('should delete the document', function() { + return this.DocManager.deleteDoc + .calledWith(this.project_id, this.doc_id) + .should.equal(true) + }) - it("should delete the document", function() { - return this.DocManager.deleteDoc - .calledWith(this.project_id, this.doc_id) - .should.equal(true); - }); + return it('should return a 204 (No Content)', function() { + return this.res.send.calledWith(204).should.equal(true) + }) + }) - return it("should return a 204 (No Content)", function() { - return this.res.send - .calledWith(204) - .should.equal(true); - }); - }); + describe('archiveAllDocs', function() { + beforeEach(function() { + this.req.params = { project_id: this.project_id } + this.DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1) + return this.HttpController.archiveAllDocs(this.req, this.res, this.next) + }) - describe("archiveAllDocs", function() { - beforeEach(function() { - this.req.params = - {project_id: this.project_id}; - this.DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1); - return this.HttpController.archiveAllDocs(this.req, this.res, this.next); - }); + it('should archive the project', function() { + return this.DocArchiveManager.archiveAllDocs + .calledWith(this.project_id) + .should.equal(true) + }) - it("should archive the project", function() { - return this.DocArchiveManager.archiveAllDocs - .calledWith(this.project_id) - .should.equal(true); - }); + return it('should return a 204 (No Content)', function() { + return this.res.send.calledWith(204).should.equal(true) + }) + }) - return it("should return a 204 (No Content)", function() { - return this.res.send - .calledWith(204) - .should.equal(true); - }); - }); + return describe('destroyAllDocs', function() { + beforeEach(function() { + this.req.params = { project_id: this.project_id } + this.DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1) + return this.HttpController.destroyAllDocs(this.req, this.res, this.next) + }) - return describe("destroyAllDocs", function() { - beforeEach(function() { - this.req.params = - {project_id: this.project_id}; - this.DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1); - return this.HttpController.destroyAllDocs(this.req, this.res, this.next); - }); - - it("should destroy the docs", function() { - return sinon.assert.calledWith(this.DocArchiveManager.destroyAllDocs, this.project_id); - }); - - return it("should return 204", function() { - return sinon.assert.calledWith(this.res.send, 204); - }); - }); -}); + it('should destroy the docs', function() { + return sinon.assert.calledWith( + this.DocArchiveManager.destroyAllDocs, + this.project_id + ) + }) + return it('should return 204', function() { + return sinon.assert.calledWith(this.res.send, 204) + }) + }) +}) diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index d7dabe3afb..0af25c5ce7 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -9,223 +9,285 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const SandboxedModule = require('sandboxed-module'); -const sinon = require('sinon'); -require('chai').should(); -const modulePath = require('path').join(__dirname, '../../../app/js/MongoManager'); -const { - ObjectId -} = require("mongojs"); -const { - assert -} = require("chai"); +const SandboxedModule = require('sandboxed-module') +const sinon = require('sinon') +require('chai').should() +const modulePath = require('path').join( + __dirname, + '../../../app/js/MongoManager' +) +const { ObjectId } = require('mongojs') +const { assert } = require('chai') -describe("MongoManager", function() { - beforeEach(function() { - this.MongoManager = SandboxedModule.require(modulePath, { requires: { - "./mongojs": { - db: (this.db = { docs: {}, docOps: {} }), - ObjectId - }, - 'metrics-sharelatex': {timeAsyncMethod: sinon.stub()}, - 'logger-sharelatex': {log(){}} - } - }); - this.project_id = ObjectId().toString(); - this.doc_id = ObjectId().toString(); - this.callback = sinon.stub(); - return this.stubbedErr = new Error("hello world"); - }); +describe('MongoManager', function() { + beforeEach(function() { + this.MongoManager = SandboxedModule.require(modulePath, { + requires: { + './mongojs': { + db: (this.db = { docs: {}, docOps: {} }), + ObjectId + }, + 'metrics-sharelatex': { timeAsyncMethod: sinon.stub() }, + 'logger-sharelatex': { log() {} } + } + }) + this.project_id = ObjectId().toString() + this.doc_id = ObjectId().toString() + this.callback = sinon.stub() + return (this.stubbedErr = new Error('hello world')) + }) - describe("findDoc", function() { - beforeEach(function() { - this.doc = { name: "mock-doc"}; - this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc]); - this.filter = { lines: true }; - return this.MongoManager.findDoc(this.project_id, this.doc_id, this.filter, this.callback); - }); + describe('findDoc', function() { + beforeEach(function() { + this.doc = { name: 'mock-doc' } + this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc]) + this.filter = { lines: true } + return this.MongoManager.findDoc( + this.project_id, + this.doc_id, + this.filter, + this.callback + ) + }) - it("should find the doc", function() { - return this.db.docs.find - .calledWith({ - _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id) - }, this.filter) - .should.equal(true); - }); + it('should find the doc', function() { + return this.db.docs.find + .calledWith( + { + _id: ObjectId(this.doc_id), + project_id: ObjectId(this.project_id) + }, + this.filter + ) + .should.equal(true) + }) - return it("should call the callback with the doc", function() { - return this.callback.calledWith(null, this.doc).should.equal(true); - }); - }); + return it('should call the callback with the doc', function() { + return this.callback.calledWith(null, this.doc).should.equal(true) + }) + }) - describe("getProjectsDocs", function() { - beforeEach(function() { - this.filter = {lines: true}; - this.doc1 = { name: "mock-doc1" }; - this.doc2 = { name: "mock-doc2" }; - this.doc3 = { name: "mock-doc3" }; - this.doc4 = { name: "mock-doc4" }; - return this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc, this.doc3, this.doc4]); - }); - - describe("with included_deleted = false", function() { - beforeEach(function() { - return this.MongoManager.getProjectsDocs(this.project_id, {include_deleted: false}, this.filter, this.callback); - }); + describe('getProjectsDocs', function() { + beforeEach(function() { + this.filter = { lines: true } + this.doc1 = { name: 'mock-doc1' } + this.doc2 = { name: 'mock-doc2' } + this.doc3 = { name: 'mock-doc3' } + this.doc4 = { name: 'mock-doc4' } + return (this.db.docs.find = sinon + .stub() + .callsArgWith(2, null, [this.doc, this.doc3, this.doc4])) + }) - it("should find the non-deleted docs via the project_id", function() { - return this.db.docs.find - .calledWith({ - project_id: ObjectId(this.project_id), - deleted: { $ne: true } - }, this.filter) - .should.equal(true); - }); + describe('with included_deleted = false', function() { + beforeEach(function() { + return this.MongoManager.getProjectsDocs( + this.project_id, + { include_deleted: false }, + this.filter, + this.callback + ) + }) - return it("should call the callback with the docs", function() { - return this.callback.calledWith(null, [this.doc, this.doc3, this.doc4]).should.equal(true); - }); - }); - - return describe("with included_deleted = true", function() { - beforeEach(function() { - return this.MongoManager.getProjectsDocs(this.project_id, {include_deleted: true}, this.filter, this.callback); - }); + it('should find the non-deleted docs via the project_id', function() { + return this.db.docs.find + .calledWith( + { + project_id: ObjectId(this.project_id), + deleted: { $ne: true } + }, + this.filter + ) + .should.equal(true) + }) - it("should find all via the project_id", function() { - return this.db.docs.find - .calledWith({ - project_id: ObjectId(this.project_id) - }, this.filter) - .should.equal(true); - }); + return it('should call the callback with the docs', function() { + return this.callback + .calledWith(null, [this.doc, this.doc3, this.doc4]) + .should.equal(true) + }) + }) - return it("should call the callback with the docs", function() { - return this.callback.calledWith(null, [this.doc, this.doc3, this.doc4]).should.equal(true); - }); - }); - }); + return describe('with included_deleted = true', function() { + beforeEach(function() { + return this.MongoManager.getProjectsDocs( + this.project_id, + { include_deleted: true }, + this.filter, + this.callback + ) + }) - describe("upsertIntoDocCollection", function() { - beforeEach(function() { - this.db.docs.update = sinon.stub().callsArgWith(3, this.stubbedErr); - return this.oldRev = 77; - }); + it('should find all via the project_id', function() { + return this.db.docs.find + .calledWith( + { + project_id: ObjectId(this.project_id) + }, + this.filter + ) + .should.equal(true) + }) - it("should upsert the document", function(done){ - return this.MongoManager.upsertIntoDocCollection(this.project_id, this.doc_id, {lines: this.lines}, err=> { - const args = this.db.docs.update.args[0]; - assert.deepEqual(args[0], {_id: ObjectId(this.doc_id)}); - assert.equal(args[1].$set.lines, this.lines); - assert.equal(args[1].$inc.rev, 1); - assert.deepEqual(args[1].$set.project_id, ObjectId(this.project_id)); - return done(); - }); - }); + return it('should call the callback with the docs', function() { + return this.callback + .calledWith(null, [this.doc, this.doc3, this.doc4]) + .should.equal(true) + }) + }) + }) - return it("should return the error", function(done){ - return this.MongoManager.upsertIntoDocCollection(this.project_id, this.doc_id, {lines: this.lines}, err=> { - err.should.equal(this.stubbedErr); - return done(); - }); - }); - }); + describe('upsertIntoDocCollection', function() { + beforeEach(function() { + this.db.docs.update = sinon.stub().callsArgWith(3, this.stubbedErr) + return (this.oldRev = 77) + }) - describe("markDocAsDeleted", function() { - beforeEach(function() { - this.db.docs.update = sinon.stub().callsArgWith(2, this.stubbedErr); - return this.oldRev = 77; - }); + it('should upsert the document', function(done) { + return this.MongoManager.upsertIntoDocCollection( + this.project_id, + this.doc_id, + { lines: this.lines }, + err => { + const args = this.db.docs.update.args[0] + assert.deepEqual(args[0], { _id: ObjectId(this.doc_id) }) + assert.equal(args[1].$set.lines, this.lines) + assert.equal(args[1].$inc.rev, 1) + assert.deepEqual(args[1].$set.project_id, ObjectId(this.project_id)) + return done() + } + ) + }) - it("should process the update", function(done) { - return this.MongoManager.markDocAsDeleted(this.project_id, this.doc_id, err=> { - const args = this.db.docs.update.args[0]; - assert.deepEqual(args[0], {_id: ObjectId(this.doc_id), project_id: ObjectId(this.project_id)}); - assert.equal(args[1].$set.deleted, true); - return done(); - }); - }); + return it('should return the error', function(done) { + return this.MongoManager.upsertIntoDocCollection( + this.project_id, + this.doc_id, + { lines: this.lines }, + err => { + err.should.equal(this.stubbedErr) + return done() + } + ) + }) + }) - return it("should return the error", function(done){ - return this.MongoManager.markDocAsDeleted(this.project_id, this.doc_id, err=> { - err.should.equal(this.stubbedErr); - return done(); - }); - }); - }); + describe('markDocAsDeleted', function() { + beforeEach(function() { + this.db.docs.update = sinon.stub().callsArgWith(2, this.stubbedErr) + return (this.oldRev = 77) + }) - describe("destroyDoc", function() { - beforeEach(function(done) { - this.db.docs.remove = sinon.stub().yields(); - this.db.docOps.remove = sinon.stub().yields(); - return this.MongoManager.destroyDoc('123456789012', done); - }); + it('should process the update', function(done) { + return this.MongoManager.markDocAsDeleted( + this.project_id, + this.doc_id, + err => { + const args = this.db.docs.update.args[0] + assert.deepEqual(args[0], { + _id: ObjectId(this.doc_id), + project_id: ObjectId(this.project_id) + }) + assert.equal(args[1].$set.deleted, true) + return done() + } + ) + }) - it("should destroy the doc", function() { - return sinon.assert.calledWith(this.db.docs.remove, {_id: ObjectId('123456789012')}); - }); + return it('should return the error', function(done) { + return this.MongoManager.markDocAsDeleted( + this.project_id, + this.doc_id, + err => { + err.should.equal(this.stubbedErr) + return done() + } + ) + }) + }) - return it("should destroy the docOps", function() { - return sinon.assert.calledWith(this.db.docOps.remove, {doc_id: ObjectId('123456789012')}); - }); - }); + describe('destroyDoc', function() { + beforeEach(function(done) { + this.db.docs.remove = sinon.stub().yields() + this.db.docOps.remove = sinon.stub().yields() + return this.MongoManager.destroyDoc('123456789012', done) + }) - describe("getDocVersion", function() { - describe("when the doc exists", function() { - beforeEach(function() { - this.doc = - {version: (this.version = 42)}; - this.db.docOps.find = sinon.stub().callsArgWith(2, null, [this.doc]); - return this.MongoManager.getDocVersion(this.doc_id, this.callback); - }); + it('should destroy the doc', function() { + return sinon.assert.calledWith(this.db.docs.remove, { + _id: ObjectId('123456789012') + }) + }) - it("should look for the doc in the database", function() { - return this.db.docOps.find - .calledWith({ doc_id: ObjectId(this.doc_id) }, {version: 1}) - .should.equal(true); - }); + return it('should destroy the docOps', function() { + return sinon.assert.calledWith(this.db.docOps.remove, { + doc_id: ObjectId('123456789012') + }) + }) + }) - return it("should call the callback with the version", function() { - return this.callback.calledWith(null, this.version).should.equal(true); - }); - }); + describe('getDocVersion', function() { + describe('when the doc exists', function() { + beforeEach(function() { + this.doc = { version: (this.version = 42) } + this.db.docOps.find = sinon.stub().callsArgWith(2, null, [this.doc]) + return this.MongoManager.getDocVersion(this.doc_id, this.callback) + }) - return describe("when the doc doesn't exist", function() { - beforeEach(function() { - this.db.docOps.find = sinon.stub().callsArgWith(2, null, []); - return this.MongoManager.getDocVersion(this.doc_id, this.callback); - }); + it('should look for the doc in the database', function() { + return this.db.docOps.find + .calledWith({ doc_id: ObjectId(this.doc_id) }, { version: 1 }) + .should.equal(true) + }) - return it("should call the callback with 0", function() { - return this.callback.calledWith(null, 0).should.equal(true); - }); - }); - }); + return it('should call the callback with the version', function() { + return this.callback.calledWith(null, this.version).should.equal(true) + }) + }) - return describe("setDocVersion", function() { - beforeEach(function() { - this.version = 42; - this.db.docOps.update = sinon.stub().callsArg(3); - return this.MongoManager.setDocVersion(this.doc_id, this.version, this.callback); - }); + return describe("when the doc doesn't exist", function() { + beforeEach(function() { + this.db.docOps.find = sinon.stub().callsArgWith(2, null, []) + return this.MongoManager.getDocVersion(this.doc_id, this.callback) + }) - it("should update the doc version", function() { - return this.db.docOps.update - .calledWith({ - doc_id: ObjectId(this.doc_id) - }, { - $set: { - version: this.version - } - }, { - upsert: true - }) - .should.equal(true); - }); + return it('should call the callback with 0', function() { + return this.callback.calledWith(null, 0).should.equal(true) + }) + }) + }) - return it("should call the callback", function() { - return this.callback.called.should.equal(true); - }); - }); -}); + return describe('setDocVersion', function() { + beforeEach(function() { + this.version = 42 + this.db.docOps.update = sinon.stub().callsArg(3) + return this.MongoManager.setDocVersion( + this.doc_id, + this.version, + this.callback + ) + }) + + it('should update the doc version', function() { + return this.db.docOps.update + .calledWith( + { + doc_id: ObjectId(this.doc_id) + }, + { + $set: { + version: this.version + } + }, + { + upsert: true + } + ) + .should.equal(true) + }) + + return it('should call the callback', function() { + return this.callback.called.should.equal(true) + }) + }) +}) diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index b67e535181..ff6d96a0d1 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -10,190 +10,248 @@ * DS102: Remove unnecessary code created because of implicit returns * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const SandboxedModule = require('sandboxed-module'); -const sinon = require('sinon'); -require('chai').should(); -const { - expect -} = require('chai'); -const modulePath = require('path').join(__dirname, '../../../app/js/RangeManager'); -const { - ObjectId -} = require("mongojs"); -const { - assert -} = require("chai"); -const _ = require("underscore"); +const SandboxedModule = require('sandboxed-module') +const sinon = require('sinon') +require('chai').should() +const { expect } = require('chai') +const modulePath = require('path').join( + __dirname, + '../../../app/js/RangeManager' +) +const { ObjectId } = require('mongojs') +const { assert } = require('chai') +const _ = require('underscore') -describe("RangeManager", function() { - beforeEach(function() { - return this.RangeManager = SandboxedModule.require(modulePath, { requires: { - "./mongojs": { - ObjectId - } - } - } - ); - }); +describe('RangeManager', function() { + beforeEach(function() { + return (this.RangeManager = SandboxedModule.require(modulePath, { + requires: { + './mongojs': { + ObjectId + } + } + })) + }) - describe("jsonRangesToMongo", function() { - it("should convert ObjectIds and dates to proper objects", function() { - const change_id = ObjectId().toString(); - const comment_id = ObjectId().toString(); - const user_id = ObjectId().toString(); - const thread_id = ObjectId().toString(); - const ts = new Date().toJSON(); - return this.RangeManager.jsonRangesToMongo({ - changes: [{ - id: change_id, - op: { i: "foo", p: 3 }, - metadata: { - user_id, - ts - } - }], - comments: [{ - id: comment_id, - op: { c: "foo", p: 3, t: thread_id } - }] - }).should.deep.equal({ - changes: [{ - id: ObjectId(change_id), - op: { i: "foo", p: 3 }, - metadata: { - user_id: ObjectId(user_id), - ts: new Date(ts) - } - }], - comments: [{ - id: ObjectId(comment_id), - op: { c: "foo", p: 3, t: ObjectId(thread_id) } - }] - }); - }); - - it("should leave malformed ObjectIds as they are", function() { - const change_id = "foo"; - const comment_id = "bar"; - const user_id = "baz"; - return this.RangeManager.jsonRangesToMongo({ - changes: [{ - id: change_id, - metadata: { - user_id - } - }], - comments: [{ - id: comment_id - }] - }).should.deep.equal({ - changes: [{ - id: change_id, - metadata: { - user_id - } - }], - comments: [{ - id: comment_id - }] - }); - }); - - return it("should be consistent when transformed through json -> mongo -> json", function() { - const change_id = ObjectId().toString(); - const comment_id = ObjectId().toString(); - const user_id = ObjectId().toString(); - const thread_id = ObjectId().toString(); - const ts = new Date().toJSON(); - const ranges1 = { - changes: [{ - id: change_id, - op: { i: "foo", p: 3 }, - metadata: { - user_id, - ts - } - }], - comments: [{ - id: comment_id, - op: { c: "foo", p: 3, t: thread_id } - }] - }; - const ranges1_copy = JSON.parse(JSON.stringify(ranges1)); // jsonRangesToMongo modifies in place - const ranges2 = JSON.parse(JSON.stringify(this.RangeManager.jsonRangesToMongo(ranges1_copy))); - return ranges1.should.deep.equal(ranges2); - }); - }); - - return describe("shouldUpdateRanges", function() { - beforeEach(function() { - this.ranges = { - changes: [{ - id: ObjectId(), - op: { i: "foo", p: 3 }, - metadata: { - user_id: ObjectId(), - ts: new Date() - } - }], - comments: [{ - id: ObjectId(), - op: { c: "foo", p: 3, t: ObjectId() } - }] - }; - return this.ranges_copy = this.RangeManager.jsonRangesToMongo(JSON.parse(JSON.stringify(this.ranges))); - }); + describe('jsonRangesToMongo', function() { + it('should convert ObjectIds and dates to proper objects', function() { + const change_id = ObjectId().toString() + const comment_id = ObjectId().toString() + const user_id = ObjectId().toString() + const thread_id = ObjectId().toString() + const ts = new Date().toJSON() + return this.RangeManager.jsonRangesToMongo({ + changes: [ + { + id: change_id, + op: { i: 'foo', p: 3 }, + metadata: { + user_id, + ts + } + } + ], + comments: [ + { + id: comment_id, + op: { c: 'foo', p: 3, t: thread_id } + } + ] + }).should.deep.equal({ + changes: [ + { + id: ObjectId(change_id), + op: { i: 'foo', p: 3 }, + metadata: { + user_id: ObjectId(user_id), + ts: new Date(ts) + } + } + ], + comments: [ + { + id: ObjectId(comment_id), + op: { c: 'foo', p: 3, t: ObjectId(thread_id) } + } + ] + }) + }) - describe("with a blank new range", function() { return it("should throw an error", function() { - return expect(() => { - return this.RangeManager.shouldUpdateRanges(this.ranges, null); - }).to.throw(Error); - }); }); - - describe("with a blank old range", function() { return it("should treat it like {}", function() { - this.RangeManager.shouldUpdateRanges(null, {}).should.equal(false); - return this.RangeManager.shouldUpdateRanges(null, this.ranges).should.equal(true); - }); }); - - describe("with no changes", function() { return it("should return false", function() { - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(false); - }); }); - - return describe("with changes", function() { - it("should return true when the change id changes", function() { - this.ranges_copy.changes[0].id = ObjectId(); - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); - }); + it('should leave malformed ObjectIds as they are', function() { + const change_id = 'foo' + const comment_id = 'bar' + const user_id = 'baz' + return this.RangeManager.jsonRangesToMongo({ + changes: [ + { + id: change_id, + metadata: { + user_id + } + } + ], + comments: [ + { + id: comment_id + } + ] + }).should.deep.equal({ + changes: [ + { + id: change_id, + metadata: { + user_id + } + } + ], + comments: [ + { + id: comment_id + } + ] + }) + }) - it("should return true when the change user id changes", function() { - this.ranges_copy.changes[0].metadata.user_id = ObjectId(); - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); - }); + return it('should be consistent when transformed through json -> mongo -> json', function() { + const change_id = ObjectId().toString() + const comment_id = ObjectId().toString() + const user_id = ObjectId().toString() + const thread_id = ObjectId().toString() + const ts = new Date().toJSON() + const ranges1 = { + changes: [ + { + id: change_id, + op: { i: 'foo', p: 3 }, + metadata: { + user_id, + ts + } + } + ], + comments: [ + { + id: comment_id, + op: { c: 'foo', p: 3, t: thread_id } + } + ] + } + const ranges1_copy = JSON.parse(JSON.stringify(ranges1)) // jsonRangesToMongo modifies in place + const ranges2 = JSON.parse( + JSON.stringify(this.RangeManager.jsonRangesToMongo(ranges1_copy)) + ) + return ranges1.should.deep.equal(ranges2) + }) + }) - it("should return true when the change ts changes", function() { - this.ranges_copy.changes[0].metadata.ts = new Date(Date.now() + 1000); - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); - }); + return describe('shouldUpdateRanges', function() { + beforeEach(function() { + this.ranges = { + changes: [ + { + id: ObjectId(), + op: { i: 'foo', p: 3 }, + metadata: { + user_id: ObjectId(), + ts: new Date() + } + } + ], + comments: [ + { + id: ObjectId(), + op: { c: 'foo', p: 3, t: ObjectId() } + } + ] + } + return (this.ranges_copy = this.RangeManager.jsonRangesToMongo( + JSON.parse(JSON.stringify(this.ranges)) + )) + }) - it("should return true when the change op changes", function() { - this.ranges_copy.changes[0].op.i = "bar"; - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); - }); + describe('with a blank new range', function() { + return it('should throw an error', function() { + return expect(() => { + return this.RangeManager.shouldUpdateRanges(this.ranges, null) + }).to.throw(Error) + }) + }) - it("should return true when the comment id changes", function() { - this.ranges_copy.comments[0].id = ObjectId(); - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); - }); + describe('with a blank old range', function() { + return it('should treat it like {}', function() { + this.RangeManager.shouldUpdateRanges(null, {}).should.equal(false) + return this.RangeManager.shouldUpdateRanges( + null, + this.ranges + ).should.equal(true) + }) + }) - it("should return true when the comment offset changes", function() { - this.ranges_copy.comments[0].op.p = 17; - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); - }); + describe('with no changes', function() { + return it('should return false', function() { + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(false) + }) + }) - return it("should return true when the comment content changes", function() { - this.ranges_copy.comments[0].op.c = "bar"; - return this.RangeManager.shouldUpdateRanges(this.ranges, this.ranges_copy).should.equal(true); - }); - }); - }); -}); \ No newline at end of file + return describe('with changes', function() { + it('should return true when the change id changes', function() { + this.ranges_copy.changes[0].id = ObjectId() + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(true) + }) + + it('should return true when the change user id changes', function() { + this.ranges_copy.changes[0].metadata.user_id = ObjectId() + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(true) + }) + + it('should return true when the change ts changes', function() { + this.ranges_copy.changes[0].metadata.ts = new Date(Date.now() + 1000) + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(true) + }) + + it('should return true when the change op changes', function() { + this.ranges_copy.changes[0].op.i = 'bar' + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(true) + }) + + it('should return true when the comment id changes', function() { + this.ranges_copy.comments[0].id = ObjectId() + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(true) + }) + + it('should return true when the comment offset changes', function() { + this.ranges_copy.comments[0].op.p = 17 + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(true) + }) + + return it('should return true when the comment content changes', function() { + this.ranges_copy.comments[0].op.c = 'bar' + return this.RangeManager.shouldUpdateRanges( + this.ranges, + this.ranges_copy + ).should.equal(true) + }) + }) + }) +}) From 93c718dae9985266ee234a75b5e0aa23778fd647 Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:00 +0000 Subject: [PATCH 223/349] decaffeinate: Rename ArchiveDocsTests.coffee and 6 other files from .coffee to .js --- .../coffee/{ArchiveDocsTests.coffee => ArchiveDocsTests.js} | 0 .../coffee/{DeletingDocsTests.coffee => DeletingDocsTests.js} | 0 .../coffee/{GettingAllDocsTests.coffee => GettingAllDocsTests.js} | 0 .../coffee/{GettingDocsTests.coffee => GettingDocsTests.js} | 0 .../coffee/{UpdatingDocsTests.coffee => UpdatingDocsTests.js} | 0 .../coffee/helpers/{DocstoreApp.coffee => DocstoreApp.js} | 0 .../coffee/helpers/{DocstoreClient.coffee => DocstoreClient.js} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename services/docstore/test/acceptance/coffee/{ArchiveDocsTests.coffee => ArchiveDocsTests.js} (100%) rename services/docstore/test/acceptance/coffee/{DeletingDocsTests.coffee => DeletingDocsTests.js} (100%) rename services/docstore/test/acceptance/coffee/{GettingAllDocsTests.coffee => GettingAllDocsTests.js} (100%) rename services/docstore/test/acceptance/coffee/{GettingDocsTests.coffee => GettingDocsTests.js} (100%) rename services/docstore/test/acceptance/coffee/{UpdatingDocsTests.coffee => UpdatingDocsTests.js} (100%) rename services/docstore/test/acceptance/coffee/helpers/{DocstoreApp.coffee => DocstoreApp.js} (100%) rename services/docstore/test/acceptance/coffee/helpers/{DocstoreClient.coffee => DocstoreClient.js} (100%) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/ArchiveDocsTests.coffee rename to services/docstore/test/acceptance/coffee/ArchiveDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee b/services/docstore/test/acceptance/coffee/DeletingDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/DeletingDocsTests.coffee rename to services/docstore/test/acceptance/coffee/DeletingDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/GettingAllDocsTests.coffee rename to services/docstore/test/acceptance/coffee/GettingAllDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.coffee b/services/docstore/test/acceptance/coffee/GettingDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/GettingDocsTests.coffee rename to services/docstore/test/acceptance/coffee/GettingDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/UpdatingDocsTests.coffee rename to services/docstore/test/acceptance/coffee/UpdatingDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js similarity index 100% rename from services/docstore/test/acceptance/coffee/helpers/DocstoreApp.coffee rename to services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js similarity index 100% rename from services/docstore/test/acceptance/coffee/helpers/DocstoreClient.coffee rename to services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js From 73b0bc023f6b5f2fd616bb4b3f874bda419a3a4a Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:02 +0000 Subject: [PATCH 224/349] decaffeinate: Convert ArchiveDocsTests.coffee and 6 other files to JS --- .../acceptance/coffee/ArchiveDocsTests.js | 774 ++++++++++-------- .../acceptance/coffee/DeletingDocsTests.js | 181 ++-- .../acceptance/coffee/GettingAllDocsTests.js | 122 +-- .../acceptance/coffee/GettingDocsTests.js | 124 +-- .../acceptance/coffee/UpdatingDocsTests.js | 463 +++++++---- .../acceptance/coffee/helpers/DocstoreApp.js | 58 +- .../coffee/helpers/DocstoreClient.js | 119 +-- 7 files changed, 1098 insertions(+), 743 deletions(-) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js index 0291eef032..ac3a14f637 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js @@ -1,392 +1,518 @@ -sinon = require "sinon" -chai = require("chai") -should = chai.should() -{db, ObjectId, ISODate} = require "../../../app/js/mongojs" -async = require "async" -Settings = require("settings-sharelatex") -DocArchiveManager = require("../../../app/js/DocArchiveManager.js") -request = require "request" -DocstoreApp = require "./helpers/DocstoreApp" -DocstoreClient = require "./helpers/DocstoreClient" +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const sinon = require("sinon"); +const chai = require("chai"); +const should = chai.should(); +const {db, ObjectId, ISODate} = require("../../../app/js/mongojs"); +const async = require("async"); +const Settings = require("settings-sharelatex"); +const DocArchiveManager = require("../../../app/js/DocArchiveManager.js"); +const request = require("request"); +const DocstoreApp = require("./helpers/DocstoreApp"); +const DocstoreClient = require("./helpers/DocstoreClient"); -describe "Archiving", -> +describe("Archiving", function() { - before (done)-> - DocstoreApp.ensureRunning(done) + before(done => DocstoreApp.ensureRunning(done)); - describe "multiple docs in a project", -> - before (done) -> - @project_id = ObjectId() - @docs = [{ - _id: ObjectId() - lines: ["one", "two", "three"] - ranges: {} + describe("multiple docs in a project", function() { + before(function(done) { + this.project_id = ObjectId(); + this.docs = [{ + _id: ObjectId(), + lines: ["one", "two", "three"], + ranges: {}, version: 2 }, { - _id: ObjectId() - lines: ["aaa", "bbb", "ccc"] - ranges: {} + _id: ObjectId(), + lines: ["aaa", "bbb", "ccc"], + ranges: {}, version: 4 - }] - jobs = for doc in @docs - do (doc) => - (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, doc.version, doc.ranges, callback + }]; + const jobs = Array.from(this.docs).map((doc) => + (doc => { + return callback => { + return DocstoreClient.createDoc(this.project_id, doc._id, doc.lines, doc.version, doc.ranges, callback); + }; + })(doc)); - async.series jobs, (error) => - throw error if error? - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - done() + return async.series(jobs, error => { + if (error != null) { throw error; } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res; + return done(); + }); + }); + }); - it "should archive all the docs", (done) -> - @res.statusCode.should.equal 204 - done() + it("should archive all the docs", function(done) { + this.res.statusCode.should.equal(204); + return done(); + }); - it "should set inS3 and unset lines and ranges in each doc", (done) -> - jobs = for doc in @docs - do (doc) => - (callback) => - db.docs.findOne _id: doc._id, (error, doc) => - should.not.exist doc.lines - should.not.exist doc.ranges - doc.inS3.should.equal true - callback() - async.series jobs, done + it("should set inS3 and unset lines and ranges in each doc", function(done) { + const jobs = Array.from(this.docs).map((doc) => + (doc => { + return callback => { + return db.docs.findOne({_id: doc._id}, (error, doc) => { + should.not.exist(doc.lines); + should.not.exist(doc.ranges); + doc.inS3.should.equal(true); + return callback(); + }); + }; + })(doc)); + return async.series(jobs, done); + }); - it "should set the docs in s3 correctly", (done) -> - jobs = for doc in @docs - do (doc) => - (callback) => - DocstoreClient.getS3Doc @project_id, doc._id, (error, res, s3_doc) => - s3_doc.lines.should.deep.equal doc.lines - s3_doc.ranges.should.deep.equal doc.ranges - callback() - async.series jobs, done + it("should set the docs in s3 correctly", function(done) { + const jobs = Array.from(this.docs).map((doc) => + (doc => { + return callback => { + return DocstoreClient.getS3Doc(this.project_id, doc._id, (error, res, s3_doc) => { + s3_doc.lines.should.deep.equal(doc.lines); + s3_doc.ranges.should.deep.equal(doc.ranges); + return callback(); + }); + }; + })(doc)); + return async.series(jobs, done); + }); - describe "after unarchiving from a request for the project", -> - before (done) -> - DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => - throw error if error? - done() + return describe("after unarchiving from a request for the project", function() { + before(function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs; + if (error != null) { throw error; } + return done(); + }); + }); - it "should return the docs", (done) -> - for doc, i in @fetched_docs - doc.lines.should.deep.equal @docs[i].lines - done() + it("should return the docs", function(done) { + for (let i = 0; i < this.fetched_docs.length; i++) { + const doc = this.fetched_docs[i]; + doc.lines.should.deep.equal(this.docs[i].lines); + } + return done(); + }); - it "should restore the docs to mongo", (done) -> - jobs = for doc, i in @docs - do (doc, i) => - (callback) => - db.docs.findOne _id: doc._id, (error, doc) => - doc.lines.should.deep.equal @docs[i].lines - doc.ranges.should.deep.equal @docs[i].ranges - should.not.exist doc.inS3 - callback() - async.series jobs, done + return it("should restore the docs to mongo", function(done) { + const jobs = Array.from(this.docs).map((doc, i) => + ((doc, i) => { + return callback => { + return db.docs.findOne({_id: doc._id}, (error, doc) => { + doc.lines.should.deep.equal(this.docs[i].lines); + doc.ranges.should.deep.equal(this.docs[i].ranges); + should.not.exist(doc.inS3); + return callback(); + }); + }; + })(doc, i)); + return async.series(jobs, done); + }); + }); + }); - describe "a deleted doc", -> - before (done) -> - @project_id = ObjectId() - @doc = { - _id: ObjectId() - lines: ["one", "two", "three"] - ranges: {} + describe("a deleted doc", function() { + before(function(done) { + this.project_id = ObjectId(); + this.doc = { + _id: ObjectId(), + lines: ["one", "two", "three"], + ranges: {}, version: 2 - } - DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => - throw error if error? - DocstoreClient.deleteDoc @project_id, @doc._id, (error) => - throw error if error? - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - throw error if error? - done() + }; + return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { + if (error != null) { throw error; } + return DocstoreClient.deleteDoc(this.project_id, this.doc._id, error => { + if (error != null) { throw error; } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res; + if (error != null) { throw error; } + return done(); + }); + }); + }); + }); - it "should successully archive the docs", (done) -> - @res.statusCode.should.equal 204 - done() + it("should successully archive the docs", function(done) { + this.res.statusCode.should.equal(204); + return done(); + }); - it "should set inS3 and unset lines and ranges in each doc", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - should.not.exist doc.lines - should.not.exist doc.ranges - doc.inS3.should.equal true - doc.deleted.should.equal true - done() + it("should set inS3 and unset lines and ranges in each doc", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + should.not.exist(doc.lines); + should.not.exist(doc.ranges); + doc.inS3.should.equal(true); + doc.deleted.should.equal(true); + return done(); + }); + }); - it "should set the doc in s3 correctly", (done) -> - DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => - throw error if error? - s3_doc.lines.should.deep.equal @doc.lines - s3_doc.ranges.should.deep.equal @doc.ranges - done() + it("should set the doc in s3 correctly", function(done) { + return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { + if (error != null) { throw error; } + s3_doc.lines.should.deep.equal(this.doc.lines); + s3_doc.ranges.should.deep.equal(this.doc.ranges); + return done(); + }); + }); - describe "after unarchiving from a request for the project", -> - before (done) -> - DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => - throw error if error? - done() + return describe("after unarchiving from a request for the project", function() { + before(function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs; + if (error != null) { throw error; } + return done(); + }); + }); - it "should not included the deleted", (done) -> - @fetched_docs.length.should.equal 0 - done() + it("should not included the deleted", function(done) { + this.fetched_docs.length.should.equal(0); + return done(); + }); - it "should restore the doc to mongo", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - doc.lines.should.deep.equal @doc.lines - doc.ranges.should.deep.equal @doc.ranges - should.not.exist doc.inS3 - doc.deleted.should.equal true - done() + return it("should restore the doc to mongo", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + doc.lines.should.deep.equal(this.doc.lines); + doc.ranges.should.deep.equal(this.doc.ranges); + should.not.exist(doc.inS3); + doc.deleted.should.equal(true); + return done(); + }); + }); + }); + }); - describe "a doc with large lines", -> - before (done) -> - @project_id = ObjectId() - @timeout 1000 * 30 - quarterMegInBytes = 250000 - big_line = require("crypto").randomBytes(quarterMegInBytes).toString("hex") - @doc = { - _id: ObjectId() - lines: [big_line, big_line, big_line, big_line] - ranges: {} + describe("a doc with large lines", function() { + before(function(done) { + this.project_id = ObjectId(); + this.timeout(1000 * 30); + const quarterMegInBytes = 250000; + const big_line = require("crypto").randomBytes(quarterMegInBytes).toString("hex"); + this.doc = { + _id: ObjectId(), + lines: [big_line, big_line, big_line, big_line], + ranges: {}, version: 2 - } - DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => - throw error if error? - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - throw error if error? - done() + }; + return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { + if (error != null) { throw error; } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res; + if (error != null) { throw error; } + return done(); + }); + }); + }); - it "should successully archive the docs", (done) -> - @res.statusCode.should.equal 204 - done() + it("should successully archive the docs", function(done) { + this.res.statusCode.should.equal(204); + return done(); + }); - it "should set inS3 and unset lines and ranges in each doc", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - should.not.exist doc.lines - should.not.exist doc.ranges - doc.inS3.should.equal true - done() + it("should set inS3 and unset lines and ranges in each doc", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + should.not.exist(doc.lines); + should.not.exist(doc.ranges); + doc.inS3.should.equal(true); + return done(); + }); + }); - it "should set the doc in s3 correctly", (done) -> - DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => - throw error if error? - s3_doc.lines.should.deep.equal @doc.lines - s3_doc.ranges.should.deep.equal @doc.ranges - done() + it("should set the doc in s3 correctly", function(done) { + return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { + if (error != null) { throw error; } + s3_doc.lines.should.deep.equal(this.doc.lines); + s3_doc.ranges.should.deep.equal(this.doc.ranges); + return done(); + }); + }); - describe "after unarchiving from a request for the project", -> - before (done) -> - DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => - throw error if error? - done() + return describe("after unarchiving from a request for the project", function() { + before(function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs; + if (error != null) { throw error; } + return done(); + }); + }); - it "should restore the doc to mongo", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - doc.lines.should.deep.equal @doc.lines - doc.ranges.should.deep.equal @doc.ranges - should.not.exist doc.inS3 - done() + return it("should restore the doc to mongo", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + doc.lines.should.deep.equal(this.doc.lines); + doc.ranges.should.deep.equal(this.doc.ranges); + should.not.exist(doc.inS3); + return done(); + }); + }); + }); + }); - describe "a doc with naughty strings", -> - before (done) -> - @project_id = ObjectId() - @doc = { - _id: ObjectId() - lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ] - ranges: {} + describe("a doc with naughty strings", function() { + before(function(done) { + this.project_id = ObjectId(); + this.doc = { + _id: ObjectId(), + lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ], + ranges: {}, version: 2 - } - DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => - throw error if error? - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - throw error if error? - done() + }; + return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { + if (error != null) { throw error; } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res; + if (error != null) { throw error; } + return done(); + }); + }); + }); - it "should successully archive the docs", (done) -> - @res.statusCode.should.equal 204 - done() + it("should successully archive the docs", function(done) { + this.res.statusCode.should.equal(204); + return done(); + }); - it "should set inS3 and unset lines and ranges in each doc", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - should.not.exist doc.lines - should.not.exist doc.ranges - doc.inS3.should.equal true - done() + it("should set inS3 and unset lines and ranges in each doc", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + should.not.exist(doc.lines); + should.not.exist(doc.ranges); + doc.inS3.should.equal(true); + return done(); + }); + }); - it "should set the doc in s3 correctly", (done) -> - DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => - throw error if error? - s3_doc.lines.should.deep.equal @doc.lines - s3_doc.ranges.should.deep.equal @doc.ranges - done() + it("should set the doc in s3 correctly", function(done) { + return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { + if (error != null) { throw error; } + s3_doc.lines.should.deep.equal(this.doc.lines); + s3_doc.ranges.should.deep.equal(this.doc.ranges); + return done(); + }); + }); - describe "after unarchiving from a request for the project", -> - before (done) -> - DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => - throw error if error? - done() + return describe("after unarchiving from a request for the project", function() { + before(function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs; + if (error != null) { throw error; } + return done(); + }); + }); - it "should restore the doc to mongo", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - doc.lines.should.deep.equal @doc.lines - doc.ranges.should.deep.equal @doc.ranges - should.not.exist doc.inS3 - done() + return it("should restore the doc to mongo", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + doc.lines.should.deep.equal(this.doc.lines); + doc.ranges.should.deep.equal(this.doc.ranges); + should.not.exist(doc.inS3); + return done(); + }); + }); + }); + }); - describe "a doc with ranges", -> - before (done) -> - @project_id = ObjectId() - @doc = { - _id: ObjectId() - lines: ["one", "two", "three"] + describe("a doc with ranges", function() { + before(function(done) { + this.project_id = ObjectId(); + this.doc = { + _id: ObjectId(), + lines: ["one", "two", "three"], ranges: { changes: [{ id : ObjectId(), - op : { "i" : "foo", "p" : 24 } + op : { "i" : "foo", "p" : 24 }, metadata : { "user_id" : ObjectId(), "ts" : new Date("2017-01-27T16:10:44.194Z") } }, { id : ObjectId(), - op : { "d" : "bar", "p" : 50 } + op : { "d" : "bar", "p" : 50 }, metadata : { "user_id" : ObjectId(), "ts" : new Date("2017-01-27T18:10:44.194Z") } - }] + }], comments: [{ id: ObjectId(), op: { "c" : "comment", "p" : 284, "t" : ObjectId() }, metadata: { "user_id" : ObjectId(), "ts" : new Date("2017-01-26T14:22:04.869Z") } }] - } + }, version: 2 - } - DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => - throw error if error? - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - throw error if error? - done() + }; + return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { + if (error != null) { throw error; } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res; + if (error != null) { throw error; } + return done(); + }); + }); + }); - it "should successully archive the docs", (done) -> - @res.statusCode.should.equal 204 - done() + it("should successully archive the docs", function(done) { + this.res.statusCode.should.equal(204); + return done(); + }); - it "should set inS3 and unset lines and ranges in each doc", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - should.not.exist doc.lines - should.not.exist doc.ranges - doc.inS3.should.equal true - done() + it("should set inS3 and unset lines and ranges in each doc", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + should.not.exist(doc.lines); + should.not.exist(doc.ranges); + doc.inS3.should.equal(true); + return done(); + }); + }); - it "should set the doc in s3 correctly", (done) -> - DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => - throw error if error? - s3_doc.lines.should.deep.equal @doc.lines - ranges = JSON.parse(JSON.stringify(@doc.ranges)) # ObjectId -> String - s3_doc.ranges.should.deep.equal ranges - done() + it("should set the doc in s3 correctly", function(done) { + return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { + if (error != null) { throw error; } + s3_doc.lines.should.deep.equal(this.doc.lines); + const ranges = JSON.parse(JSON.stringify(this.doc.ranges)); // ObjectId -> String + s3_doc.ranges.should.deep.equal(ranges); + return done(); + }); + }); - describe "after unarchiving from a request for the project", -> - before (done) -> - DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => - throw error if error? - done() + return describe("after unarchiving from a request for the project", function() { + before(function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs; + if (error != null) { throw error; } + return done(); + }); + }); - it "should restore the doc to mongo", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - doc.lines.should.deep.equal @doc.lines - doc.ranges.should.deep.equal @doc.ranges - should.not.exist doc.inS3 - done() + return it("should restore the doc to mongo", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + doc.lines.should.deep.equal(this.doc.lines); + doc.ranges.should.deep.equal(this.doc.ranges); + should.not.exist(doc.inS3); + return done(); + }); + }); + }); + }); - describe "a doc that is archived twice", -> - before (done) -> - @project_id = ObjectId() - @doc = { - _id: ObjectId() - lines: ["abc", "def", "ghi"] - ranges: {} + describe("a doc that is archived twice", function() { + before(function(done) { + this.project_id = ObjectId(); + this.doc = { + _id: ObjectId(), + lines: ["abc", "def", "ghi"], + ranges: {}, version: 2 - } - DocstoreClient.createDoc @project_id, @doc._id, @doc.lines, @doc.version, @doc.ranges, (error) => - throw error if error? - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - throw error if error? - @res.statusCode.should.equal 204 - DocstoreClient.archiveAllDoc @project_id, (error, @res) => - throw error if error? - @res.statusCode.should.equal 204 - done() + }; + return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { + if (error != null) { throw error; } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res; + if (error != null) { throw error; } + this.res.statusCode.should.equal(204); + return DocstoreClient.archiveAllDoc(this.project_id, (error, res1) => { + this.res = res1; + if (error != null) { throw error; } + this.res.statusCode.should.equal(204); + return done(); + }); + }); + }); + }); - it "should set inS3 and unset lines and ranges in each doc", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - should.not.exist doc.lines - should.not.exist doc.ranges - doc.inS3.should.equal true - done() + it("should set inS3 and unset lines and ranges in each doc", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + should.not.exist(doc.lines); + should.not.exist(doc.ranges); + doc.inS3.should.equal(true); + return done(); + }); + }); - it "should set the doc in s3 correctly", (done) -> - DocstoreClient.getS3Doc @project_id, @doc._id, (error, res, s3_doc) => - throw error if error? - s3_doc.lines.should.deep.equal @doc.lines - s3_doc.ranges.should.deep.equal @doc.ranges - done() + it("should set the doc in s3 correctly", function(done) { + return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { + if (error != null) { throw error; } + s3_doc.lines.should.deep.equal(this.doc.lines); + s3_doc.ranges.should.deep.equal(this.doc.ranges); + return done(); + }); + }); - describe "after unarchiving from a request for the project", -> - before (done) -> - DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => - throw error if error? - done() + return describe("after unarchiving from a request for the project", function() { + before(function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs; + if (error != null) { throw error; } + return done(); + }); + }); - it "should restore the doc to mongo", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - doc.lines.should.deep.equal @doc.lines - doc.ranges.should.deep.equal @doc.ranges - should.not.exist doc.inS3 - done() + return it("should restore the doc to mongo", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + doc.lines.should.deep.equal(this.doc.lines); + doc.ranges.should.deep.equal(this.doc.ranges); + should.not.exist(doc.inS3); + return done(); + }); + }); + }); + }); - describe "a doc with the old schema (just an array of lines)", -> - before (done) -> - @project_id = ObjectId() - @doc = { - _id: ObjectId() - lines: ["abc", "def", "ghi"] - ranges: {} + return describe("a doc with the old schema (just an array of lines)", function() { + before(function(done) { + this.project_id = ObjectId(); + this.doc = { + _id: ObjectId(), + lines: ["abc", "def", "ghi"], + ranges: {}, version: 2 - } - options = DocArchiveManager.buildS3Options("#{@project_id}/#{@doc._id}") - options.json = @doc.lines - request.put options, (error, res, body) => - throw error if error? - res.statusCode.should.equal 200 - db.docs.insert { - project_id: @project_id - _id: @doc._id - rev: @doc.version + }; + const options = DocArchiveManager.buildS3Options(`${this.project_id}/${this.doc._id}`); + options.json = this.doc.lines; + return request.put(options, (error, res, body) => { + if (error != null) { throw error; } + res.statusCode.should.equal(200); + return db.docs.insert({ + project_id: this.project_id, + _id: this.doc._id, + rev: this.doc.version, inS3: true - }, (error) => - throw error if error? - DocstoreClient.getAllDocs @project_id, (error, res, @fetched_docs) => - throw error if error? - done() + }, error => { + if (error != null) { throw error; } + return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs; + if (error != null) { throw error; } + return done(); + }); + }); + }); + }); - it "should restore the doc to mongo", (done) -> - db.docs.findOne _id: @doc._id, (error, doc) => - throw error if error? - doc.lines.should.deep.equal @doc.lines - should.not.exist doc.inS3 - done() + it("should restore the doc to mongo", function(done) { + return db.docs.findOne({_id: this.doc._id}, (error, doc) => { + if (error != null) { throw error; } + doc.lines.should.deep.equal(this.doc.lines); + should.not.exist(doc.inS3); + return done(); + }); + }); - it "should return the doc", (done) -> - @fetched_docs[0].lines.should.deep.equal @doc.lines - done() + return it("should return the doc", function(done) { + this.fetched_docs[0].lines.should.deep.equal(this.doc.lines); + return done(); + }); + }); +}); diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.js b/services/docstore/test/acceptance/coffee/DeletingDocsTests.js index 4aac25902e..3fd2bf240d 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.js @@ -1,85 +1,122 @@ -sinon = require "sinon" -chai = require("chai") -chai.should() -{db, ObjectId} = require "../../../app/js/mongojs" -expect = chai.expect -DocstoreApp = require "./helpers/DocstoreApp" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const sinon = require("sinon"); +const chai = require("chai"); +chai.should(); +const {db, ObjectId} = require("../../../app/js/mongojs"); +const { + expect +} = chai; +const DocstoreApp = require("./helpers/DocstoreApp"); -DocstoreClient = require "./helpers/DocstoreClient" +const DocstoreClient = require("./helpers/DocstoreClient"); -describe "Deleting a doc", -> - beforeEach (done) -> - @project_id = ObjectId() - @doc_id = ObjectId() - @lines = ["original", "lines"] - @version = 42 - @ranges = [] - DocstoreApp.ensureRunning => - DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => - throw error if error? - done() +describe("Deleting a doc", function() { + beforeEach(function(done) { + this.project_id = ObjectId(); + this.doc_id = ObjectId(); + this.lines = ["original", "lines"]; + this.version = 42; + this.ranges = []; + return DocstoreApp.ensureRunning(() => { + return DocstoreClient.createDoc(this.project_id, this.doc_id, this.lines, this.version, this.ranges, error => { + if (error != null) { throw error; } + return done(); + }); + }); + }); - describe "when the doc exists", -> - beforeEach (done) -> - DocstoreClient.deleteDoc @project_id, @doc_id, (error, @res, doc) => - done() + describe("when the doc exists", function() { + beforeEach(function(done) { + return DocstoreClient.deleteDoc(this.project_id, this.doc_id, (error, res, doc) => { + this.res = res; + return done(); + }); + }); - afterEach (done) -> - db.docs.remove({_id: @doc_id}, done) + afterEach(function(done) { + return db.docs.remove({_id: this.doc_id}, done); + }); - it "should insert a deleted doc into the docs collection", (done) -> - db.docs.find _id: @doc_id, (error, docs) => - docs[0]._id.should.deep.equal @doc_id - docs[0].lines.should.deep.equal @lines - docs[0].deleted.should.equal true - done() + return it("should insert a deleted doc into the docs collection", function(done) { + return db.docs.find({_id: this.doc_id}, (error, docs) => { + docs[0]._id.should.deep.equal(this.doc_id); + docs[0].lines.should.deep.equal(this.lines); + docs[0].deleted.should.equal(true); + return done(); + }); + }); + }); - describe "when the doc does not exist", -> - it "should return a 404", (done) -> - missing_doc_id = ObjectId() - DocstoreClient.deleteDoc @project_id, missing_doc_id, (error, res, doc) -> - res.statusCode.should.equal 404 - done() + return describe("when the doc does not exist", () => it("should return a 404", function(done) { + const missing_doc_id = ObjectId(); + return DocstoreClient.deleteDoc(this.project_id, missing_doc_id, function(error, res, doc) { + res.statusCode.should.equal(404); + return done(); + }); + })); +}); -describe "Destroying a project's documents", -> - describe "when the doc exists", -> - beforeEach (done) -> - db.docOps.insert {doc_id: ObjectId(@doc_id), version: 1}, (err) -> - return done(err) if err? - DocstoreClient.destroyAllDoc @project_id, done +describe("Destroying a project's documents", function() { + describe("when the doc exists", function() { + beforeEach(function(done) { + return db.docOps.insert({doc_id: ObjectId(this.doc_id), version: 1}, function(err) { + if (err != null) { return done(err); } + return DocstoreClient.destroyAllDoc(this.project_id, done); + }); + }); - it "should remove the doc from the docs collection", (done) -> - db.docs.find _id: @doc_id, (err, docs) -> - expect(err).not.to.exist - expect(docs).to.deep.equal [] - done() + it("should remove the doc from the docs collection", function(done) { + return db.docs.find({_id: this.doc_id}, function(err, docs) { + expect(err).not.to.exist; + expect(docs).to.deep.equal([]); + return done(); + }); + }); - it "should remove the docOps from the docOps collection", (done) -> - db.docOps.find doc_id: @doc_id, (err, docOps) -> - expect(err).not.to.exist - expect(docOps).to.deep.equal [] - done() + return it("should remove the docOps from the docOps collection", function(done) { + return db.docOps.find({doc_id: this.doc_id}, function(err, docOps) { + expect(err).not.to.exist; + expect(docOps).to.deep.equal([]); + return done(); + }); + }); + }); - describe "when the doc is archived", -> - beforeEach (done) -> - DocstoreClient.archiveAllDoc @project_id, (err) -> - return done(err) if err? - DocstoreClient.destroyAllDoc @project_id, done + return describe("when the doc is archived", function() { + beforeEach(function(done) { + return DocstoreClient.archiveAllDoc(this.project_id, function(err) { + if (err != null) { return done(err); } + return DocstoreClient.destroyAllDoc(this.project_id, done); + }); + }); - it "should remove the doc from the docs collection", (done) -> - db.docs.find _id: @doc_id, (err, docs) -> - expect(err).not.to.exist - expect(docs).to.deep.equal [] - done() + it("should remove the doc from the docs collection", function(done) { + return db.docs.find({_id: this.doc_id}, function(err, docs) { + expect(err).not.to.exist; + expect(docs).to.deep.equal([]); + return done(); + }); + }); - it "should remove the docOps from the docOps collection", (done) -> - db.docOps.find doc_id: @doc_id, (err, docOps) -> - expect(err).not.to.exist - expect(docOps).to.deep.equal [] - done() + it("should remove the docOps from the docOps collection", function(done) { + return db.docOps.find({doc_id: this.doc_id}, function(err, docOps) { + expect(err).not.to.exist; + expect(docOps).to.deep.equal([]); + return done(); + }); + }); - it "should remove the doc contents from s3", (done) -> - DocstoreClient.getS3Doc @project_id, @doc_id, (error, res, s3_doc) => - throw error if error? - expect(res.statusCode).to.equal 404 - done() + return it("should remove the doc contents from s3", function(done) { + return DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error, res, s3_doc) => { + if (error != null) { throw error; } + expect(res.statusCode).to.equal(404); + return done(); + }); + }); + }); +}); diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js index 6a16006044..e5df055760 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js @@ -1,63 +1,83 @@ -sinon = require "sinon" -chai = require("chai") -chai.should() -{ObjectId} = require "mongojs" -async = require "async" -DocstoreApp = require "./helpers/DocstoreApp" +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const sinon = require("sinon"); +const chai = require("chai"); +chai.should(); +const {ObjectId} = require("mongojs"); +const async = require("async"); +const DocstoreApp = require("./helpers/DocstoreApp"); -DocstoreClient = require "./helpers/DocstoreClient" +const DocstoreClient = require("./helpers/DocstoreClient"); -describe "Getting all docs", -> - beforeEach (done) -> - @project_id = ObjectId() - @docs = [{ - _id: ObjectId() - lines: ["one", "two", "three"] - ranges: {"mock": "one"} +describe("Getting all docs", function() { + beforeEach(function(done) { + this.project_id = ObjectId(); + this.docs = [{ + _id: ObjectId(), + lines: ["one", "two", "three"], + ranges: {"mock": "one"}, rev: 2 }, { - _id: ObjectId() - lines: ["aaa", "bbb", "ccc"] - ranges: {"mock": "two"} + _id: ObjectId(), + lines: ["aaa", "bbb", "ccc"], + ranges: {"mock": "two"}, rev: 4 }, { - _id: ObjectId() - lines: ["111", "222", "333"] - ranges: {"mock": "three"} + _id: ObjectId(), + lines: ["111", "222", "333"], + ranges: {"mock": "three"}, rev: 6 - }] - @deleted_doc = { - _id: ObjectId() - lines: ["deleted"] - ranges: {"mock": "four"} + }]; + this.deleted_doc = { + _id: ObjectId(), + lines: ["deleted"], + ranges: {"mock": "four"}, rev: 8 - } - version = 42 - jobs = for doc in @docs - do (doc) => - (callback) => - DocstoreClient.createDoc @project_id, doc._id, doc.lines, version, doc.ranges, callback - jobs.push (cb) => - DocstoreClient.createDoc @project_id, @deleted_doc._id, @deleted_doc.lines, version, @deleted_doc.ranges, (err)=> - DocstoreClient.deleteDoc @project_id, @deleted_doc._id, cb - jobs.unshift (cb)-> - DocstoreApp.ensureRunning cb - async.series jobs, done + }; + const version = 42; + const jobs = Array.from(this.docs).map((doc) => + (doc => { + return callback => { + return DocstoreClient.createDoc(this.project_id, doc._id, doc.lines, version, doc.ranges, callback); + }; + })(doc)); + jobs.push(cb => { + return DocstoreClient.createDoc(this.project_id, this.deleted_doc._id, this.deleted_doc.lines, version, this.deleted_doc.ranges, err=> { + return DocstoreClient.deleteDoc(this.project_id, this.deleted_doc._id, cb); + }); + }); + jobs.unshift(cb => DocstoreApp.ensureRunning(cb)); + return async.series(jobs, done); + }); - it "getAllDocs should return all the (non-deleted) docs", (done) -> - DocstoreClient.getAllDocs @project_id, (error, res, docs) => - throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs - doc.lines.should.deep.equal @docs[i].lines - done() + it("getAllDocs should return all the (non-deleted) docs", function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, docs) => { + if (error != null) { throw error; } + docs.length.should.equal(this.docs.length); + for (let i = 0; i < docs.length; i++) { + const doc = docs[i]; + doc.lines.should.deep.equal(this.docs[i].lines); + } + return done(); + }); + }); - it "getAllRanges should return all the (non-deleted) doc ranges", (done) -> - DocstoreClient.getAllRanges @project_id, (error, res, docs) => - throw error if error? - docs.length.should.equal @docs.length - for doc, i in docs - doc.ranges.should.deep.equal @docs[i].ranges - done() + return it("getAllRanges should return all the (non-deleted) doc ranges", function(done) { + return DocstoreClient.getAllRanges(this.project_id, (error, res, docs) => { + if (error != null) { throw error; } + docs.length.should.equal(this.docs.length); + for (let i = 0; i < docs.length; i++) { + const doc = docs[i]; + doc.ranges.should.deep.equal(this.docs[i].ranges); + } + return done(); + }); + }); +}); diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.js b/services/docstore/test/acceptance/coffee/GettingDocsTests.js index dbdbd31aa2..02c0b6d7b1 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.js +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.js @@ -1,63 +1,83 @@ -sinon = require "sinon" -chai = require("chai") -chai.should() -{ObjectId} = require "mongojs" -DocstoreApp = require "./helpers/DocstoreApp" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const sinon = require("sinon"); +const chai = require("chai"); +chai.should(); +const {ObjectId} = require("mongojs"); +const DocstoreApp = require("./helpers/DocstoreApp"); -DocstoreClient = require "./helpers/DocstoreClient" +const DocstoreClient = require("./helpers/DocstoreClient"); -describe "Getting a doc", -> - beforeEach (done) -> - @project_id = ObjectId() - @doc_id = ObjectId() - @lines = ["original", "lines"] - @version = 42 - @ranges = { +describe("Getting a doc", function() { + beforeEach(function(done) { + this.project_id = ObjectId(); + this.doc_id = ObjectId(); + this.lines = ["original", "lines"]; + this.version = 42; + this.ranges = { changes: [{ - id: ObjectId().toString() - op: { i: "foo", p: 3 } - meta: - user_id: ObjectId().toString() + id: ObjectId().toString(), + op: { i: "foo", p: 3 }, + meta: { + user_id: ObjectId().toString(), ts: new Date().toString() + } }] - } - DocstoreApp.ensureRunning => - DocstoreClient.createDoc @project_id, @doc_id, @lines, @version, @ranges, (error) => - throw error if error? - done() + }; + return DocstoreApp.ensureRunning(() => { + return DocstoreClient.createDoc(this.project_id, this.doc_id, this.lines, this.version, this.ranges, error => { + if (error != null) { throw error; } + return done(); + }); + }); + }); - describe "when the doc exists", -> - it "should get the doc lines and version", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @lines - doc.version.should.equal @version - doc.ranges.should.deep.equal @ranges - done() + describe("when the doc exists", () => it("should get the doc lines and version", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.lines); + doc.version.should.equal(this.version); + doc.ranges.should.deep.equal(this.ranges); + return done(); + }); + })); - describe "when the doc does not exist", -> - it "should return a 404", (done) -> - missing_doc_id = ObjectId() - DocstoreClient.getDoc @project_id, missing_doc_id, {}, (error, res, doc) -> - res.statusCode.should.equal 404 - done() + describe("when the doc does not exist", () => it("should return a 404", function(done) { + const missing_doc_id = ObjectId(); + return DocstoreClient.getDoc(this.project_id, missing_doc_id, {}, function(error, res, doc) { + res.statusCode.should.equal(404); + return done(); + }); + })); - describe "when the doc is a deleted doc", -> - beforeEach (done) -> - @deleted_doc_id = ObjectId() - DocstoreClient.createDoc @project_id, @deleted_doc_id, @lines, @version, @ranges, (error) => - throw error if error? - DocstoreClient.deleteDoc @project_id, @deleted_doc_id, done + return describe("when the doc is a deleted doc", function() { + beforeEach(function(done) { + this.deleted_doc_id = ObjectId(); + return DocstoreClient.createDoc(this.project_id, this.deleted_doc_id, this.lines, this.version, this.ranges, error => { + if (error != null) { throw error; } + return DocstoreClient.deleteDoc(this.project_id, this.deleted_doc_id, done); + }); + }); - it "should return the doc", (done) -> - DocstoreClient.getDoc @project_id, @deleted_doc_id, {include_deleted:true},(error, res, doc) => - doc.lines.should.deep.equal @lines - doc.version.should.equal @version - doc.ranges.should.deep.equal @ranges - doc.deleted.should.equal true - done() + it("should return the doc", function(done) { + return DocstoreClient.getDoc(this.project_id, this.deleted_doc_id, {include_deleted:true},(error, res, doc) => { + doc.lines.should.deep.equal(this.lines); + doc.version.should.equal(this.version); + doc.ranges.should.deep.equal(this.ranges); + doc.deleted.should.equal(true); + return done(); + }); + }); - it "should return a 404 when the query string is not set", (done)-> - DocstoreClient.getDoc @project_id, @deleted_doc_id, {},(error, res, doc) => - res.statusCode.should.equal 404 - done() + return it("should return a 404 when the query string is not set", function(done){ + return DocstoreClient.getDoc(this.project_id, this.deleted_doc_id, {},(error, res, doc) => { + res.statusCode.should.equal(404); + return done(); + }); + }); + }); +}); \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js index 2b916a3a83..b5f12af3c8 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js @@ -1,225 +1,332 @@ -sinon = require "sinon" -chai = require("chai") -chai.should() -{ObjectId} = require "mongojs" -DocstoreApp = require "./helpers/DocstoreApp" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const sinon = require("sinon"); +const chai = require("chai"); +chai.should(); +const {ObjectId} = require("mongojs"); +const DocstoreApp = require("./helpers/DocstoreApp"); -DocstoreClient = require "./helpers/DocstoreClient" +const DocstoreClient = require("./helpers/DocstoreClient"); -describe "Applying updates to a doc", -> - beforeEach (done) -> - @project_id = ObjectId() - @doc_id = ObjectId() - @originalLines = ["original", "lines"] - @newLines = ["new", "lines"] - @originalRanges = { +describe("Applying updates to a doc", function() { + beforeEach(function(done) { + this.project_id = ObjectId(); + this.doc_id = ObjectId(); + this.originalLines = ["original", "lines"]; + this.newLines = ["new", "lines"]; + this.originalRanges = { changes: [{ - id: ObjectId().toString() - op: { i: "foo", p: 3 } - meta: - user_id: ObjectId().toString() + id: ObjectId().toString(), + op: { i: "foo", p: 3 }, + meta: { + user_id: ObjectId().toString(), ts: new Date().toString() + } }] - } - @newRanges = { + }; + this.newRanges = { changes: [{ - id: ObjectId().toString() - op: { i: "bar", p: 6 } - meta: - user_id: ObjectId().toString() + id: ObjectId().toString(), + op: { i: "bar", p: 6 }, + meta: { + user_id: ObjectId().toString(), ts: new Date().toString() + } }] - } - @version = 42 - DocstoreApp.ensureRunning => - DocstoreClient.createDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error) => - throw error if error? - done() + }; + this.version = 42; + return DocstoreApp.ensureRunning(() => { + return DocstoreClient.createDoc(this.project_id, this.doc_id, this.originalLines, this.version, this.originalRanges, error => { + if (error != null) { throw error; } + return done(); + }); + }); + }); - describe "when nothing has been updated", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, @originalRanges, (error, res, @body) => - done() + describe("when nothing has been updated", function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, this.version, this.originalRanges, (error, res, body) => { + this.body = body; + return done(); + }); + }); - it "should return modified = false", -> - @body.modified.should.equal false + it("should return modified = false", function() { + return this.body.modified.should.equal(false); + }); - it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - doc.version.should.equal @version - doc.ranges.should.deep.equal @originalRanges - done() + return it("should not update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + doc.version.should.equal(this.version); + doc.ranges.should.deep.equal(this.originalRanges); + return done(); + }); + }); + }); - describe "when the lines have changed", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @newLines, @version, @originalRanges, (error, res, @body) => - done() + describe("when the lines have changed", function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.newLines, this.version, this.originalRanges, (error, res, body) => { + this.body = body; + return done(); + }); + }); - it "should return modified = true", -> - @body.modified.should.equal true + it("should return modified = true", function() { + return this.body.modified.should.equal(true); + }); - it "should return the rev", -> - @body.rev.should.equal 2 + it("should return the rev", function() { + return this.body.rev.should.equal(2); + }); - it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @newLines - doc.version.should.equal @version - doc.ranges.should.deep.equal @originalRanges - done() + return it("should update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.newLines); + doc.version.should.equal(this.version); + doc.ranges.should.deep.equal(this.originalRanges); + return done(); + }); + }); + }); - describe "when the version has changed", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version + 1, @originalRanges, (error, res, @body) => - done() + describe("when the version has changed", function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, this.version + 1, this.originalRanges, (error, res, body) => { + this.body = body; + return done(); + }); + }); - it "should return modified = true", -> - @body.modified.should.equal true + it("should return modified = true", function() { + return this.body.modified.should.equal(true); + }); - it "should return the rev", -> - @body.rev.should.equal 1 + it("should return the rev", function() { + return this.body.rev.should.equal(1); + }); - it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - doc.version.should.equal @version + 1 - doc.ranges.should.deep.equal @originalRanges - done() + return it("should update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + doc.version.should.equal(this.version + 1); + doc.ranges.should.deep.equal(this.originalRanges); + return done(); + }); + }); + }); - describe "when the ranges have changed", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, @version, @newRanges, (error, res, @body) => - done() + describe("when the ranges have changed", function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, this.version, this.newRanges, (error, res, body) => { + this.body = body; + return done(); + }); + }); - it "should return modified = true", -> - @body.modified.should.equal true + it("should return modified = true", function() { + return this.body.modified.should.equal(true); + }); - it "should return the rev", -> - @body.rev.should.equal 2 + it("should return the rev", function() { + return this.body.rev.should.equal(2); + }); - it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - doc.version.should.equal @version - doc.ranges.should.deep.equal @newRanges - done() + return it("should update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + doc.version.should.equal(this.version); + doc.ranges.should.deep.equal(this.newRanges); + return done(); + }); + }); + }); - describe "when the doc does not exist", -> - beforeEach (done) -> - @missing_doc_id = ObjectId() - DocstoreClient.updateDoc @project_id, @missing_doc_id, @originalLines, 0, @originalRanges, (error, @res, @body) => - done() + describe("when the doc does not exist", function() { + beforeEach(function(done) { + this.missing_doc_id = ObjectId(); + return DocstoreClient.updateDoc(this.project_id, this.missing_doc_id, this.originalLines, 0, this.originalRanges, (error, res, body) => { + this.res = res; + this.body = body; + return done(); + }); + }); - it "should create the doc", -> - @body.rev.should.equal 1 + it("should create the doc", function() { + return this.body.rev.should.equal(1); + }); - it "should be retreivable", (done)-> - DocstoreClient.getDoc @project_id, @missing_doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - doc.version.should.equal 0 - doc.ranges.should.deep.equal @originalRanges - done() + return it("should be retreivable", function(done){ + return DocstoreClient.getDoc(this.project_id, this.missing_doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + doc.version.should.equal(0); + doc.ranges.should.deep.equal(this.originalRanges); + return done(); + }); + }); + }); - describe "when malformed doc lines are provided", -> - describe "when the lines are not an array", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, { foo: "bar" }, @version, @originalRanges, (error, @res, @body) => - done() + describe("when malformed doc lines are provided", function() { + describe("when the lines are not an array", function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc(this.project_id, this.doc_id, { foo: "bar" }, this.version, this.originalRanges, (error, res, body) => { + this.res = res; + this.body = body; + return done(); + }); + }); - it "should return 400", -> - @res.statusCode.should.equal 400 + it("should return 400", function() { + return this.res.statusCode.should.equal(400); + }); - it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - done() + return it("should not update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + return done(); + }); + }); + }); - describe "when the lines are not present", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, null, @version, @originalRanges, (error, @res, @body) => - done() + return describe("when the lines are not present", function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc(this.project_id, this.doc_id, null, this.version, this.originalRanges, (error, res, body) => { + this.res = res; + this.body = body; + return done(); + }); + }); - it "should return 400", -> - @res.statusCode.should.equal 400 + it("should return 400", function() { + return this.res.statusCode.should.equal(400); + }); - it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - done() + return it("should not update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + return done(); + }); + }); + }); + }); - describe "when no version is provided", -> - beforeEach (done) -> - DocstoreClient.updateDoc @project_id, @doc_id, @originalLines, null, @originalRanges, (error, @res, @body) => - done() + describe("when no version is provided", function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, null, this.originalRanges, (error, res, body) => { + this.res = res; + this.body = body; + return done(); + }); + }); - it "should return 400", -> - @res.statusCode.should.equal 400 + it("should return 400", function() { + return this.res.statusCode.should.equal(400); + }); - it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - doc.version.should.equal @version - done() + return it("should not update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + doc.version.should.equal(this.version); + return done(); + }); + }); + }); - describe "when the content is large", -> - beforeEach (done) -> - line = new Array(1025).join("x") # 1kb - @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1mb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, res, @body) => - done() + describe("when the content is large", function() { + beforeEach(function(done) { + const line = new Array(1025).join("x"); // 1kb + this.largeLines = Array.apply(null, Array(1024)).map(() => line); // 1mb + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { + this.body = body; + return done(); + }); + }); - it "should return modified = true", -> - @body.modified.should.equal true + it("should return modified = true", function() { + return this.body.modified.should.equal(true); + }); - it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @largeLines - done() + return it("should update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.largeLines); + return done(); + }); + }); + }); - describe "when there is a large json payload", -> - beforeEach (done) -> - line = new Array(1025).join("x") # 1kb - @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1kb - @originalRanges.padding = Array.apply(null, Array(2049)).map(() -> line) # 2mb + 1kb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, @res, @body) => - done() + describe("when there is a large json payload", function() { + beforeEach(function(done) { + const line = new Array(1025).join("x"); // 1kb + this.largeLines = Array.apply(null, Array(1024)).map(() => line); // 1kb + this.originalRanges.padding = Array.apply(null, Array(2049)).map(() => line); // 2mb + 1kb + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { + this.res = res; + this.body = body; + return done(); + }); + }); - it "should return modified = true", -> - @body.modified.should.equal true + it("should return modified = true", function() { + return this.body.modified.should.equal(true); + }); - it "should update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @largeLines - done() + return it("should update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.largeLines); + return done(); + }); + }); + }); - describe "when the document body is too large", -> - beforeEach (done) -> - line = new Array(1025).join("x") # 1kb - @largeLines = Array.apply(null, Array(2049)).map(() -> line) # 2mb + 1kb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, @res, @body) => - done() + describe("when the document body is too large", function() { + beforeEach(function(done) { + const line = new Array(1025).join("x"); // 1kb + this.largeLines = Array.apply(null, Array(2049)).map(() => line); // 2mb + 1kb + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { + this.res = res; + this.body = body; + return done(); + }); + }); - it "should return 413", -> - @res.statusCode.should.equal 413 + it("should return 413", function() { + return this.res.statusCode.should.equal(413); + }); - it "should report body too large", -> - @res.body.should.equal 'document body too large' + it("should report body too large", function() { + return this.res.body.should.equal('document body too large'); + }); - it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - done() + return it("should not update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + return done(); + }); + }); + }); - describe "when the json payload is too large", -> - beforeEach (done) -> - line = new Array(1025).join("x") # 1kb - @largeLines = Array.apply(null, Array(1024)).map(() -> line) # 1kb - @originalRanges.padding = Array.apply(null, Array(4096)).map(() -> line) # 4mb - DocstoreClient.updateDoc @project_id, @doc_id, @largeLines, @version, @originalRanges, (error, @res, @body) => - done() + return describe("when the json payload is too large", function() { + beforeEach(function(done) { + const line = new Array(1025).join("x"); // 1kb + this.largeLines = Array.apply(null, Array(1024)).map(() => line); // 1kb + this.originalRanges.padding = Array.apply(null, Array(4096)).map(() => line); // 4mb + return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { + this.res = res; + this.body = body; + return done(); + }); + }); - it "should not update the doc in the API", (done) -> - DocstoreClient.getDoc @project_id, @doc_id, {}, (error, res, doc) => - doc.lines.should.deep.equal @originalLines - done() + return it("should not update the doc in the API", function(done) { + return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines); + return done(); + }); + }); + }); +}); diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js b/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js index 4a916955a9..533284d8a3 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js @@ -1,21 +1,39 @@ -app = require('../../../../app') -require("logger-sharelatex").logger.level("error") -settings = require("settings-sharelatex") +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS205: Consider reworking code to avoid use of IIFEs + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const app = require('../../../../app'); +require("logger-sharelatex").logger.level("error"); +const settings = require("settings-sharelatex"); -module.exports = - running: false - initing: false - callbacks: [] - ensureRunning: (callback = (error) ->) -> - if @running - return callback() - else if @initing - @callbacks.push callback - else - @initing = true - @callbacks.push callback - app.listen settings.internal.docstore.port, "localhost", (error) => - throw error if error? - @running = true - for callback in @callbacks - callback() \ No newline at end of file +module.exports = { + running: false, + initing: false, + callbacks: [], + ensureRunning(callback) { + if (callback == null) { callback = function(error) {}; } + if (this.running) { + return callback(); + } else if (this.initing) { + return this.callbacks.push(callback); + } else { + this.initing = true; + this.callbacks.push(callback); + return app.listen(settings.internal.docstore.port, "localhost", error => { + if (error != null) { throw error; } + this.running = true; + return (() => { + const result = []; + for (callback of Array.from(this.callbacks)) { + result.push(callback()); + } + return result; + })(); + }); + } + } +}; \ No newline at end of file diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js index 446f99ad58..61cc519ec6 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js @@ -1,57 +1,84 @@ -request = require("request").defaults(jar: false) -{db, ObjectId} = require("../../../../app/js/mongojs") -settings = require("settings-sharelatex") -DocArchiveManager = require("../../../../app/js/DocArchiveManager.js") +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +let DocstoreClient; +const request = require("request").defaults({jar: false}); +const {db, ObjectId} = require("../../../../app/js/mongojs"); +const settings = require("settings-sharelatex"); +const DocArchiveManager = require("../../../../app/js/DocArchiveManager.js"); -module.exports = DocstoreClient = +module.exports = (DocstoreClient = { - createDoc: (project_id, doc_id, lines, version, ranges, callback = (error) ->) -> - DocstoreClient.updateDoc project_id, doc_id, lines, version, ranges, callback + createDoc(project_id, doc_id, lines, version, ranges, callback) { + if (callback == null) { callback = function(error) {}; } + return DocstoreClient.updateDoc(project_id, doc_id, lines, version, ranges, callback); + }, - getDoc: (project_id, doc_id, qs, callback = (error, res, body) ->) -> - request.get { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" + getDoc(project_id, doc_id, qs, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + return request.get({ + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + json: true, + qs + }, callback); + }, + + getAllDocs(project_id, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + return request.get({ + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, json: true - qs:qs - }, callback + }, callback); + }, - getAllDocs: (project_id, callback = (error, res, body) ->) -> - request.get { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc" + getAllRanges(project_id, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + return request.get({ + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, json: true - }, callback + }, callback); + }, - getAllRanges: (project_id, callback = (error, res, body) ->) -> - request.get { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/ranges" - json: true - }, callback + updateDoc(project_id, doc_id, lines, version, ranges, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + return request.post({ + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + json: { + lines, + version, + ranges + } + }, callback); + }, - updateDoc: (project_id, doc_id, lines, version, ranges, callback = (error, res, body) ->) -> - request.post { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" - json: - lines: lines - version: version - ranges: ranges - }, callback - - deleteDoc: (project_id, doc_id, callback = (error, res, body) ->) -> - request.del { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/doc/#{doc_id}" - }, callback + deleteDoc(project_id, doc_id, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + return request.del({ + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}` + }, callback); + }, - archiveAllDoc: (project_id, callback = (error, res, body) ->) -> - request.post { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/archive" - }, callback + archiveAllDoc(project_id, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + return request.post({ + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive` + }, callback); + }, - destroyAllDoc: (project_id, callback = (error, res, body) ->) -> - request.post { - url: "http://localhost:#{settings.internal.docstore.port}/project/#{project_id}/destroy" - }, callback + destroyAllDoc(project_id, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + return request.post({ + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy` + }, callback); + }, - getS3Doc: (project_id, doc_id, callback = (error, res, body) ->) -> - options = DocArchiveManager.buildS3Options(project_id+"/"+doc_id) - options.json = true - request.get options, callback + getS3Doc(project_id, doc_id, callback) { + if (callback == null) { callback = function(error, res, body) {}; } + const options = DocArchiveManager.buildS3Options(project_id+"/"+doc_id); + options.json = true; + return request.get(options, callback); + } +}); From 1391ae96e7b73da9ff85d7b76b13519d4c2d2e1d Mon Sep 17 00:00:00 2001 From: decaffeinate <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:03 +0000 Subject: [PATCH 225/349] decaffeinate: Run post-processing cleanups on ArchiveDocsTests.coffee and 6 other files --- .../acceptance/coffee/ArchiveDocsTests.js | 9 +++++++- .../acceptance/coffee/DeletingDocsTests.js | 21 ++++++++++++------- .../acceptance/coffee/GettingAllDocsTests.js | 6 ++++++ .../acceptance/coffee/GettingDocsTests.js | 17 ++++++++++----- .../acceptance/coffee/UpdatingDocsTests.js | 6 ++++++ .../acceptance/coffee/helpers/DocstoreApp.js | 5 +++++ .../coffee/helpers/DocstoreClient.js | 7 +++++++ 7 files changed, 58 insertions(+), 13 deletions(-) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js index ac3a14f637..69a3ec2308 100644 --- a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js @@ -1,3 +1,10 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from @@ -19,7 +26,7 @@ const DocstoreClient = require("./helpers/DocstoreClient"); describe("Archiving", function() { - before(done => DocstoreApp.ensureRunning(done)); + before(function(done) { return DocstoreApp.ensureRunning(done); }); describe("multiple docs in a project", function() { before(function(done) { diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.js b/services/docstore/test/acceptance/coffee/DeletingDocsTests.js index 3fd2bf240d..026730205d 100644 --- a/services/docstore/test/acceptance/coffee/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/coffee/DeletingDocsTests.js @@ -1,3 +1,10 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -52,13 +59,13 @@ describe("Deleting a doc", function() { }); }); - return describe("when the doc does not exist", () => it("should return a 404", function(done) { + return describe("when the doc does not exist", function() { return it("should return a 404", function(done) { const missing_doc_id = ObjectId(); - return DocstoreClient.deleteDoc(this.project_id, missing_doc_id, function(error, res, doc) { + return DocstoreClient.deleteDoc(this.project_id, missing_doc_id, (error, res, doc) => { res.statusCode.should.equal(404); return done(); }); - })); + }); }); }); describe("Destroying a project's documents", function() { @@ -71,7 +78,7 @@ describe("Destroying a project's documents", function() { }); it("should remove the doc from the docs collection", function(done) { - return db.docs.find({_id: this.doc_id}, function(err, docs) { + return db.docs.find({_id: this.doc_id}, (err, docs) => { expect(err).not.to.exist; expect(docs).to.deep.equal([]); return done(); @@ -79,7 +86,7 @@ describe("Destroying a project's documents", function() { }); return it("should remove the docOps from the docOps collection", function(done) { - return db.docOps.find({doc_id: this.doc_id}, function(err, docOps) { + return db.docOps.find({doc_id: this.doc_id}, (err, docOps) => { expect(err).not.to.exist; expect(docOps).to.deep.equal([]); return done(); @@ -96,7 +103,7 @@ describe("Destroying a project's documents", function() { }); it("should remove the doc from the docs collection", function(done) { - return db.docs.find({_id: this.doc_id}, function(err, docs) { + return db.docs.find({_id: this.doc_id}, (err, docs) => { expect(err).not.to.exist; expect(docs).to.deep.equal([]); return done(); @@ -104,7 +111,7 @@ describe("Destroying a project's documents", function() { }); it("should remove the docOps from the docOps collection", function(done) { - return db.docOps.find({doc_id: this.doc_id}, function(err, docOps) { + return db.docOps.find({doc_id: this.doc_id}, (err, docOps) => { expect(err).not.to.exist; expect(docOps).to.deep.equal([]); return done(); diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js index e5df055760..2970042480 100644 --- a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js @@ -1,3 +1,9 @@ +/* eslint-disable + handle-callback-err, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.js b/services/docstore/test/acceptance/coffee/GettingDocsTests.js index 02c0b6d7b1..e6a96d0958 100644 --- a/services/docstore/test/acceptance/coffee/GettingDocsTests.js +++ b/services/docstore/test/acceptance/coffee/GettingDocsTests.js @@ -1,3 +1,10 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns @@ -36,22 +43,22 @@ describe("Getting a doc", function() { }); }); - describe("when the doc exists", () => it("should get the doc lines and version", function(done) { + describe("when the doc exists", function() { return it("should get the doc lines and version", function(done) { return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { doc.lines.should.deep.equal(this.lines); doc.version.should.equal(this.version); doc.ranges.should.deep.equal(this.ranges); return done(); }); - })); + }); }); - describe("when the doc does not exist", () => it("should return a 404", function(done) { + describe("when the doc does not exist", function() { return it("should return a 404", function(done) { const missing_doc_id = ObjectId(); - return DocstoreClient.getDoc(this.project_id, missing_doc_id, {}, function(error, res, doc) { + return DocstoreClient.getDoc(this.project_id, missing_doc_id, {}, (error, res, doc) => { res.statusCode.should.equal(404); return done(); }); - })); + }); }); return describe("when the doc is a deleted doc", function() { beforeEach(function(done) { diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js index b5f12af3c8..b3908ba2c4 100644 --- a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js @@ -1,3 +1,9 @@ +/* eslint-disable + handle-callback-err, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js b/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js index 533284d8a3..9fd8389576 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js @@ -1,3 +1,8 @@ +/* eslint-disable + handle-callback-err, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS101: Remove unnecessary use of Array.from diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js index 61cc519ec6..129723a9ea 100644 --- a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js @@ -1,3 +1,10 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. /* * decaffeinate suggestions: * DS102: Remove unnecessary code created because of implicit returns From 7e131e4c71743aed6e1f9c1bb7a700c5f6eb9c9b Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:06 +0000 Subject: [PATCH 226/349] decaffeinate: rename test/acceptance/coffee to test/acceptance/js --- .../docstore/test/acceptance/{coffee => js}/ArchiveDocsTests.js | 0 .../docstore/test/acceptance/{coffee => js}/DeletingDocsTests.js | 0 .../test/acceptance/{coffee => js}/GettingAllDocsTests.js | 0 .../docstore/test/acceptance/{coffee => js}/GettingDocsTests.js | 0 .../docstore/test/acceptance/{coffee => js}/UpdatingDocsTests.js | 0 .../test/acceptance/{coffee => js}/helpers/DocstoreApp.js | 0 .../test/acceptance/{coffee => js}/helpers/DocstoreClient.js | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename services/docstore/test/acceptance/{coffee => js}/ArchiveDocsTests.js (100%) rename services/docstore/test/acceptance/{coffee => js}/DeletingDocsTests.js (100%) rename services/docstore/test/acceptance/{coffee => js}/GettingAllDocsTests.js (100%) rename services/docstore/test/acceptance/{coffee => js}/GettingDocsTests.js (100%) rename services/docstore/test/acceptance/{coffee => js}/UpdatingDocsTests.js (100%) rename services/docstore/test/acceptance/{coffee => js}/helpers/DocstoreApp.js (100%) rename services/docstore/test/acceptance/{coffee => js}/helpers/DocstoreClient.js (100%) diff --git a/services/docstore/test/acceptance/coffee/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/ArchiveDocsTests.js rename to services/docstore/test/acceptance/js/ArchiveDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/DeletingDocsTests.js rename to services/docstore/test/acceptance/js/DeletingDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/GettingAllDocsTests.js rename to services/docstore/test/acceptance/js/GettingAllDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/GettingDocsTests.js rename to services/docstore/test/acceptance/js/GettingDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js similarity index 100% rename from services/docstore/test/acceptance/coffee/UpdatingDocsTests.js rename to services/docstore/test/acceptance/js/UpdatingDocsTests.js diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js similarity index 100% rename from services/docstore/test/acceptance/coffee/helpers/DocstoreApp.js rename to services/docstore/test/acceptance/js/helpers/DocstoreApp.js diff --git a/services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js similarity index 100% rename from services/docstore/test/acceptance/coffee/helpers/DocstoreClient.js rename to services/docstore/test/acceptance/js/helpers/DocstoreClient.js From 785a6cb5444d9795c85a9882aaad9961c0e829ea Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:09 +0000 Subject: [PATCH 227/349] prettier: convert test/acceptance decaffeinated files to Prettier format --- .../test/acceptance/js/ArchiveDocsTests.js | 1561 +++++++++++------ .../test/acceptance/js/DeletingDocsTests.js | 234 +-- .../test/acceptance/js/GettingAllDocsTests.js | 169 +- .../test/acceptance/js/GettingDocsTests.js | 187 +- .../test/acceptance/js/UpdatingDocsTests.js | 733 +++++--- .../test/acceptance/js/helpers/DocstoreApp.js | 62 +- .../acceptance/js/helpers/DocstoreClient.js | 183 +- 7 files changed, 2012 insertions(+), 1117 deletions(-) diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 69a3ec2308..67d5d0e828 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -12,514 +12,1097 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -const should = chai.should(); -const {db, ObjectId, ISODate} = require("../../../app/js/mongojs"); -const async = require("async"); -const Settings = require("settings-sharelatex"); -const DocArchiveManager = require("../../../app/js/DocArchiveManager.js"); -const request = require("request"); -const DocstoreApp = require("./helpers/DocstoreApp"); -const DocstoreClient = require("./helpers/DocstoreClient"); +const sinon = require('sinon') +const chai = require('chai') +const should = chai.should() +const { db, ObjectId, ISODate } = require('../../../app/js/mongojs') +const async = require('async') +const Settings = require('settings-sharelatex') +const DocArchiveManager = require('../../../app/js/DocArchiveManager.js') +const request = require('request') +const DocstoreApp = require('./helpers/DocstoreApp') +const DocstoreClient = require('./helpers/DocstoreClient') +describe('Archiving', function() { + before(function(done) { + return DocstoreApp.ensureRunning(done) + }) -describe("Archiving", function() { + describe('multiple docs in a project', function() { + before(function(done) { + this.project_id = ObjectId() + this.docs = [ + { + _id: ObjectId(), + lines: ['one', 'two', 'three'], + ranges: {}, + version: 2 + }, + { + _id: ObjectId(), + lines: ['aaa', 'bbb', 'ccc'], + ranges: {}, + version: 4 + } + ] + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { + return DocstoreClient.createDoc( + this.project_id, + doc._id, + doc.lines, + doc.version, + doc.ranges, + callback + ) + } + })(doc) + ) - before(function(done) { return DocstoreApp.ensureRunning(done); }); + return async.series(jobs, error => { + if (error != null) { + throw error + } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res + return done() + }) + }) + }) - describe("multiple docs in a project", function() { - before(function(done) { - this.project_id = ObjectId(); - this.docs = [{ - _id: ObjectId(), - lines: ["one", "two", "three"], - ranges: {}, - version: 2 - }, { - _id: ObjectId(), - lines: ["aaa", "bbb", "ccc"], - ranges: {}, - version: 4 - }]; - const jobs = Array.from(this.docs).map((doc) => - (doc => { - return callback => { - return DocstoreClient.createDoc(this.project_id, doc._id, doc.lines, doc.version, doc.ranges, callback); - }; - })(doc)); + it('should archive all the docs', function(done) { + this.res.statusCode.should.equal(204) + return done() + }) - return async.series(jobs, error => { - if (error != null) { throw error; } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res; - return done(); - }); - }); - }); + it('should set inS3 and unset lines and ranges in each doc', function(done) { + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { + return db.docs.findOne({ _id: doc._id }, (error, doc) => { + should.not.exist(doc.lines) + should.not.exist(doc.ranges) + doc.inS3.should.equal(true) + return callback() + }) + } + })(doc) + ) + return async.series(jobs, done) + }) - it("should archive all the docs", function(done) { - this.res.statusCode.should.equal(204); - return done(); - }); + it('should set the docs in s3 correctly', function(done) { + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { + return DocstoreClient.getS3Doc( + this.project_id, + doc._id, + (error, res, s3_doc) => { + s3_doc.lines.should.deep.equal(doc.lines) + s3_doc.ranges.should.deep.equal(doc.ranges) + return callback() + } + ) + } + })(doc) + ) + return async.series(jobs, done) + }) - it("should set inS3 and unset lines and ranges in each doc", function(done) { - const jobs = Array.from(this.docs).map((doc) => - (doc => { - return callback => { - return db.docs.findOne({_id: doc._id}, (error, doc) => { - should.not.exist(doc.lines); - should.not.exist(doc.ranges); - doc.inS3.should.equal(true); - return callback(); - }); - }; - })(doc)); - return async.series(jobs, done); - }); + return describe('after unarchiving from a request for the project', function() { + before(function(done) { + return DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + }) - it("should set the docs in s3 correctly", function(done) { - const jobs = Array.from(this.docs).map((doc) => - (doc => { - return callback => { - return DocstoreClient.getS3Doc(this.project_id, doc._id, (error, res, s3_doc) => { - s3_doc.lines.should.deep.equal(doc.lines); - s3_doc.ranges.should.deep.equal(doc.ranges); - return callback(); - }); - }; - })(doc)); - return async.series(jobs, done); - }); - - return describe("after unarchiving from a request for the project", function() { - before(function(done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs; - if (error != null) { throw error; } - return done(); - }); - }); - - it("should return the docs", function(done) { - for (let i = 0; i < this.fetched_docs.length; i++) { - const doc = this.fetched_docs[i]; - doc.lines.should.deep.equal(this.docs[i].lines); - } - return done(); - }); - - return it("should restore the docs to mongo", function(done) { - const jobs = Array.from(this.docs).map((doc, i) => - ((doc, i) => { - return callback => { - return db.docs.findOne({_id: doc._id}, (error, doc) => { - doc.lines.should.deep.equal(this.docs[i].lines); - doc.ranges.should.deep.equal(this.docs[i].ranges); - should.not.exist(doc.inS3); - return callback(); - }); - }; - })(doc, i)); - return async.series(jobs, done); - }); - }); - }); - - describe("a deleted doc", function() { - before(function(done) { - this.project_id = ObjectId(); - this.doc = { - _id: ObjectId(), - lines: ["one", "two", "three"], - ranges: {}, - version: 2 - }; - return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { - if (error != null) { throw error; } - return DocstoreClient.deleteDoc(this.project_id, this.doc._id, error => { - if (error != null) { throw error; } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res; - if (error != null) { throw error; } - return done(); - }); - }); - }); - }); - - it("should successully archive the docs", function(done) { - this.res.statusCode.should.equal(204); - return done(); - }); + it('should return the docs', function(done) { + for (let i = 0; i < this.fetched_docs.length; i++) { + const doc = this.fetched_docs[i] + doc.lines.should.deep.equal(this.docs[i].lines) + } + return done() + }) - it("should set inS3 and unset lines and ranges in each doc", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - should.not.exist(doc.lines); - should.not.exist(doc.ranges); - doc.inS3.should.equal(true); - doc.deleted.should.equal(true); - return done(); - }); - }); - - it("should set the doc in s3 correctly", function(done) { - return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { - if (error != null) { throw error; } - s3_doc.lines.should.deep.equal(this.doc.lines); - s3_doc.ranges.should.deep.equal(this.doc.ranges); - return done(); - }); - }); - - return describe("after unarchiving from a request for the project", function() { - before(function(done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs; - if (error != null) { throw error; } - return done(); - }); - }); - - it("should not included the deleted", function(done) { - this.fetched_docs.length.should.equal(0); - return done(); - }); - - return it("should restore the doc to mongo", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - doc.lines.should.deep.equal(this.doc.lines); - doc.ranges.should.deep.equal(this.doc.ranges); - should.not.exist(doc.inS3); - doc.deleted.should.equal(true); - return done(); - }); - }); - }); - }); - - describe("a doc with large lines", function() { - before(function(done) { - this.project_id = ObjectId(); - this.timeout(1000 * 30); - const quarterMegInBytes = 250000; - const big_line = require("crypto").randomBytes(quarterMegInBytes).toString("hex"); - this.doc = { - _id: ObjectId(), - lines: [big_line, big_line, big_line, big_line], - ranges: {}, - version: 2 - }; - return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { - if (error != null) { throw error; } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res; - if (error != null) { throw error; } - return done(); - }); - }); - }); - - it("should successully archive the docs", function(done) { - this.res.statusCode.should.equal(204); - return done(); - }); + return it('should restore the docs to mongo', function(done) { + const jobs = Array.from(this.docs).map((doc, i) => + ((doc, i) => { + return callback => { + return db.docs.findOne({ _id: doc._id }, (error, doc) => { + doc.lines.should.deep.equal(this.docs[i].lines) + doc.ranges.should.deep.equal(this.docs[i].ranges) + should.not.exist(doc.inS3) + return callback() + }) + } + })(doc, i) + ) + return async.series(jobs, done) + }) + }) + }) - it("should set inS3 and unset lines and ranges in each doc", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - should.not.exist(doc.lines); - should.not.exist(doc.ranges); - doc.inS3.should.equal(true); - return done(); - }); - }); + describe('a deleted doc', function() { + before(function(done) { + this.project_id = ObjectId() + this.doc = { + _id: ObjectId(), + lines: ['one', 'two', 'three'], + ranges: {}, + version: 2 + } + return DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + error => { + if (error != null) { + throw error + } + return DocstoreClient.deleteDoc( + this.project_id, + this.doc._id, + error => { + if (error != null) { + throw error + } + return DocstoreClient.archiveAllDoc( + this.project_id, + (error, res) => { + this.res = res + if (error != null) { + throw error + } + return done() + } + ) + } + ) + } + ) + }) - it("should set the doc in s3 correctly", function(done) { - return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { - if (error != null) { throw error; } - s3_doc.lines.should.deep.equal(this.doc.lines); - s3_doc.ranges.should.deep.equal(this.doc.ranges); - return done(); - }); - }); - - return describe("after unarchiving from a request for the project", function() { - before(function(done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs; - if (error != null) { throw error; } - return done(); - }); - }); - - return it("should restore the doc to mongo", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - doc.lines.should.deep.equal(this.doc.lines); - doc.ranges.should.deep.equal(this.doc.ranges); - should.not.exist(doc.inS3); - return done(); - }); - }); - }); - }); - - describe("a doc with naughty strings", function() { - before(function(done) { - this.project_id = ObjectId(); - this.doc = { - _id: ObjectId(), - lines: [ "", "undefined", "undef", "null", "NULL", "(null)", "nil", "NIL", "true", "false", "True", "False", "None", "\\", "\\\\", "0", "1", "1.00", "$1.00", "1/2", "1E2", "1E02", "1E+02", "-1", "-1.00", "-$1.00", "-1/2", "-1E2", "-1E02", "-1E+02", "1/0", "0/0", "-2147483648/-1", "-9223372036854775808/-1", "0.00", "0..0", ".", "0.0.0", "0,00", "0,,0", ",", "0,0,0", "0.0/0", "1.0/0.0", "0.0/0.0", "1,0/0,0", "0,0/0,0", "--1", "-", "-.", "-,", "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", "NaN", "Infinity", "-Infinity", "0x0", "0xffffffff", "0xffffffffffffffff", "0xabad1dea", "123456789012345678901234567890123456789", "1,000.00", "1 000.00", "1'000.00", "1,000,000.00", "1 000 000.00", "1'000'000.00", "1.000,00", "1 000,00", "1'000,00", "1.000.000,00", "1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟", "̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕", "Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮", "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", "00˙Ɩ$-", "The quick brown fox jumps over the lazy dog", "𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠", "𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌", "𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈", "𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰", "𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘", "𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐", "⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢", "<script>alert(123)</script>", "<script>alert('123');</script>", "<img src=x onerror=alert(123) />", "<svg><script>123<1>alert(123)</script> ", "\"><script>alert(123)</script>", "'><script>alert(123)</script>", "><script>alert(123)</script>", "</script><script>alert(123)</script>", "< / script >< script >alert(123)< / script >", " onfocus=JaVaSCript:alert(123) autofocus ", "\" onfocus=JaVaSCript:alert(123) autofocus ", "' onfocus=JaVaSCript:alert(123) autofocus ", "<script>alert(123)</script>", "<sc<script>ript>alert(123)</sc</script>ript>", "--><script>alert(123)</script>", "\";alert(123);t=\"", "';alert(123);t='", "JavaSCript:alert(123)", ";alert(123);", "src=JaVaSCript:prompt(132)", "\"><script>alert(123);</script x=\"", "'><script>alert(123);</script x='", "><script>alert(123);</script x=", "\" autofocus onkeyup=\"javascript:alert(123)", "' autofocus onkeyup='javascript:alert(123)", "<script\\x20type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x3Etype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Dtype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x09type=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Ctype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x2Ftype=\"text/javascript\">javascript:alert(1);</script>", "<script\\x0Atype=\"text/javascript\">javascript:alert(1);</script>", "'`\"><\\x3Cscript>javascript:alert(1)</script> ", "'`\"><\\x00script>javascript:alert(1)</script>", "ABC<div style=\"x\\x3Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x5C(javascript:alert(1)\">DEF", "ABC<div style=\"x:expression\\x00(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x00ression(javascript:alert(1)\">DEF", "ABC<div style=\"x:exp\\x5Cression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x09expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE3\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x84expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xC2\\xA0expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x80expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Dexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Cexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x87expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x20expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x88expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x00expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x86expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x85expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x82expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\x0Bexpression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x81expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x83expression(javascript:alert(1)\">DEF", "ABC<div style=\"x:\\xE2\\x80\\x89expression(javascript:alert(1)\">DEF", "<a href=\"\\x0Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xC2\\xA0javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x05javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x18javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x11javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x88javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x89javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x17javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x03javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x00javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x10javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x82javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x20javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x13javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x09javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x8Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x14javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x19javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xAFjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x81javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x87javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x07javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE1\\x9A\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x83javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x04javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x01javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x08javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x84javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x86javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE3\\x80\\x80javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x12javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Djavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Ajavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x0Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x15javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA8javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x16javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x02javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Bjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x06javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\xA9javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x80\\x85javascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Ejavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\xE2\\x81\\x9Fjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"\\x1Cjavascript:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x00:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x3A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x09:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0D:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "<a href=\"javascript\\x0A:javascript:alert(1)\" id=\"fuzzelement1\">test</a>", "`\"'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x22onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Donerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x09onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x0Conerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x00onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x27onerror=javascript:alert(1)>", "`\"'><img src=xxx:x \\x20onerror=javascript:alert(1)>", "\"`'><script>\\x3Bjavascript:alert(1)</script>", "\"`'><script>\\x0Djavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x81javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x84javascript:alert(1)</script>", "\"`'><script>\\xE3\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x09javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x89javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x85javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x88javascript:alert(1)</script>", "\"`'><script>\\x00javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>", "\"`'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>", "\"`'><script>\\x0Cjavascript:alert(1)</script>", "\"`'><script>\\x2Bjavascript:alert(1)</script>", "\"`'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>", "\"`'><script>-javascript:alert(1)</script>", "\"`'><script>\\x0Ajavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>", "\"`'><script>\\x7Ejavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x87javascript:alert(1)</script>", "\"`'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>", "\"`'><script>\\xC2\\x85javascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x83javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>", "\"`'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x80javascript:alert(1)</script>", "\"`'><script>\\x21javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x82javascript:alert(1)</script>", "\"`'><script>\\xE2\\x80\\x86javascript:alert(1)</script>", "\"`'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>", "\"`'><script>\\x0Bjavascript:alert(1)</script>", "\"`'><script>\\x20javascript:alert(1)</script>", "\"`'><script>\\xC2\\xA0javascript:alert(1)</script>", "<img \\x00src=x onerror=\"alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x12src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x10src=x onerror=\"javascript:alert(1)\">", "<img\\x13src=x onerror=\"javascript:alert(1)\">", "<img\\x32src=x onerror=\"javascript:alert(1)\">", "<img\\x47src=x onerror=\"javascript:alert(1)\">", "<img\\x11src=x onerror=\"javascript:alert(1)\">", "<img \\x47src=x onerror=\"javascript:alert(1)\">", "<img \\x34src=x onerror=\"javascript:alert(1)\">", "<img \\x39src=x onerror=\"javascript:alert(1)\">", "<img \\x00src=x onerror=\"javascript:alert(1)\">", "<img src\\x09=x onerror=\"javascript:alert(1)\">", "<img src\\x10=x onerror=\"javascript:alert(1)\">", "<img src\\x13=x onerror=\"javascript:alert(1)\">", "<img src\\x32=x onerror=\"javascript:alert(1)\">", "<img src\\x12=x onerror=\"javascript:alert(1)\">", "<img src\\x11=x onerror=\"javascript:alert(1)\">", "<img src\\x00=x onerror=\"javascript:alert(1)\">", "<img src\\x47=x onerror=\"javascript:alert(1)\">", "<img src=x\\x09onerror=\"javascript:alert(1)\">", "<img src=x\\x10onerror=\"javascript:alert(1)\">", "<img src=x\\x11onerror=\"javascript:alert(1)\">", "<img src=x\\x12onerror=\"javascript:alert(1)\">", "<img src=x\\x13onerror=\"javascript:alert(1)\">", "<img[a][b][c]src[d]=x[e]onerror=[f]\"alert(1)\">", "<img src=x onerror=\\x09\"javascript:alert(1)\">", "<img src=x onerror=\\x10\"javascript:alert(1)\">", "<img src=x onerror=\\x11\"javascript:alert(1)\">", "<img src=x onerror=\\x12\"javascript:alert(1)\">", "<img src=x onerror=\\x32\"javascript:alert(1)\">", "<img src=x onerror=\\x00\"javascript:alert(1)\">", "<a href=java script:javascript:alert(1)>XXX</a>", "<img src=\"x` `<script>javascript:alert(1)</script>\"` `>", "<img src onerror /\" '\"= alt=javascript:alert(1)//\">", "<title onpropertychange=javascript:alert(1)>", "<a href=http://foo.bar/#x=`y></a><img alt=\"`><img src=x:x onerror=javascript:alert(1)></a>\">", "<!--[if]><script>javascript:alert(1)</script -->", "<!--[if<img src=x onerror=javascript:alert(1)//]> -->", "<script src=\"/\\%(jscript)s\"></script>", "<script src=\"\\\\%(jscript)s\"></script>", "<IMG \"\"\"><SCRIPT>alert(\"XSS\")</SCRIPT>\">", "<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>", "<IMG SRC=# onmouseover=\"alert('xxs')\">", "<IMG SRC= onmouseover=\"alert('xxs')\">", "<IMG onmouseover=\"alert('xxs')\">", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=javascript:alert('XSS')>", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "<IMG SRC=\"jav ascript:alert('XSS');\">", "perl -e 'print \"<IMG SRC=java\\0script:alert(\\\"XSS\\\")>\";' > out", "<IMG SRC=\"  javascript:alert('XSS');\">", "<SCRIPT/XSS SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert(\"XSS\")>", "<SCRIPT/SRC=\"http://ha.ckers.org/xss.js\"></SCRIPT>", "<<SCRIPT>alert(\"XSS\");//<</SCRIPT>", "<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >", "<SCRIPT SRC=//ha.ckers.org/.j>", "<IMG SRC=\"javascript:alert('XSS')\"", "<iframe src=http://ha.ckers.org/scriptlet.html <", "\\\";alert('XSS');//", "<plaintext>", "1;DROP TABLE users", "1'; DROP TABLE users-- 1", "' OR 1=1 -- 1", "' OR '1'='1", "-", "--", "--version", "--help", "$USER", "/dev/null; touch /tmp/blns.fail ; echo", "`touch /tmp/blns.fail`", "$(touch /tmp/blns.fail)", "@{[system \"touch /tmp/blns.fail\"]}", "eval(\"puts 'hello world'\")", "System(\"ls -al /\")", "`ls -al /`", "Kernel.exec(\"ls -al /\")", "Kernel.exit(1)", "%x('ls -al /')", "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM \"file:///etc/passwd\" >]><foo>&xxe;</foo>", "$HOME", "$ENV{'HOME'}", "%d", "%s", "%*.*s", "../../../../../../../../../../../etc/passwd%00", "../../../../../../../../../../../etc/hosts", "() { 0; }; touch /tmp/blns.shellshock1.fail;", "() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }", "CON", "PRN", "AUX", "CLOCK$", "NUL", "A:", "ZZ:", "COM1", "LPT1", "LPT2", "LPT3", "COM2", "COM3", "COM4", "Scunthorpe General Hospital", "Penistone Community Church", "Lightwater Country Park", "Jimmy Clitheroe", "Horniman Museum", "shitake mushrooms", "RomansInSussex.co.uk", "http://www.cum.qc.ca/", "Craig Cockburn, Software Specialist", "Linda Callahan", "Dr. Herman I. Libshitz", "magna cum laude", "Super Bowl XXX", "medieval erection of parapets", "evaluate", "mocha", "expression", "Arsenal canal", "classic", "Tyson Gay", "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", "Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue", "But now...\u001b[20Cfor my greatest trick...\u001b[8m", "The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]", "Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗" ], - ranges: {}, - version: 2 - }; - return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { - if (error != null) { throw error; } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res; - if (error != null) { throw error; } - return done(); - }); - }); - }); - - it("should successully archive the docs", function(done) { - this.res.statusCode.should.equal(204); - return done(); - }); + it('should successully archive the docs', function(done) { + this.res.statusCode.should.equal(204) + return done() + }) - it("should set inS3 and unset lines and ranges in each doc", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - should.not.exist(doc.lines); - should.not.exist(doc.ranges); - doc.inS3.should.equal(true); - return done(); - }); - }); + it('should set inS3 and unset lines and ranges in each doc', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + should.not.exist(doc.lines) + should.not.exist(doc.ranges) + doc.inS3.should.equal(true) + doc.deleted.should.equal(true) + return done() + }) + }) - it("should set the doc in s3 correctly", function(done) { - return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { - if (error != null) { throw error; } - s3_doc.lines.should.deep.equal(this.doc.lines); - s3_doc.ranges.should.deep.equal(this.doc.ranges); - return done(); - }); - }); - - return describe("after unarchiving from a request for the project", function() { - before(function(done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs; - if (error != null) { throw error; } - return done(); - }); - }); - - return it("should restore the doc to mongo", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - doc.lines.should.deep.equal(this.doc.lines); - doc.ranges.should.deep.equal(this.doc.ranges); - should.not.exist(doc.inS3); - return done(); - }); - }); - }); - }); + it('should set the doc in s3 correctly', function(done) { + return DocstoreClient.getS3Doc( + this.project_id, + this.doc._id, + (error, res, s3_doc) => { + if (error != null) { + throw error + } + s3_doc.lines.should.deep.equal(this.doc.lines) + s3_doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) - describe("a doc with ranges", function() { - before(function(done) { - this.project_id = ObjectId(); - this.doc = { - _id: ObjectId(), - lines: ["one", "two", "three"], - ranges: { - changes: - [{ - id : ObjectId(), - op : { "i" : "foo", "p" : 24 }, - metadata : { "user_id" : ObjectId(), "ts" : new Date("2017-01-27T16:10:44.194Z") } - }, { - id : ObjectId(), - op : { "d" : "bar", "p" : 50 }, - metadata : { "user_id" : ObjectId(), "ts" : new Date("2017-01-27T18:10:44.194Z") } - }], - comments: [{ - id: ObjectId(), - op: { "c" : "comment", "p" : 284, "t" : ObjectId() }, - metadata: { "user_id" : ObjectId(), "ts" : new Date("2017-01-26T14:22:04.869Z") } - }] - }, - version: 2 - }; - return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { - if (error != null) { throw error; } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res; - if (error != null) { throw error; } - return done(); - }); - }); - }); - - it("should successully archive the docs", function(done) { - this.res.statusCode.should.equal(204); - return done(); - }); + return describe('after unarchiving from a request for the project', function() { + before(function(done) { + return DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + }) - it("should set inS3 and unset lines and ranges in each doc", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - should.not.exist(doc.lines); - should.not.exist(doc.ranges); - doc.inS3.should.equal(true); - return done(); - }); - }); + it('should not included the deleted', function(done) { + this.fetched_docs.length.should.equal(0) + return done() + }) - it("should set the doc in s3 correctly", function(done) { - return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { - if (error != null) { throw error; } - s3_doc.lines.should.deep.equal(this.doc.lines); - const ranges = JSON.parse(JSON.stringify(this.doc.ranges)); // ObjectId -> String - s3_doc.ranges.should.deep.equal(ranges); - return done(); - }); - }); - - return describe("after unarchiving from a request for the project", function() { - before(function(done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs; - if (error != null) { throw error; } - return done(); - }); - }); - - return it("should restore the doc to mongo", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - doc.lines.should.deep.equal(this.doc.lines); - doc.ranges.should.deep.equal(this.doc.ranges); - should.not.exist(doc.inS3); - return done(); - }); - }); - }); - }); + return it('should restore the doc to mongo', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + should.not.exist(doc.inS3) + doc.deleted.should.equal(true) + return done() + }) + }) + }) + }) - describe("a doc that is archived twice", function() { - before(function(done) { - this.project_id = ObjectId(); - this.doc = { - _id: ObjectId(), - lines: ["abc", "def", "ghi"], - ranges: {}, - version: 2 - }; - return DocstoreClient.createDoc(this.project_id, this.doc._id, this.doc.lines, this.doc.version, this.doc.ranges, error => { - if (error != null) { throw error; } - return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { - this.res = res; - if (error != null) { throw error; } - this.res.statusCode.should.equal(204); - return DocstoreClient.archiveAllDoc(this.project_id, (error, res1) => { - this.res = res1; - if (error != null) { throw error; } - this.res.statusCode.should.equal(204); - return done(); - }); - }); - }); - }); + describe('a doc with large lines', function() { + before(function(done) { + this.project_id = ObjectId() + this.timeout(1000 * 30) + const quarterMegInBytes = 250000 + const big_line = require('crypto') + .randomBytes(quarterMegInBytes) + .toString('hex') + this.doc = { + _id: ObjectId(), + lines: [big_line, big_line, big_line, big_line], + ranges: {}, + version: 2 + } + return DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + error => { + if (error != null) { + throw error + } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res + if (error != null) { + throw error + } + return done() + }) + } + ) + }) - it("should set inS3 and unset lines and ranges in each doc", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - should.not.exist(doc.lines); - should.not.exist(doc.ranges); - doc.inS3.should.equal(true); - return done(); - }); - }); + it('should successully archive the docs', function(done) { + this.res.statusCode.should.equal(204) + return done() + }) - it("should set the doc in s3 correctly", function(done) { - return DocstoreClient.getS3Doc(this.project_id, this.doc._id, (error, res, s3_doc) => { - if (error != null) { throw error; } - s3_doc.lines.should.deep.equal(this.doc.lines); - s3_doc.ranges.should.deep.equal(this.doc.ranges); - return done(); - }); - }); - - return describe("after unarchiving from a request for the project", function() { - before(function(done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs; - if (error != null) { throw error; } - return done(); - }); - }); - - return it("should restore the doc to mongo", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - doc.lines.should.deep.equal(this.doc.lines); - doc.ranges.should.deep.equal(this.doc.ranges); - should.not.exist(doc.inS3); - return done(); - }); - }); - }); - }); + it('should set inS3 and unset lines and ranges in each doc', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + should.not.exist(doc.lines) + should.not.exist(doc.ranges) + doc.inS3.should.equal(true) + return done() + }) + }) - return describe("a doc with the old schema (just an array of lines)", function() { - before(function(done) { - this.project_id = ObjectId(); - this.doc = { - _id: ObjectId(), - lines: ["abc", "def", "ghi"], - ranges: {}, - version: 2 - }; - const options = DocArchiveManager.buildS3Options(`${this.project_id}/${this.doc._id}`); - options.json = this.doc.lines; - return request.put(options, (error, res, body) => { - if (error != null) { throw error; } - res.statusCode.should.equal(200); - return db.docs.insert({ - project_id: this.project_id, - _id: this.doc._id, - rev: this.doc.version, - inS3: true - }, error => { - if (error != null) { throw error; } - return DocstoreClient.getAllDocs(this.project_id, (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs; - if (error != null) { throw error; } - return done(); - }); - }); - }); - }); + it('should set the doc in s3 correctly', function(done) { + return DocstoreClient.getS3Doc( + this.project_id, + this.doc._id, + (error, res, s3_doc) => { + if (error != null) { + throw error + } + s3_doc.lines.should.deep.equal(this.doc.lines) + s3_doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) - it("should restore the doc to mongo", function(done) { - return db.docs.findOne({_id: this.doc._id}, (error, doc) => { - if (error != null) { throw error; } - doc.lines.should.deep.equal(this.doc.lines); - should.not.exist(doc.inS3); - return done(); - }); - }); - - return it("should return the doc", function(done) { - this.fetched_docs[0].lines.should.deep.equal(this.doc.lines); - return done(); - }); - }); -}); + return describe('after unarchiving from a request for the project', function() { + before(function(done) { + return DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + }) + return it('should restore the doc to mongo', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + should.not.exist(doc.inS3) + return done() + }) + }) + }) + }) + + describe('a doc with naughty strings', function() { + before(function(done) { + this.project_id = ObjectId() + this.doc = { + _id: ObjectId(), + lines: [ + '', + 'undefined', + 'undef', + 'null', + 'NULL', + '(null)', + 'nil', + 'NIL', + 'true', + 'false', + 'True', + 'False', + 'None', + '\\', + '\\\\', + '0', + '1', + '1.00', + '$1.00', + '1/2', + '1E2', + '1E02', + '1E+02', + '-1', + '-1.00', + '-$1.00', + '-1/2', + '-1E2', + '-1E02', + '-1E+02', + '1/0', + '0/0', + '-2147483648/-1', + '-9223372036854775808/-1', + '0.00', + '0..0', + '.', + '0.0.0', + '0,00', + '0,,0', + ',', + '0,0,0', + '0.0/0', + '1.0/0.0', + '0.0/0.0', + '1,0/0,0', + '0,0/0,0', + '--1', + '-', + '-.', + '-,', + '999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999', + 'NaN', + 'Infinity', + '-Infinity', + '0x0', + '0xffffffff', + '0xffffffffffffffff', + '0xabad1dea', + '123456789012345678901234567890123456789', + '1,000.00', + '1 000.00', + "1'000.00", + '1,000,000.00', + '1 000 000.00', + "1'000'000.00", + '1.000,00', + '1 000,00', + "1'000,00", + '1.000.000,00', + '1 000i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟', + '̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕', + 'Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮', + "˙ɐnbᴉlɐ ɐuƃɐɯ ǝɹolop ʇǝ ǝɹoqɐl ʇn ʇunpᴉpᴉɔuᴉ ɹodɯǝʇ poɯsnᴉǝ op pǝs 'ʇᴉlǝ ƃuᴉɔsᴉdᴉpɐ ɹnʇǝʇɔǝsuoɔ 'ʇǝɯɐ ʇᴉs ɹolop ɯnsdᴉ ɯǝɹo˥", + '00˙Ɩ$-', + 'The quick brown fox jumps over the lazy dog', + '𝐓𝐡𝐞 𝐪𝐮𝐢𝐜𝐤 𝐛𝐫𝐨𝐰𝐧 𝐟𝐨𝐱 𝐣𝐮𝐦𝐩𝐬 𝐨𝐯𝐞𝐫 𝐭𝐡𝐞 𝐥𝐚𝐳𝐲 𝐝𝐨𝐠', + '𝕿𝖍𝖊 𝖖𝖚𝖎𝖈𝖐 𝖇𝖗𝖔𝖜𝖓 𝖋𝖔𝖝 𝖏𝖚𝖒𝖕𝖘 𝖔𝖛𝖊𝖗 𝖙𝖍𝖊 𝖑𝖆𝖟𝖞 𝖉𝖔𝖌', + '𝑻𝒉𝒆 𝒒𝒖𝒊𝒄𝒌 𝒃𝒓𝒐𝒘𝒏 𝒇𝒐𝒙 𝒋𝒖𝒎𝒑𝒔 𝒐𝒗𝒆𝒓 𝒕𝒉𝒆 𝒍𝒂𝒛𝒚 𝒅𝒐𝒈', + '𝓣𝓱𝓮 𝓺𝓾𝓲𝓬𝓴 𝓫𝓻𝓸𝔀𝓷 𝓯𝓸𝔁 𝓳𝓾𝓶𝓹𝓼 𝓸𝓿𝓮𝓻 𝓽𝓱𝓮 𝓵𝓪𝔃𝔂 𝓭𝓸𝓰', + '𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘', + '𝚃𝚑𝚎 𝚚𝚞𝚒𝚌𝚔 𝚋𝚛𝚘𝚠𝚗 𝚏𝚘𝚡 𝚓𝚞𝚖𝚙𝚜 𝚘𝚟𝚎𝚛 𝚝𝚑𝚎 𝚕𝚊𝚣𝚢 𝚍𝚘𝚐', + '⒯⒣⒠ ⒬⒰⒤⒞⒦ ⒝⒭⒪⒲⒩ ⒡⒪⒳ ⒥⒰⒨⒫⒮ ⒪⒱⒠⒭ ⒯⒣⒠ ⒧⒜⒵⒴ ⒟⒪⒢', + '<script>alert(123)</script>', + '<script>alert('123');</script>', + '<img src=x onerror=alert(123) />', + '<svg><script>123<1>alert(123)</script> ', + '"><script>alert(123)</script>', + "'><script>alert(123)</script>", + '><script>alert(123)</script>', + '</script><script>alert(123)</script>', + '< / script >< script >alert(123)< / script >', + ' onfocus=JaVaSCript:alert(123) autofocus ', + '" onfocus=JaVaSCript:alert(123) autofocus ', + "' onfocus=JaVaSCript:alert(123) autofocus ", + '<script>alert(123)</script>', + '<sc<script>ript>alert(123)</sc</script>ript>', + '--><script>alert(123)</script>', + '";alert(123);t="', + "';alert(123);t='", + 'JavaSCript:alert(123)', + ';alert(123);', + 'src=JaVaSCript:prompt(132)', + '"><script>alert(123);</script x="', + "'><script>alert(123);</script x='", + '><script>alert(123);</script x=', + '" autofocus onkeyup="javascript:alert(123)', + "' autofocus onkeyup='javascript:alert(123)", + '<script\\x20type="text/javascript">javascript:alert(1);</script>', + '<script\\x3Etype="text/javascript">javascript:alert(1);</script>', + '<script\\x0Dtype="text/javascript">javascript:alert(1);</script>', + '<script\\x09type="text/javascript">javascript:alert(1);</script>', + '<script\\x0Ctype="text/javascript">javascript:alert(1);</script>', + '<script\\x2Ftype="text/javascript">javascript:alert(1);</script>', + '<script\\x0Atype="text/javascript">javascript:alert(1);</script>', + '\'`"><\\x3Cscript>javascript:alert(1)</script> ', + '\'`"><\\x00script>javascript:alert(1)</script>', + 'ABC<div style="x\\x3Aexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:expression\\x5C(javascript:alert(1)">DEF', + 'ABC<div style="x:expression\\x00(javascript:alert(1)">DEF', + 'ABC<div style="x:exp\\x00ression(javascript:alert(1)">DEF', + 'ABC<div style="x:exp\\x5Cression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\x0Aexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\x09expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE3\\x80\\x80expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x84expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xC2\\xA0expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x80expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x8Aexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\x0Dexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\x0Cexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x87expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xEF\\xBB\\xBFexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\x20expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x88expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\x00expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x8Bexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x86expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x85expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x82expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\x0Bexpression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x81expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x83expression(javascript:alert(1)">DEF', + 'ABC<div style="x:\\xE2\\x80\\x89expression(javascript:alert(1)">DEF', + '<a href="\\x0Bjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x0Fjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xC2\\xA0javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x05javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE1\\xA0\\x8Ejavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x18javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x11javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x88javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x89javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x80javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x17javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x03javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x0Ejavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x1Ajavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x00javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x10javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x82javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x20javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x13javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x09javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x8Ajavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x14javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x19javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\xAFjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x1Fjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x81javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x1Djavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x87javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x07javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE1\\x9A\\x80javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x83javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x04javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x01javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x08javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x84javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x86javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE3\\x80\\x80javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x12javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x0Djavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x0Ajavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x0Cjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x15javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\xA8javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x16javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x02javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x1Bjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x06javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\xA9javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x80\\x85javascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x1Ejavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\xE2\\x81\\x9Fjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="\\x1Cjavascript:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="javascript\\x00:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="javascript\\x3A:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="javascript\\x09:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="javascript\\x0D:javascript:alert(1)" id="fuzzelement1">test</a>', + '<a href="javascript\\x0A:javascript:alert(1)" id="fuzzelement1">test</a>', + '`"\'><img src=xxx:x \\x0Aonerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x22onerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x0Bonerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x0Donerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x2Fonerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x09onerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x0Conerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x00onerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x27onerror=javascript:alert(1)>', + '`"\'><img src=xxx:x \\x20onerror=javascript:alert(1)>', + '"`\'><script>\\x3Bjavascript:alert(1)</script>', + '"`\'><script>\\x0Djavascript:alert(1)</script>', + '"`\'><script>\\xEF\\xBB\\xBFjavascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x81javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x84javascript:alert(1)</script>', + '"`\'><script>\\xE3\\x80\\x80javascript:alert(1)</script>', + '"`\'><script>\\x09javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x89javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x85javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x88javascript:alert(1)</script>', + '"`\'><script>\\x00javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\xA8javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x8Ajavascript:alert(1)</script>', + '"`\'><script>\\xE1\\x9A\\x80javascript:alert(1)</script>', + '"`\'><script>\\x0Cjavascript:alert(1)</script>', + '"`\'><script>\\x2Bjavascript:alert(1)</script>', + '"`\'><script>\\xF0\\x90\\x96\\x9Ajavascript:alert(1)</script>', + '"`\'><script>-javascript:alert(1)</script>', + '"`\'><script>\\x0Ajavascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\xAFjavascript:alert(1)</script>', + '"`\'><script>\\x7Ejavascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x87javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x81\\x9Fjavascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\xA9javascript:alert(1)</script>', + '"`\'><script>\\xC2\\x85javascript:alert(1)</script>', + '"`\'><script>\\xEF\\xBF\\xAEjavascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x83javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x8Bjavascript:alert(1)</script>', + '"`\'><script>\\xEF\\xBF\\xBEjavascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x80javascript:alert(1)</script>', + '"`\'><script>\\x21javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x82javascript:alert(1)</script>', + '"`\'><script>\\xE2\\x80\\x86javascript:alert(1)</script>', + '"`\'><script>\\xE1\\xA0\\x8Ejavascript:alert(1)</script>', + '"`\'><script>\\x0Bjavascript:alert(1)</script>', + '"`\'><script>\\x20javascript:alert(1)</script>', + '"`\'><script>\\xC2\\xA0javascript:alert(1)</script>', + '<img \\x00src=x onerror="alert(1)">', + '<img \\x47src=x onerror="javascript:alert(1)">', + '<img \\x11src=x onerror="javascript:alert(1)">', + '<img \\x12src=x onerror="javascript:alert(1)">', + '<img\\x47src=x onerror="javascript:alert(1)">', + '<img\\x10src=x onerror="javascript:alert(1)">', + '<img\\x13src=x onerror="javascript:alert(1)">', + '<img\\x32src=x onerror="javascript:alert(1)">', + '<img\\x47src=x onerror="javascript:alert(1)">', + '<img\\x11src=x onerror="javascript:alert(1)">', + '<img \\x47src=x onerror="javascript:alert(1)">', + '<img \\x34src=x onerror="javascript:alert(1)">', + '<img \\x39src=x onerror="javascript:alert(1)">', + '<img \\x00src=x onerror="javascript:alert(1)">', + '<img src\\x09=x onerror="javascript:alert(1)">', + '<img src\\x10=x onerror="javascript:alert(1)">', + '<img src\\x13=x onerror="javascript:alert(1)">', + '<img src\\x32=x onerror="javascript:alert(1)">', + '<img src\\x12=x onerror="javascript:alert(1)">', + '<img src\\x11=x onerror="javascript:alert(1)">', + '<img src\\x00=x onerror="javascript:alert(1)">', + '<img src\\x47=x onerror="javascript:alert(1)">', + '<img src=x\\x09onerror="javascript:alert(1)">', + '<img src=x\\x10onerror="javascript:alert(1)">', + '<img src=x\\x11onerror="javascript:alert(1)">', + '<img src=x\\x12onerror="javascript:alert(1)">', + '<img src=x\\x13onerror="javascript:alert(1)">', + '<img[a][b][c]src[d]=x[e]onerror=[f]"alert(1)">', + '<img src=x onerror=\\x09"javascript:alert(1)">', + '<img src=x onerror=\\x10"javascript:alert(1)">', + '<img src=x onerror=\\x11"javascript:alert(1)">', + '<img src=x onerror=\\x12"javascript:alert(1)">', + '<img src=x onerror=\\x32"javascript:alert(1)">', + '<img src=x onerror=\\x00"javascript:alert(1)">', + '<a href=java script:javascript:alert(1)>XXX</a>', + '<img src="x` `<script>javascript:alert(1)</script>"` `>', + '<img src onerror /" \'"= alt=javascript:alert(1)//">', + '<title onpropertychange=javascript:alert(1)>', + '<a href=http://foo.bar/#x=`y></a><img alt="`><img src=x:x onerror=javascript:alert(1)></a>">', + '<!--[if]><script>javascript:alert(1)</script -->', + '<!--[if<img src=x onerror=javascript:alert(1)//]> -->', + '<script src="/\\%(jscript)s"></script>', + '<script src="\\\\%(jscript)s"></script>', + '<IMG """><SCRIPT>alert("XSS")</SCRIPT>">', + '<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>', + '<IMG SRC=# onmouseover="alert(\'xxs\')">', + '<IMG SRC= onmouseover="alert(\'xxs\')">', + '<IMG onmouseover="alert(\'xxs\')">', + '<IMG SRC=javascript:alert('XSS')>', + '<IMG SRC=javascript:alert('XSS')>', + '<IMG SRC=javascript:alert('XSS')>', + '<IMG SRC="jav ascript:alert(\'XSS\');">', + '<IMG SRC="jav ascript:alert(\'XSS\');">', + '<IMG SRC="jav ascript:alert(\'XSS\');">', + '<IMG SRC="jav ascript:alert(\'XSS\');">', + 'perl -e \'print "<IMG SRC=java\\0script:alert(\\"XSS\\")>";\' > out', + '<IMG SRC="  javascript:alert(\'XSS\');">', + '<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + '<BODY onload!#$%&()*~+-_.,:;?@[/|\\]^`=alert("XSS")>', + '<SCRIPT/SRC="http://ha.ckers.org/xss.js"></SCRIPT>', + '<<SCRIPT>alert("XSS");//<</SCRIPT>', + '<SCRIPT SRC=http://ha.ckers.org/xss.js?< B >', + '<SCRIPT SRC=//ha.ckers.org/.j>', + '<IMG SRC="javascript:alert(\'XSS\')"', + '<iframe src=http://ha.ckers.org/scriptlet.html <', + "\\\";alert('XSS');//", + '<plaintext>', + '1;DROP TABLE users', + "1'; DROP TABLE users-- 1", + "' OR 1=1 -- 1", + "' OR '1'='1", + '-', + '--', + '--version', + '--help', + '$USER', + '/dev/null; touch /tmp/blns.fail ; echo', + '`touch /tmp/blns.fail`', + '$(touch /tmp/blns.fail)', + '@{[system "touch /tmp/blns.fail"]}', + 'eval("puts \'hello world\'")', + 'System("ls -al /")', + '`ls -al /`', + 'Kernel.exec("ls -al /")', + 'Kernel.exit(1)', + "%x('ls -al /')", + '<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>', + '$HOME', + "$ENV{'HOME'}", + '%d', + '%s', + '%*.*s', + '../../../../../../../../../../../etc/passwd%00', + '../../../../../../../../../../../etc/hosts', + '() { 0; }; touch /tmp/blns.shellshock1.fail;', + '() { _; } >_[$($())] { touch /tmp/blns.shellshock2.fail; }', + 'CON', + 'PRN', + 'AUX', + 'CLOCK$', + 'NUL', + 'A:', + 'ZZ:', + 'COM1', + 'LPT1', + 'LPT2', + 'LPT3', + 'COM2', + 'COM3', + 'COM4', + 'Scunthorpe General Hospital', + 'Penistone Community Church', + 'Lightwater Country Park', + 'Jimmy Clitheroe', + 'Horniman Museum', + 'shitake mushrooms', + 'RomansInSussex.co.uk', + 'http://www.cum.qc.ca/', + 'Craig Cockburn, Software Specialist', + 'Linda Callahan', + 'Dr. Herman I. Libshitz', + 'magna cum laude', + 'Super Bowl XXX', + 'medieval erection of parapets', + 'evaluate', + 'mocha', + 'expression', + 'Arsenal canal', + 'classic', + 'Tyson Gay', + "If you're reading this, you've been in a coma for almost 20 years now. We're trying a new technique. We don't know where this message will end up in your dream, but we hope it works. Please wake up, we miss you.", + 'Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue', + 'But now...\u001b[20Cfor my greatest trick...\u001b[8m', + 'The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]', + 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗' + ], + ranges: {}, + version: 2 + } + return DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + error => { + if (error != null) { + throw error + } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res + if (error != null) { + throw error + } + return done() + }) + } + ) + }) + + it('should successully archive the docs', function(done) { + this.res.statusCode.should.equal(204) + return done() + }) + + it('should set inS3 and unset lines and ranges in each doc', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + should.not.exist(doc.lines) + should.not.exist(doc.ranges) + doc.inS3.should.equal(true) + return done() + }) + }) + + it('should set the doc in s3 correctly', function(done) { + return DocstoreClient.getS3Doc( + this.project_id, + this.doc._id, + (error, res, s3_doc) => { + if (error != null) { + throw error + } + s3_doc.lines.should.deep.equal(this.doc.lines) + s3_doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) + + return describe('after unarchiving from a request for the project', function() { + before(function(done) { + return DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + }) + + return it('should restore the doc to mongo', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + should.not.exist(doc.inS3) + return done() + }) + }) + }) + }) + + describe('a doc with ranges', function() { + before(function(done) { + this.project_id = ObjectId() + this.doc = { + _id: ObjectId(), + lines: ['one', 'two', 'three'], + ranges: { + changes: [ + { + id: ObjectId(), + op: { i: 'foo', p: 24 }, + metadata: { + user_id: ObjectId(), + ts: new Date('2017-01-27T16:10:44.194Z') + } + }, + { + id: ObjectId(), + op: { d: 'bar', p: 50 }, + metadata: { + user_id: ObjectId(), + ts: new Date('2017-01-27T18:10:44.194Z') + } + } + ], + comments: [ + { + id: ObjectId(), + op: { c: 'comment', p: 284, t: ObjectId() }, + metadata: { + user_id: ObjectId(), + ts: new Date('2017-01-26T14:22:04.869Z') + } + } + ] + }, + version: 2 + } + return DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + error => { + if (error != null) { + throw error + } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res + if (error != null) { + throw error + } + return done() + }) + } + ) + }) + + it('should successully archive the docs', function(done) { + this.res.statusCode.should.equal(204) + return done() + }) + + it('should set inS3 and unset lines and ranges in each doc', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + should.not.exist(doc.lines) + should.not.exist(doc.ranges) + doc.inS3.should.equal(true) + return done() + }) + }) + + it('should set the doc in s3 correctly', function(done) { + return DocstoreClient.getS3Doc( + this.project_id, + this.doc._id, + (error, res, s3_doc) => { + if (error != null) { + throw error + } + s3_doc.lines.should.deep.equal(this.doc.lines) + const ranges = JSON.parse(JSON.stringify(this.doc.ranges)) // ObjectId -> String + s3_doc.ranges.should.deep.equal(ranges) + return done() + } + ) + }) + + return describe('after unarchiving from a request for the project', function() { + before(function(done) { + return DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + }) + + return it('should restore the doc to mongo', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + should.not.exist(doc.inS3) + return done() + }) + }) + }) + }) + + describe('a doc that is archived twice', function() { + before(function(done) { + this.project_id = ObjectId() + this.doc = { + _id: ObjectId(), + lines: ['abc', 'def', 'ghi'], + ranges: {}, + version: 2 + } + return DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + error => { + if (error != null) { + throw error + } + return DocstoreClient.archiveAllDoc(this.project_id, (error, res) => { + this.res = res + if (error != null) { + throw error + } + this.res.statusCode.should.equal(204) + return DocstoreClient.archiveAllDoc( + this.project_id, + (error, res1) => { + this.res = res1 + if (error != null) { + throw error + } + this.res.statusCode.should.equal(204) + return done() + } + ) + }) + } + ) + }) + + it('should set inS3 and unset lines and ranges in each doc', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + should.not.exist(doc.lines) + should.not.exist(doc.ranges) + doc.inS3.should.equal(true) + return done() + }) + }) + + it('should set the doc in s3 correctly', function(done) { + return DocstoreClient.getS3Doc( + this.project_id, + this.doc._id, + (error, res, s3_doc) => { + if (error != null) { + throw error + } + s3_doc.lines.should.deep.equal(this.doc.lines) + s3_doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) + + return describe('after unarchiving from a request for the project', function() { + before(function(done) { + return DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + }) + + return it('should restore the doc to mongo', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + doc.lines.should.deep.equal(this.doc.lines) + doc.ranges.should.deep.equal(this.doc.ranges) + should.not.exist(doc.inS3) + return done() + }) + }) + }) + }) + + return describe('a doc with the old schema (just an array of lines)', function() { + before(function(done) { + this.project_id = ObjectId() + this.doc = { + _id: ObjectId(), + lines: ['abc', 'def', 'ghi'], + ranges: {}, + version: 2 + } + const options = DocArchiveManager.buildS3Options( + `${this.project_id}/${this.doc._id}` + ) + options.json = this.doc.lines + return request.put(options, (error, res, body) => { + if (error != null) { + throw error + } + res.statusCode.should.equal(200) + return db.docs.insert( + { + project_id: this.project_id, + _id: this.doc._id, + rev: this.doc.version, + inS3: true + }, + error => { + if (error != null) { + throw error + } + return DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + } + ) + }) + }) + + it('should restore the doc to mongo', function(done) { + return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error != null) { + throw error + } + doc.lines.should.deep.equal(this.doc.lines) + should.not.exist(doc.inS3) + return done() + }) + }) + + return it('should return the doc', function(done) { + this.fetched_docs[0].lines.should.deep.equal(this.doc.lines) + return done() + }) + }) +}) diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 026730205d..8941567359 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -11,119 +11,149 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const {db, ObjectId} = require("../../../app/js/mongojs"); -const { - expect -} = chai; -const DocstoreApp = require("./helpers/DocstoreApp"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { db, ObjectId } = require('../../../app/js/mongojs') +const { expect } = chai +const DocstoreApp = require('./helpers/DocstoreApp') -const DocstoreClient = require("./helpers/DocstoreClient"); +const DocstoreClient = require('./helpers/DocstoreClient') -describe("Deleting a doc", function() { - beforeEach(function(done) { - this.project_id = ObjectId(); - this.doc_id = ObjectId(); - this.lines = ["original", "lines"]; - this.version = 42; - this.ranges = []; - return DocstoreApp.ensureRunning(() => { - return DocstoreClient.createDoc(this.project_id, this.doc_id, this.lines, this.version, this.ranges, error => { - if (error != null) { throw error; } - return done(); - }); - }); - }); +describe('Deleting a doc', function() { + beforeEach(function(done) { + this.project_id = ObjectId() + this.doc_id = ObjectId() + this.lines = ['original', 'lines'] + this.version = 42 + this.ranges = [] + return DocstoreApp.ensureRunning(() => { + return DocstoreClient.createDoc( + this.project_id, + this.doc_id, + this.lines, + this.version, + this.ranges, + error => { + if (error != null) { + throw error + } + return done() + } + ) + }) + }) - describe("when the doc exists", function() { - beforeEach(function(done) { - return DocstoreClient.deleteDoc(this.project_id, this.doc_id, (error, res, doc) => { - this.res = res; - return done(); - }); - }); + describe('when the doc exists', function() { + beforeEach(function(done) { + return DocstoreClient.deleteDoc( + this.project_id, + this.doc_id, + (error, res, doc) => { + this.res = res + return done() + } + ) + }) - afterEach(function(done) { - return db.docs.remove({_id: this.doc_id}, done); - }); + afterEach(function(done) { + return db.docs.remove({ _id: this.doc_id }, done) + }) - return it("should insert a deleted doc into the docs collection", function(done) { - return db.docs.find({_id: this.doc_id}, (error, docs) => { - docs[0]._id.should.deep.equal(this.doc_id); - docs[0].lines.should.deep.equal(this.lines); - docs[0].deleted.should.equal(true); - return done(); - }); - }); - }); + return it('should insert a deleted doc into the docs collection', function(done) { + return db.docs.find({ _id: this.doc_id }, (error, docs) => { + docs[0]._id.should.deep.equal(this.doc_id) + docs[0].lines.should.deep.equal(this.lines) + docs[0].deleted.should.equal(true) + return done() + }) + }) + }) - return describe("when the doc does not exist", function() { return it("should return a 404", function(done) { - const missing_doc_id = ObjectId(); - return DocstoreClient.deleteDoc(this.project_id, missing_doc_id, (error, res, doc) => { - res.statusCode.should.equal(404); - return done(); - }); - }); }); -}); + return describe('when the doc does not exist', function() { + return it('should return a 404', function(done) { + const missing_doc_id = ObjectId() + return DocstoreClient.deleteDoc( + this.project_id, + missing_doc_id, + (error, res, doc) => { + res.statusCode.should.equal(404) + return done() + } + ) + }) + }) +}) describe("Destroying a project's documents", function() { - describe("when the doc exists", function() { - beforeEach(function(done) { - return db.docOps.insert({doc_id: ObjectId(this.doc_id), version: 1}, function(err) { - if (err != null) { return done(err); } - return DocstoreClient.destroyAllDoc(this.project_id, done); - }); - }); + describe('when the doc exists', function() { + beforeEach(function(done) { + return db.docOps.insert( + { doc_id: ObjectId(this.doc_id), version: 1 }, + function(err) { + if (err != null) { + return done(err) + } + return DocstoreClient.destroyAllDoc(this.project_id, done) + } + ) + }) - it("should remove the doc from the docs collection", function(done) { - return db.docs.find({_id: this.doc_id}, (err, docs) => { - expect(err).not.to.exist; - expect(docs).to.deep.equal([]); - return done(); - }); - }); + it('should remove the doc from the docs collection', function(done) { + return db.docs.find({ _id: this.doc_id }, (err, docs) => { + expect(err).not.to.exist + expect(docs).to.deep.equal([]) + return done() + }) + }) - return it("should remove the docOps from the docOps collection", function(done) { - return db.docOps.find({doc_id: this.doc_id}, (err, docOps) => { - expect(err).not.to.exist; - expect(docOps).to.deep.equal([]); - return done(); - }); - }); - }); + return it('should remove the docOps from the docOps collection', function(done) { + return db.docOps.find({ doc_id: this.doc_id }, (err, docOps) => { + expect(err).not.to.exist + expect(docOps).to.deep.equal([]) + return done() + }) + }) + }) - return describe("when the doc is archived", function() { - beforeEach(function(done) { - return DocstoreClient.archiveAllDoc(this.project_id, function(err) { - if (err != null) { return done(err); } - return DocstoreClient.destroyAllDoc(this.project_id, done); - }); - }); + return describe('when the doc is archived', function() { + beforeEach(function(done) { + return DocstoreClient.archiveAllDoc(this.project_id, function(err) { + if (err != null) { + return done(err) + } + return DocstoreClient.destroyAllDoc(this.project_id, done) + }) + }) - it("should remove the doc from the docs collection", function(done) { - return db.docs.find({_id: this.doc_id}, (err, docs) => { - expect(err).not.to.exist; - expect(docs).to.deep.equal([]); - return done(); - }); - }); + it('should remove the doc from the docs collection', function(done) { + return db.docs.find({ _id: this.doc_id }, (err, docs) => { + expect(err).not.to.exist + expect(docs).to.deep.equal([]) + return done() + }) + }) - it("should remove the docOps from the docOps collection", function(done) { - return db.docOps.find({doc_id: this.doc_id}, (err, docOps) => { - expect(err).not.to.exist; - expect(docOps).to.deep.equal([]); - return done(); - }); - }); + it('should remove the docOps from the docOps collection', function(done) { + return db.docOps.find({ doc_id: this.doc_id }, (err, docOps) => { + expect(err).not.to.exist + expect(docOps).to.deep.equal([]) + return done() + }) + }) - return it("should remove the doc contents from s3", function(done) { - return DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error, res, s3_doc) => { - if (error != null) { throw error; } - expect(res.statusCode).to.equal(404); - return done(); - }); - }); - }); -}); + return it('should remove the doc contents from s3', function(done) { + return DocstoreClient.getS3Doc( + this.project_id, + this.doc_id, + (error, res, s3_doc) => { + if (error != null) { + throw error + } + expect(res.statusCode).to.equal(404) + return done() + } + ) + }) + }) +}) diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 2970042480..4fc7f811d8 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -11,79 +11,104 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const {ObjectId} = require("mongojs"); -const async = require("async"); -const DocstoreApp = require("./helpers/DocstoreApp"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { ObjectId } = require('mongojs') +const async = require('async') +const DocstoreApp = require('./helpers/DocstoreApp') -const DocstoreClient = require("./helpers/DocstoreClient"); +const DocstoreClient = require('./helpers/DocstoreClient') -describe("Getting all docs", function() { - beforeEach(function(done) { - this.project_id = ObjectId(); - this.docs = [{ - _id: ObjectId(), - lines: ["one", "two", "three"], - ranges: {"mock": "one"}, - rev: 2 - }, { - _id: ObjectId(), - lines: ["aaa", "bbb", "ccc"], - ranges: {"mock": "two"}, - rev: 4 - }, { - _id: ObjectId(), - lines: ["111", "222", "333"], - ranges: {"mock": "three"}, - rev: 6 - }]; - this.deleted_doc = { - _id: ObjectId(), - lines: ["deleted"], - ranges: {"mock": "four"}, - rev: 8 - }; - const version = 42; - const jobs = Array.from(this.docs).map((doc) => - (doc => { - return callback => { - return DocstoreClient.createDoc(this.project_id, doc._id, doc.lines, version, doc.ranges, callback); - }; - })(doc)); - jobs.push(cb => { - return DocstoreClient.createDoc(this.project_id, this.deleted_doc._id, this.deleted_doc.lines, version, this.deleted_doc.ranges, err=> { - return DocstoreClient.deleteDoc(this.project_id, this.deleted_doc._id, cb); - }); - }); - jobs.unshift(cb => DocstoreApp.ensureRunning(cb)); - return async.series(jobs, done); - }); - - it("getAllDocs should return all the (non-deleted) docs", function(done) { - return DocstoreClient.getAllDocs(this.project_id, (error, res, docs) => { - if (error != null) { throw error; } - docs.length.should.equal(this.docs.length); - for (let i = 0; i < docs.length; i++) { - const doc = docs[i]; - doc.lines.should.deep.equal(this.docs[i].lines); - } - return done(); - }); - }); - - return it("getAllRanges should return all the (non-deleted) doc ranges", function(done) { - return DocstoreClient.getAllRanges(this.project_id, (error, res, docs) => { - if (error != null) { throw error; } - docs.length.should.equal(this.docs.length); - for (let i = 0; i < docs.length; i++) { - const doc = docs[i]; - doc.ranges.should.deep.equal(this.docs[i].ranges); - } - return done(); - }); - }); -}); +describe('Getting all docs', function() { + beforeEach(function(done) { + this.project_id = ObjectId() + this.docs = [ + { + _id: ObjectId(), + lines: ['one', 'two', 'three'], + ranges: { mock: 'one' }, + rev: 2 + }, + { + _id: ObjectId(), + lines: ['aaa', 'bbb', 'ccc'], + ranges: { mock: 'two' }, + rev: 4 + }, + { + _id: ObjectId(), + lines: ['111', '222', '333'], + ranges: { mock: 'three' }, + rev: 6 + } + ] + this.deleted_doc = { + _id: ObjectId(), + lines: ['deleted'], + ranges: { mock: 'four' }, + rev: 8 + } + const version = 42 + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { + return DocstoreClient.createDoc( + this.project_id, + doc._id, + doc.lines, + version, + doc.ranges, + callback + ) + } + })(doc) + ) + jobs.push(cb => { + return DocstoreClient.createDoc( + this.project_id, + this.deleted_doc._id, + this.deleted_doc.lines, + version, + this.deleted_doc.ranges, + err => { + return DocstoreClient.deleteDoc( + this.project_id, + this.deleted_doc._id, + cb + ) + } + ) + }) + jobs.unshift(cb => DocstoreApp.ensureRunning(cb)) + return async.series(jobs, done) + }) + it('getAllDocs should return all the (non-deleted) docs', function(done) { + return DocstoreClient.getAllDocs(this.project_id, (error, res, docs) => { + if (error != null) { + throw error + } + docs.length.should.equal(this.docs.length) + for (let i = 0; i < docs.length; i++) { + const doc = docs[i] + doc.lines.should.deep.equal(this.docs[i].lines) + } + return done() + }) + }) + return it('getAllRanges should return all the (non-deleted) doc ranges', function(done) { + return DocstoreClient.getAllRanges(this.project_id, (error, res, docs) => { + if (error != null) { + throw error + } + docs.length.should.equal(this.docs.length) + for (let i = 0; i < docs.length; i++) { + const doc = docs[i] + doc.ranges.should.deep.equal(this.docs[i].ranges) + } + return done() + }) + }) +}) diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index e6a96d0958..fb3df8a657 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -11,80 +11,127 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const {ObjectId} = require("mongojs"); -const DocstoreApp = require("./helpers/DocstoreApp"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { ObjectId } = require('mongojs') +const DocstoreApp = require('./helpers/DocstoreApp') -const DocstoreClient = require("./helpers/DocstoreClient"); +const DocstoreClient = require('./helpers/DocstoreClient') -describe("Getting a doc", function() { - beforeEach(function(done) { - this.project_id = ObjectId(); - this.doc_id = ObjectId(); - this.lines = ["original", "lines"]; - this.version = 42; - this.ranges = { - changes: [{ - id: ObjectId().toString(), - op: { i: "foo", p: 3 }, - meta: { - user_id: ObjectId().toString(), - ts: new Date().toString() - } - }] - }; - return DocstoreApp.ensureRunning(() => { - return DocstoreClient.createDoc(this.project_id, this.doc_id, this.lines, this.version, this.ranges, error => { - if (error != null) { throw error; } - return done(); - }); - }); - }); +describe('Getting a doc', function() { + beforeEach(function(done) { + this.project_id = ObjectId() + this.doc_id = ObjectId() + this.lines = ['original', 'lines'] + this.version = 42 + this.ranges = { + changes: [ + { + id: ObjectId().toString(), + op: { i: 'foo', p: 3 }, + meta: { + user_id: ObjectId().toString(), + ts: new Date().toString() + } + } + ] + } + return DocstoreApp.ensureRunning(() => { + return DocstoreClient.createDoc( + this.project_id, + this.doc_id, + this.lines, + this.version, + this.ranges, + error => { + if (error != null) { + throw error + } + return done() + } + ) + }) + }) - describe("when the doc exists", function() { return it("should get the doc lines and version", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.lines); - doc.version.should.equal(this.version); - doc.ranges.should.deep.equal(this.ranges); - return done(); - }); - }); }); + describe('when the doc exists', function() { + return it('should get the doc lines and version', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.lines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.ranges) + return done() + } + ) + }) + }) - describe("when the doc does not exist", function() { return it("should return a 404", function(done) { - const missing_doc_id = ObjectId(); - return DocstoreClient.getDoc(this.project_id, missing_doc_id, {}, (error, res, doc) => { - res.statusCode.should.equal(404); - return done(); - }); - }); }); + describe('when the doc does not exist', function() { + return it('should return a 404', function(done) { + const missing_doc_id = ObjectId() + return DocstoreClient.getDoc( + this.project_id, + missing_doc_id, + {}, + (error, res, doc) => { + res.statusCode.should.equal(404) + return done() + } + ) + }) + }) - return describe("when the doc is a deleted doc", function() { - beforeEach(function(done) { - this.deleted_doc_id = ObjectId(); - return DocstoreClient.createDoc(this.project_id, this.deleted_doc_id, this.lines, this.version, this.ranges, error => { - if (error != null) { throw error; } - return DocstoreClient.deleteDoc(this.project_id, this.deleted_doc_id, done); - }); - }); + return describe('when the doc is a deleted doc', function() { + beforeEach(function(done) { + this.deleted_doc_id = ObjectId() + return DocstoreClient.createDoc( + this.project_id, + this.deleted_doc_id, + this.lines, + this.version, + this.ranges, + error => { + if (error != null) { + throw error + } + return DocstoreClient.deleteDoc( + this.project_id, + this.deleted_doc_id, + done + ) + } + ) + }) - it("should return the doc", function(done) { - return DocstoreClient.getDoc(this.project_id, this.deleted_doc_id, {include_deleted:true},(error, res, doc) => { - doc.lines.should.deep.equal(this.lines); - doc.version.should.equal(this.version); - doc.ranges.should.deep.equal(this.ranges); - doc.deleted.should.equal(true); - return done(); - }); - }); + it('should return the doc', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.deleted_doc_id, + { include_deleted: true }, + (error, res, doc) => { + doc.lines.should.deep.equal(this.lines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.ranges) + doc.deleted.should.equal(true) + return done() + } + ) + }) - return it("should return a 404 when the query string is not set", function(done){ - return DocstoreClient.getDoc(this.project_id, this.deleted_doc_id, {},(error, res, doc) => { - res.statusCode.should.equal(404); - return done(); - }); - }); - }); -}); - \ No newline at end of file + return it('should return a 404 when the query string is not set', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.deleted_doc_id, + {}, + (error, res, doc) => { + res.statusCode.should.equal(404) + return done() + } + ) + }) + }) +}) diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index b3908ba2c4..96f5dfac47 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -10,329 +10,490 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require("sinon"); -const chai = require("chai"); -chai.should(); -const {ObjectId} = require("mongojs"); -const DocstoreApp = require("./helpers/DocstoreApp"); +const sinon = require('sinon') +const chai = require('chai') +chai.should() +const { ObjectId } = require('mongojs') +const DocstoreApp = require('./helpers/DocstoreApp') -const DocstoreClient = require("./helpers/DocstoreClient"); +const DocstoreClient = require('./helpers/DocstoreClient') -describe("Applying updates to a doc", function() { - beforeEach(function(done) { - this.project_id = ObjectId(); - this.doc_id = ObjectId(); - this.originalLines = ["original", "lines"]; - this.newLines = ["new", "lines"]; - this.originalRanges = { - changes: [{ - id: ObjectId().toString(), - op: { i: "foo", p: 3 }, - meta: { - user_id: ObjectId().toString(), - ts: new Date().toString() - } - }] - }; - this.newRanges = { - changes: [{ - id: ObjectId().toString(), - op: { i: "bar", p: 6 }, - meta: { - user_id: ObjectId().toString(), - ts: new Date().toString() - } - }] - }; - this.version = 42; - return DocstoreApp.ensureRunning(() => { - return DocstoreClient.createDoc(this.project_id, this.doc_id, this.originalLines, this.version, this.originalRanges, error => { - if (error != null) { throw error; } - return done(); - }); - }); - }); +describe('Applying updates to a doc', function() { + beforeEach(function(done) { + this.project_id = ObjectId() + this.doc_id = ObjectId() + this.originalLines = ['original', 'lines'] + this.newLines = ['new', 'lines'] + this.originalRanges = { + changes: [ + { + id: ObjectId().toString(), + op: { i: 'foo', p: 3 }, + meta: { + user_id: ObjectId().toString(), + ts: new Date().toString() + } + } + ] + } + this.newRanges = { + changes: [ + { + id: ObjectId().toString(), + op: { i: 'bar', p: 6 }, + meta: { + user_id: ObjectId().toString(), + ts: new Date().toString() + } + } + ] + } + this.version = 42 + return DocstoreApp.ensureRunning(() => { + return DocstoreClient.createDoc( + this.project_id, + this.doc_id, + this.originalLines, + this.version, + this.originalRanges, + error => { + if (error != null) { + throw error + } + return done() + } + ) + }) + }) - describe("when nothing has been updated", function() { - beforeEach(function(done) { - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, this.version, this.originalRanges, (error, res, body) => { - this.body = body; - return done(); - }); - }); + describe('when nothing has been updated', function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.originalLines, + this.version, + this.originalRanges, + (error, res, body) => { + this.body = body + return done() + } + ) + }) - it("should return modified = false", function() { - return this.body.modified.should.equal(false); - }); + it('should return modified = false', function() { + return this.body.modified.should.equal(false) + }) - return it("should not update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - doc.version.should.equal(this.version); - doc.ranges.should.deep.equal(this.originalRanges); - return done(); - }); - }); - }); + return it('should not update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.originalRanges) + return done() + } + ) + }) + }) - describe("when the lines have changed", function() { - beforeEach(function(done) { - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.newLines, this.version, this.originalRanges, (error, res, body) => { - this.body = body; - return done(); - }); - }); + describe('when the lines have changed', function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.newLines, + this.version, + this.originalRanges, + (error, res, body) => { + this.body = body + return done() + } + ) + }) - it("should return modified = true", function() { - return this.body.modified.should.equal(true); - }); + it('should return modified = true', function() { + return this.body.modified.should.equal(true) + }) - it("should return the rev", function() { - return this.body.rev.should.equal(2); - }); + it('should return the rev', function() { + return this.body.rev.should.equal(2) + }) - return it("should update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.newLines); - doc.version.should.equal(this.version); - doc.ranges.should.deep.equal(this.originalRanges); - return done(); - }); - }); - }); + return it('should update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.newLines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.originalRanges) + return done() + } + ) + }) + }) - describe("when the version has changed", function() { - beforeEach(function(done) { - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, this.version + 1, this.originalRanges, (error, res, body) => { - this.body = body; - return done(); - }); - }); + describe('when the version has changed', function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.originalLines, + this.version + 1, + this.originalRanges, + (error, res, body) => { + this.body = body + return done() + } + ) + }) - it("should return modified = true", function() { - return this.body.modified.should.equal(true); - }); + it('should return modified = true', function() { + return this.body.modified.should.equal(true) + }) - it("should return the rev", function() { - return this.body.rev.should.equal(1); - }); + it('should return the rev', function() { + return this.body.rev.should.equal(1) + }) - return it("should update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - doc.version.should.equal(this.version + 1); - doc.ranges.should.deep.equal(this.originalRanges); - return done(); - }); - }); - }); + return it('should update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version + 1) + doc.ranges.should.deep.equal(this.originalRanges) + return done() + } + ) + }) + }) - describe("when the ranges have changed", function() { - beforeEach(function(done) { - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, this.version, this.newRanges, (error, res, body) => { - this.body = body; - return done(); - }); - }); + describe('when the ranges have changed', function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.originalLines, + this.version, + this.newRanges, + (error, res, body) => { + this.body = body + return done() + } + ) + }) - it("should return modified = true", function() { - return this.body.modified.should.equal(true); - }); + it('should return modified = true', function() { + return this.body.modified.should.equal(true) + }) - it("should return the rev", function() { - return this.body.rev.should.equal(2); - }); + it('should return the rev', function() { + return this.body.rev.should.equal(2) + }) - return it("should update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - doc.version.should.equal(this.version); - doc.ranges.should.deep.equal(this.newRanges); - return done(); - }); - }); - }); + return it('should update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version) + doc.ranges.should.deep.equal(this.newRanges) + return done() + } + ) + }) + }) - describe("when the doc does not exist", function() { - beforeEach(function(done) { - this.missing_doc_id = ObjectId(); - return DocstoreClient.updateDoc(this.project_id, this.missing_doc_id, this.originalLines, 0, this.originalRanges, (error, res, body) => { - this.res = res; - this.body = body; - return done(); - }); - }); + describe('when the doc does not exist', function() { + beforeEach(function(done) { + this.missing_doc_id = ObjectId() + return DocstoreClient.updateDoc( + this.project_id, + this.missing_doc_id, + this.originalLines, + 0, + this.originalRanges, + (error, res, body) => { + this.res = res + this.body = body + return done() + } + ) + }) - it("should create the doc", function() { - return this.body.rev.should.equal(1); - }); + it('should create the doc', function() { + return this.body.rev.should.equal(1) + }) - return it("should be retreivable", function(done){ - return DocstoreClient.getDoc(this.project_id, this.missing_doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - doc.version.should.equal(0); - doc.ranges.should.deep.equal(this.originalRanges); - return done(); - }); - }); - }); + return it('should be retreivable', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.missing_doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(0) + doc.ranges.should.deep.equal(this.originalRanges) + return done() + } + ) + }) + }) - describe("when malformed doc lines are provided", function() { - describe("when the lines are not an array", function() { - beforeEach(function(done) { - return DocstoreClient.updateDoc(this.project_id, this.doc_id, { foo: "bar" }, this.version, this.originalRanges, (error, res, body) => { - this.res = res; - this.body = body; - return done(); - }); - }); + describe('when malformed doc lines are provided', function() { + describe('when the lines are not an array', function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + { foo: 'bar' }, + this.version, + this.originalRanges, + (error, res, body) => { + this.res = res + this.body = body + return done() + } + ) + }) - it("should return 400", function() { - return this.res.statusCode.should.equal(400); - }); + it('should return 400', function() { + return this.res.statusCode.should.equal(400) + }) - return it("should not update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - return done(); - }); - }); - }); + return it('should not update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + return done() + } + ) + }) + }) - return describe("when the lines are not present", function() { - beforeEach(function(done) { - return DocstoreClient.updateDoc(this.project_id, this.doc_id, null, this.version, this.originalRanges, (error, res, body) => { - this.res = res; - this.body = body; - return done(); - }); - }); + return describe('when the lines are not present', function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + null, + this.version, + this.originalRanges, + (error, res, body) => { + this.res = res + this.body = body + return done() + } + ) + }) - it("should return 400", function() { - return this.res.statusCode.should.equal(400); - }); + it('should return 400', function() { + return this.res.statusCode.should.equal(400) + }) - return it("should not update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - return done(); - }); - }); - }); - }); - - describe("when no version is provided", function() { - beforeEach(function(done) { - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.originalLines, null, this.originalRanges, (error, res, body) => { - this.res = res; - this.body = body; - return done(); - }); - }); + return it('should not update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + return done() + } + ) + }) + }) + }) - it("should return 400", function() { - return this.res.statusCode.should.equal(400); - }); + describe('when no version is provided', function() { + beforeEach(function(done) { + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.originalLines, + null, + this.originalRanges, + (error, res, body) => { + this.res = res + this.body = body + return done() + } + ) + }) - return it("should not update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - doc.version.should.equal(this.version); - return done(); - }); - }); - }); + it('should return 400', function() { + return this.res.statusCode.should.equal(400) + }) - describe("when the content is large", function() { - beforeEach(function(done) { - const line = new Array(1025).join("x"); // 1kb - this.largeLines = Array.apply(null, Array(1024)).map(() => line); // 1mb - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { - this.body = body; - return done(); - }); - }); + return it('should not update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + doc.version.should.equal(this.version) + return done() + } + ) + }) + }) - it("should return modified = true", function() { - return this.body.modified.should.equal(true); - }); + describe('when the content is large', function() { + beforeEach(function(done) { + const line = new Array(1025).join('x') // 1kb + this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1mb + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.largeLines, + this.version, + this.originalRanges, + (error, res, body) => { + this.body = body + return done() + } + ) + }) - return it("should update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.largeLines); - return done(); - }); - }); - }); + it('should return modified = true', function() { + return this.body.modified.should.equal(true) + }) - describe("when there is a large json payload", function() { - beforeEach(function(done) { - const line = new Array(1025).join("x"); // 1kb - this.largeLines = Array.apply(null, Array(1024)).map(() => line); // 1kb - this.originalRanges.padding = Array.apply(null, Array(2049)).map(() => line); // 2mb + 1kb - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { - this.res = res; - this.body = body; - return done(); - }); - }); + return it('should update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.largeLines) + return done() + } + ) + }) + }) - it("should return modified = true", function() { - return this.body.modified.should.equal(true); - }); + describe('when there is a large json payload', function() { + beforeEach(function(done) { + const line = new Array(1025).join('x') // 1kb + this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1kb + this.originalRanges.padding = Array.apply(null, Array(2049)).map( + () => line + ) // 2mb + 1kb + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.largeLines, + this.version, + this.originalRanges, + (error, res, body) => { + this.res = res + this.body = body + return done() + } + ) + }) - return it("should update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.largeLines); - return done(); - }); - }); - }); + it('should return modified = true', function() { + return this.body.modified.should.equal(true) + }) - describe("when the document body is too large", function() { - beforeEach(function(done) { - const line = new Array(1025).join("x"); // 1kb - this.largeLines = Array.apply(null, Array(2049)).map(() => line); // 2mb + 1kb - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { - this.res = res; - this.body = body; - return done(); - }); - }); + return it('should update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.largeLines) + return done() + } + ) + }) + }) - it("should return 413", function() { - return this.res.statusCode.should.equal(413); - }); + describe('when the document body is too large', function() { + beforeEach(function(done) { + const line = new Array(1025).join('x') // 1kb + this.largeLines = Array.apply(null, Array(2049)).map(() => line) // 2mb + 1kb + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.largeLines, + this.version, + this.originalRanges, + (error, res, body) => { + this.res = res + this.body = body + return done() + } + ) + }) - it("should report body too large", function() { - return this.res.body.should.equal('document body too large'); - }); + it('should return 413', function() { + return this.res.statusCode.should.equal(413) + }) - return it("should not update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - return done(); - }); - }); - }); + it('should report body too large', function() { + return this.res.body.should.equal('document body too large') + }) - return describe("when the json payload is too large", function() { - beforeEach(function(done) { - const line = new Array(1025).join("x"); // 1kb - this.largeLines = Array.apply(null, Array(1024)).map(() => line); // 1kb - this.originalRanges.padding = Array.apply(null, Array(4096)).map(() => line); // 4mb - return DocstoreClient.updateDoc(this.project_id, this.doc_id, this.largeLines, this.version, this.originalRanges, (error, res, body) => { - this.res = res; - this.body = body; - return done(); - }); - }); + return it('should not update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + return done() + } + ) + }) + }) - return it("should not update the doc in the API", function(done) { - return DocstoreClient.getDoc(this.project_id, this.doc_id, {}, (error, res, doc) => { - doc.lines.should.deep.equal(this.originalLines); - return done(); - }); - }); - }); -}); + return describe('when the json payload is too large', function() { + beforeEach(function(done) { + const line = new Array(1025).join('x') // 1kb + this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1kb + this.originalRanges.padding = Array.apply(null, Array(4096)).map( + () => line + ) // 4mb + return DocstoreClient.updateDoc( + this.project_id, + this.doc_id, + this.largeLines, + this.version, + this.originalRanges, + (error, res, body) => { + this.res = res + this.body = body + return done() + } + ) + }) + + return it('should not update the doc in the API', function(done) { + return DocstoreClient.getDoc( + this.project_id, + this.doc_id, + {}, + (error, res, doc) => { + doc.lines.should.deep.equal(this.originalLines) + return done() + } + ) + }) + }) +}) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 9fd8389576..e29117bd78 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -11,34 +11,38 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const app = require('../../../../app'); -require("logger-sharelatex").logger.level("error"); -const settings = require("settings-sharelatex"); +const app = require('../../../../app') +require('logger-sharelatex').logger.level('error') +const settings = require('settings-sharelatex') module.exports = { - running: false, - initing: false, - callbacks: [], - ensureRunning(callback) { - if (callback == null) { callback = function(error) {}; } - if (this.running) { - return callback(); - } else if (this.initing) { - return this.callbacks.push(callback); - } else { - this.initing = true; - this.callbacks.push(callback); - return app.listen(settings.internal.docstore.port, "localhost", error => { - if (error != null) { throw error; } - this.running = true; - return (() => { - const result = []; - for (callback of Array.from(this.callbacks)) { - result.push(callback()); - } - return result; - })(); - }); - } - } -}; \ No newline at end of file + running: false, + initing: false, + callbacks: [], + ensureRunning(callback) { + if (callback == null) { + callback = function(error) {} + } + if (this.running) { + return callback() + } else if (this.initing) { + return this.callbacks.push(callback) + } else { + this.initing = true + this.callbacks.push(callback) + return app.listen(settings.internal.docstore.port, 'localhost', error => { + if (error != null) { + throw error + } + this.running = true + return (() => { + const result = [] + for (callback of Array.from(this.callbacks)) { + result.push(callback()) + } + return result + })() + }) + } + } +} diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 129723a9ea..da91433880 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -11,81 +11,126 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -let DocstoreClient; -const request = require("request").defaults({jar: false}); -const {db, ObjectId} = require("../../../../app/js/mongojs"); -const settings = require("settings-sharelatex"); -const DocArchiveManager = require("../../../../app/js/DocArchiveManager.js"); +let DocstoreClient +const request = require('request').defaults({ jar: false }) +const { db, ObjectId } = require('../../../../app/js/mongojs') +const settings = require('settings-sharelatex') +const DocArchiveManager = require('../../../../app/js/DocArchiveManager.js') -module.exports = (DocstoreClient = { +module.exports = DocstoreClient = { + createDoc(project_id, doc_id, lines, version, ranges, callback) { + if (callback == null) { + callback = function(error) {} + } + return DocstoreClient.updateDoc( + project_id, + doc_id, + lines, + version, + ranges, + callback + ) + }, - createDoc(project_id, doc_id, lines, version, ranges, callback) { - if (callback == null) { callback = function(error) {}; } - return DocstoreClient.updateDoc(project_id, doc_id, lines, version, ranges, callback); - }, + getDoc(project_id, doc_id, qs, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + return request.get( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + json: true, + qs + }, + callback + ) + }, - getDoc(project_id, doc_id, qs, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - return request.get({ - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, - json: true, - qs - }, callback); - }, + getAllDocs(project_id, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + return request.get( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, + json: true + }, + callback + ) + }, - getAllDocs(project_id, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - return request.get({ - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, - json: true - }, callback); - }, + getAllRanges(project_id, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + return request.get( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, + json: true + }, + callback + ) + }, - getAllRanges(project_id, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - return request.get({ - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, - json: true - }, callback); - }, + updateDoc(project_id, doc_id, lines, version, ranges, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + return request.post( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + json: { + lines, + version, + ranges + } + }, + callback + ) + }, - updateDoc(project_id, doc_id, lines, version, ranges, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - return request.post({ - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, - json: { - lines, - version, - ranges - } - }, callback); - }, + deleteDoc(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + return request.del( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}` + }, + callback + ) + }, - deleteDoc(project_id, doc_id, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - return request.del({ - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}` - }, callback); - }, - - archiveAllDoc(project_id, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - return request.post({ - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive` - }, callback); - }, + archiveAllDoc(project_id, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + return request.post( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive` + }, + callback + ) + }, - destroyAllDoc(project_id, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - return request.post({ - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy` - }, callback); - }, + destroyAllDoc(project_id, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + return request.post( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy` + }, + callback + ) + }, - getS3Doc(project_id, doc_id, callback) { - if (callback == null) { callback = function(error, res, body) {}; } - const options = DocArchiveManager.buildS3Options(project_id+"/"+doc_id); - options.json = true; - return request.get(options, callback); - } -}); + getS3Doc(project_id, doc_id, callback) { + if (callback == null) { + callback = function(error, res, body) {} + } + const options = DocArchiveManager.buildS3Options(project_id + '/' + doc_id) + options.json = true + return request.get(options, callback) + } +} From b8aa04b9ff1182400a0a31a416461b70598cd533 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:31 +0000 Subject: [PATCH 228/349] decaffeinate: rename individual coffee files to js files --- services/docstore/{app.coffee => app.js} | 0 .../config/{settings.defaults.coffee => settings.defaults.js} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename services/docstore/{app.coffee => app.js} (100%) rename services/docstore/config/{settings.defaults.coffee => settings.defaults.js} (100%) diff --git a/services/docstore/app.coffee b/services/docstore/app.js similarity index 100% rename from services/docstore/app.coffee rename to services/docstore/app.js diff --git a/services/docstore/config/settings.defaults.coffee b/services/docstore/config/settings.defaults.js similarity index 100% rename from services/docstore/config/settings.defaults.coffee rename to services/docstore/config/settings.defaults.js From 421d6dabab5ee987cab99acdafecf02e1581c052 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:43 +0000 Subject: [PATCH 229/349] decaffeinate: convert individual files to js --- services/docstore/app.js | 121 ++++++++++-------- services/docstore/config/settings.defaults.js | 57 +++++---- 2 files changed, 105 insertions(+), 73 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index c32e3a6b19..2a14168054 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -1,67 +1,86 @@ -Metrics = require "metrics-sharelatex" -Metrics.initialize("docstore") -Settings = require "settings-sharelatex" -logger = require "logger-sharelatex" -express = require "express" -bodyParser = require "body-parser" -Errors = require "./app/js/Errors" -HttpController = require "./app/js/HttpController" -Path = require "path" +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const Metrics = require("metrics-sharelatex"); +Metrics.initialize("docstore"); +const Settings = require("settings-sharelatex"); +const logger = require("logger-sharelatex"); +const express = require("express"); +const bodyParser = require("body-parser"); +const Errors = require("./app/js/Errors"); +const HttpController = require("./app/js/HttpController"); +const Path = require("path"); -logger.initialize("docstore") -Metrics.event_loop?.monitor(logger) +logger.initialize("docstore"); +if (Metrics.event_loop != null) { + Metrics.event_loop.monitor(logger); +} -app = express() +const app = express(); -app.use Metrics.http.monitor(logger) +app.use(Metrics.http.monitor(logger)); -Metrics.injectMetricsRoute(app) +Metrics.injectMetricsRoute(app); -app.param 'project_id', (req, res, next, project_id) -> - if project_id?.match /^[0-9a-f]{24}$/ - next() - else - next new Error("invalid project id") +app.param('project_id', function(req, res, next, project_id) { + if ((project_id != null ? project_id.match(/^[0-9a-f]{24}$/) : undefined)) { + return next(); + } else { + return next(new Error("invalid project id")); + } +}); -app.param 'doc_id', (req, res, next, doc_id) -> - if doc_id?.match /^[0-9a-f]{24}$/ - next() - else - next new Error("invalid doc id") +app.param('doc_id', function(req, res, next, doc_id) { + if ((doc_id != null ? doc_id.match(/^[0-9a-f]{24}$/) : undefined)) { + return next(); + } else { + return next(new Error("invalid doc id")); + } +}); -Metrics.injectMetricsRoute(app) +Metrics.injectMetricsRoute(app); -app.get '/project/:project_id/doc', HttpController.getAllDocs -app.get '/project/:project_id/ranges', HttpController.getAllRanges -app.get '/project/:project_id/doc/:doc_id', HttpController.getDoc -app.get '/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc -# Add 64kb overhead for the JSON encoding, and double the size to allow for ranges in the json payload -app.post '/project/:project_id/doc/:doc_id', bodyParser.json(limit: (Settings.max_doc_length + 64 * 1024) * 2), HttpController.updateDoc -app.del '/project/:project_id/doc/:doc_id', HttpController.deleteDoc +app.get('/project/:project_id/doc', HttpController.getAllDocs); +app.get('/project/:project_id/ranges', HttpController.getAllRanges); +app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc); +app.get('/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc); +// Add 64kb overhead for the JSON encoding, and double the size to allow for ranges in the json payload +app.post('/project/:project_id/doc/:doc_id', bodyParser.json({limit: (Settings.max_doc_length + (64 * 1024)) * 2}), HttpController.updateDoc); +app.del('/project/:project_id/doc/:doc_id', HttpController.deleteDoc); -app.post '/project/:project_id/archive', HttpController.archiveAllDocs -app.post '/project/:project_id/unarchive', HttpController.unArchiveAllDocs -app.post '/project/:project_id/destroy', HttpController.destroyAllDocs +app.post('/project/:project_id/archive', HttpController.archiveAllDocs); +app.post('/project/:project_id/unarchive', HttpController.unArchiveAllDocs); +app.post('/project/:project_id/destroy', HttpController.destroyAllDocs); -app.get "/health_check", HttpController.healthCheck +app.get("/health_check", HttpController.healthCheck); -app.get '/status', (req, res)-> - res.send('docstore is alive') +app.get('/status', (req, res) => res.send('docstore is alive')); -app.use (error, req, res, next) -> - logger.error err: error, req:req, "request errored" - if error instanceof Errors.NotFoundError - res.send 404 - else - res.send(500, "Oops, something went wrong") +app.use(function(error, req, res, next) { + logger.error({err: error, req}, "request errored"); + if (error instanceof Errors.NotFoundError) { + return res.send(404); + } else { + return res.send(500, "Oops, something went wrong"); + } +}); -port = Settings.internal.docstore.port -host = Settings.internal.docstore.host +const { + port +} = Settings.internal.docstore; +const { + host +} = Settings.internal.docstore; -if !module.parent # Called directly - app.listen port, host, (error) -> - throw error if error? - logger.info "Docstore starting up, listening on #{host}:#{port}" +if (!module.parent) { // Called directly + app.listen(port, host, function(error) { + if (error != null) { throw error; } + return logger.info(`Docstore starting up, listening on ${host}:${port}`); + }); +} -module.exports = app +module.exports = app; diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index e45570d3fe..849fea56a1 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -1,31 +1,44 @@ -http = require('http') -http.globalAgent.maxSockets = 300 +/* + * decaffeinate suggestions: + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const http = require('http'); +http.globalAgent.maxSockets = 300; -Settings = - internal: - docstore: - port: 3016 - host: process.env['LISTEN_ADDRESS'] or "localhost" +const Settings = { + internal: { + docstore: { + port: 3016, + host: process.env['LISTEN_ADDRESS'] || "localhost" + } + }, - mongo:{} + mongo:{}, - docstore: - healthCheck: + docstore: { + healthCheck: { project_id: process.env['HEALTH_CHECK_PROJECT_ID'] + } + }, - max_doc_length: 2 * 1024 * 1024 # 2mb + max_doc_length: 2 * 1024 * 1024 // 2mb +}; -if process.env['MONGO_CONNECTION_STRING']? - Settings.mongo.url = process.env['MONGO_CONNECTION_STRING'] -else if process.env['MONGO_HOST']? - Settings.mongo.url = "mongodb://#{process.env['MONGO_HOST']}/sharelatex" -else - Settings.mongo.url = "mongodb://127.0.0.1/sharelatex" +if (process.env['MONGO_CONNECTION_STRING'] != null) { + Settings.mongo.url = process.env['MONGO_CONNECTION_STRING']; +} else if (process.env['MONGO_HOST'] != null) { + Settings.mongo.url = `mongodb://${process.env['MONGO_HOST']}/sharelatex`; +} else { + Settings.mongo.url = "mongodb://127.0.0.1/sharelatex"; +} -if process.env['AWS_ACCESS_KEY_ID']? and process.env['AWS_SECRET_ACCESS_KEY']? and process.env['AWS_BUCKET']? - Settings.docstore.s3 = - key: process.env['AWS_ACCESS_KEY_ID'] - secret: process.env['AWS_SECRET_ACCESS_KEY'] +if ((process.env['AWS_ACCESS_KEY_ID'] != null) && (process.env['AWS_SECRET_ACCESS_KEY'] != null) && (process.env['AWS_BUCKET'] != null)) { + Settings.docstore.s3 = { + key: process.env['AWS_ACCESS_KEY_ID'], + secret: process.env['AWS_SECRET_ACCESS_KEY'], bucket: process.env['AWS_BUCKET'] + }; +} -module.exports = Settings +module.exports = Settings; From 5bca0c9bab3a9f5bdb16e19bc68ef58de70b55e9 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:03:45 +0000 Subject: [PATCH 230/349] prettier: convert individual decaffeinated files to Prettier format --- services/docstore/app.js | 118 +++++++++--------- services/docstore/config/settings.defaults.js | 60 ++++----- 2 files changed, 92 insertions(+), 86 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index 2a14168054..725f1265c9 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -4,83 +4,85 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const Metrics = require("metrics-sharelatex"); -Metrics.initialize("docstore"); -const Settings = require("settings-sharelatex"); -const logger = require("logger-sharelatex"); -const express = require("express"); -const bodyParser = require("body-parser"); -const Errors = require("./app/js/Errors"); -const HttpController = require("./app/js/HttpController"); -const Path = require("path"); +const Metrics = require('metrics-sharelatex') +Metrics.initialize('docstore') +const Settings = require('settings-sharelatex') +const logger = require('logger-sharelatex') +const express = require('express') +const bodyParser = require('body-parser') +const Errors = require('./app/js/Errors') +const HttpController = require('./app/js/HttpController') +const Path = require('path') - -logger.initialize("docstore"); +logger.initialize('docstore') if (Metrics.event_loop != null) { - Metrics.event_loop.monitor(logger); + Metrics.event_loop.monitor(logger) } -const app = express(); +const app = express() -app.use(Metrics.http.monitor(logger)); +app.use(Metrics.http.monitor(logger)) -Metrics.injectMetricsRoute(app); +Metrics.injectMetricsRoute(app) app.param('project_id', function(req, res, next, project_id) { - if ((project_id != null ? project_id.match(/^[0-9a-f]{24}$/) : undefined)) { - return next(); - } else { - return next(new Error("invalid project id")); - } -}); + if (project_id != null ? project_id.match(/^[0-9a-f]{24}$/) : undefined) { + return next() + } else { + return next(new Error('invalid project id')) + } +}) app.param('doc_id', function(req, res, next, doc_id) { - if ((doc_id != null ? doc_id.match(/^[0-9a-f]{24}$/) : undefined)) { - return next(); - } else { - return next(new Error("invalid doc id")); - } -}); + if (doc_id != null ? doc_id.match(/^[0-9a-f]{24}$/) : undefined) { + return next() + } else { + return next(new Error('invalid doc id')) + } +}) -Metrics.injectMetricsRoute(app); +Metrics.injectMetricsRoute(app) -app.get('/project/:project_id/doc', HttpController.getAllDocs); -app.get('/project/:project_id/ranges', HttpController.getAllRanges); -app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc); -app.get('/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc); +app.get('/project/:project_id/doc', HttpController.getAllDocs) +app.get('/project/:project_id/ranges', HttpController.getAllRanges) +app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc) +app.get('/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc) // Add 64kb overhead for the JSON encoding, and double the size to allow for ranges in the json payload -app.post('/project/:project_id/doc/:doc_id', bodyParser.json({limit: (Settings.max_doc_length + (64 * 1024)) * 2}), HttpController.updateDoc); -app.del('/project/:project_id/doc/:doc_id', HttpController.deleteDoc); +app.post( + '/project/:project_id/doc/:doc_id', + bodyParser.json({ limit: (Settings.max_doc_length + 64 * 1024) * 2 }), + HttpController.updateDoc +) +app.del('/project/:project_id/doc/:doc_id', HttpController.deleteDoc) -app.post('/project/:project_id/archive', HttpController.archiveAllDocs); -app.post('/project/:project_id/unarchive', HttpController.unArchiveAllDocs); -app.post('/project/:project_id/destroy', HttpController.destroyAllDocs); +app.post('/project/:project_id/archive', HttpController.archiveAllDocs) +app.post('/project/:project_id/unarchive', HttpController.unArchiveAllDocs) +app.post('/project/:project_id/destroy', HttpController.destroyAllDocs) -app.get("/health_check", HttpController.healthCheck); +app.get('/health_check', HttpController.healthCheck) -app.get('/status', (req, res) => res.send('docstore is alive')); +app.get('/status', (req, res) => res.send('docstore is alive')) app.use(function(error, req, res, next) { - logger.error({err: error, req}, "request errored"); - if (error instanceof Errors.NotFoundError) { - return res.send(404); - } else { - return res.send(500, "Oops, something went wrong"); - } -}); + logger.error({ err: error, req }, 'request errored') + if (error instanceof Errors.NotFoundError) { + return res.send(404) + } else { + return res.send(500, 'Oops, something went wrong') + } +}) -const { - port -} = Settings.internal.docstore; -const { - host -} = Settings.internal.docstore; +const { port } = Settings.internal.docstore +const { host } = Settings.internal.docstore -if (!module.parent) { // Called directly - app.listen(port, host, function(error) { - if (error != null) { throw error; } - return logger.info(`Docstore starting up, listening on ${host}:${port}`); - }); +if (!module.parent) { + // Called directly + app.listen(port, host, function(error) { + if (error != null) { + throw error + } + return logger.info(`Docstore starting up, listening on ${host}:${port}`) + }) } -module.exports = app; +module.exports = app diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 849fea56a1..92bf08e324 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -3,42 +3,46 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const http = require('http'); -http.globalAgent.maxSockets = 300; +const http = require('http') +http.globalAgent.maxSockets = 300 const Settings = { - internal: { - docstore: { - port: 3016, - host: process.env['LISTEN_ADDRESS'] || "localhost" - } - }, + internal: { + docstore: { + port: 3016, + host: process.env.LISTEN_ADDRESS || 'localhost' + } + }, - mongo:{}, + mongo: {}, - docstore: { - healthCheck: { - project_id: process.env['HEALTH_CHECK_PROJECT_ID'] - } - }, + docstore: { + healthCheck: { + project_id: process.env.HEALTH_CHECK_PROJECT_ID + } + }, - max_doc_length: 2 * 1024 * 1024 // 2mb -}; + max_doc_length: 2 * 1024 * 1024 // 2mb +} -if (process.env['MONGO_CONNECTION_STRING'] != null) { - Settings.mongo.url = process.env['MONGO_CONNECTION_STRING']; -} else if (process.env['MONGO_HOST'] != null) { - Settings.mongo.url = `mongodb://${process.env['MONGO_HOST']}/sharelatex`; +if (process.env.MONGO_CONNECTION_STRING != null) { + Settings.mongo.url = process.env.MONGO_CONNECTION_STRING +} else if (process.env.MONGO_HOST != null) { + Settings.mongo.url = `mongodb://${process.env.MONGO_HOST}/sharelatex` } else { - Settings.mongo.url = "mongodb://127.0.0.1/sharelatex"; + Settings.mongo.url = 'mongodb://127.0.0.1/sharelatex' } -if ((process.env['AWS_ACCESS_KEY_ID'] != null) && (process.env['AWS_SECRET_ACCESS_KEY'] != null) && (process.env['AWS_BUCKET'] != null)) { - Settings.docstore.s3 = { - key: process.env['AWS_ACCESS_KEY_ID'], - secret: process.env['AWS_SECRET_ACCESS_KEY'], - bucket: process.env['AWS_BUCKET'] - }; +if ( + process.env.AWS_ACCESS_KEY_ID != null && + process.env.AWS_SECRET_ACCESS_KEY != null && + process.env.AWS_BUCKET != null +) { + Settings.docstore.s3 = { + key: process.env.AWS_ACCESS_KEY_ID, + secret: process.env.AWS_SECRET_ACCESS_KEY, + bucket: process.env.AWS_BUCKET + } } -module.exports = Settings; +module.exports = Settings From 5fc8c3a3c763220a0598bfa45278dcb2dcb28a08 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:04:05 +0000 Subject: [PATCH 231/349] Uninstall coffee-script --- services/docstore/package-lock.json | 5 ----- services/docstore/package.json | 1 - 2 files changed, 6 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 3ed5f34f56..943dc3f164 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -978,11 +978,6 @@ } } }, - "coffee-script": { - "version": "1.12.7", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.12.7.tgz", - "integrity": "sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==" - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", diff --git a/services/docstore/package.json b/services/docstore/package.json index 5181dbbc65..a0b8b1e842 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -21,7 +21,6 @@ "dependencies": { "async": "~0.8.0", "body-parser": "~1.0.2", - "coffee-script": "^1.12.7", "express": "~4.1.1", "logger-sharelatex": "^1.7.0", "metrics-sharelatex": "^2.2.0", From 10a3eadde92e22cc278c1d72c4f6442a50d7814c Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:06:01 +0000 Subject: [PATCH 232/349] Upgrade sha1 hashes to sha512 --- services/docstore/package-lock.json | 502 ++++++++++++++-------------- 1 file changed, 252 insertions(+), 250 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 943dc3f164..fc2241cbd3 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -28,7 +28,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", "dev": true } } @@ -244,7 +244,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" }, "gcp-metadata": { "version": "0.9.3", @@ -324,7 +324,7 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "semver": { "version": "6.1.1", @@ -341,7 +341,7 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "@protobufjs/base64": { "version": "1.1.2", @@ -356,12 +356,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -370,27 +370,27 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "@sindresorhus/is": { "version": "0.15.0", @@ -531,7 +531,7 @@ "accepts": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz", - "integrity": "sha1-weBtYT5iRrqHRnjW2bkjibfOMQw=", + "integrity": "sha512-EsBDjbbGp44Tq6UGW6YE4cgD2xF1MIIyK7Vn+sElHW3EiSgqoIetsTiwFytb9YxODl6YVc4IIY28zeQ0JKGCLQ==", "requires": { "mime": "~1.2.11", "negotiator": "~0.4.0" @@ -603,7 +603,7 @@ "aria-query": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==", "dev": true, "requires": { "ast-types-flow": "0.0.7", @@ -639,27 +639,27 @@ "asn1": { "version": "0.1.11", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", + "integrity": "sha512-Fh9zh3G2mZ8qM/kwsiKwL2U2FmXxVsboP4x1mXjnhKHv3SmzaBZoYvxEQJz/YS2gnCgd8xlAVWcZnQyC9qZBsA==", "dev": true, "optional": true }, "assert-plus": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", + "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==", "dev": true, "optional": true }, "assertion-error": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "integrity": "sha512-g/gZV+G476cnmtYI+Ko9d5khxSoCSoom/EaNmmCfwpOvBXEJ18qwFrxfP1/CsIqk2no1sAKKwxndV0tP7ROOFQ==", "dev": true }, "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, "astral-regex": { @@ -671,7 +671,7 @@ "async": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz", - "integrity": "sha1-7mXsdymML/FFa8RBigUtDwZDURI=" + "integrity": "sha512-M2LC+aqW7VetFcnFiYEbjUsmASW6GSsMNkRzhUzwHoQNfNIRClf5GLgozwuJ4tAMLAfjywrKyQ2wWiODJivQmg==" }, "async-listener": { "version": "0.6.10", @@ -685,12 +685,12 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sign2": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", + "integrity": "sha512-oqUX0DM5j7aPWPCnpWebiyNIj2wiNI87ZxnOMoGv0aE4TGlBy2N+5iWc6dQ/NOKZaBD2W6PVz8jtOGkWzSC5EA==", "dev": true, "optional": true }, @@ -742,7 +742,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==" }, "base64-js": { "version": "1.3.0", @@ -752,7 +752,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "requires": { "tweetnacl": "^0.14.3" } @@ -773,12 +773,12 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" + "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" }, "body-parser": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz", - "integrity": "sha1-NGFHmjJ4/gD8rr7DMUu1T8T3tHw=", + "integrity": "sha512-/VlRWmVVwfh8rYG/MHGIwesdJYdxBgeddggFG5ssLfX/Qhwt4NKEQhvzwdzVRcy2RhLxni1MKe0uuPfP/unjyw==", "requires": { "qs": "~0.6.6", "raw-body": "~1.1.2", @@ -788,14 +788,15 @@ "boolify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/boolify/-/boolify-1.0.1.tgz", - "integrity": "sha1-tcCeF8rNET0Rt7s+04TMASmU2Gs=", + "integrity": "sha512-ma2q0Tc760dW54CdOyJjhrg/a54317o1zYADQJFgperNGKIKgAUGIcKnuMiff8z57+yGlrGNEt4lPgZfCgTJgA==", "dev": true }, "boom": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", + "integrity": "sha512-OvfN8y1oAxxphzkl2SnCS+ztV/uVKTATtgLjWYg/7KwcNyf3rzpHxNQJZCKtsZd4+MteKczhWbSjtEX4bGgU9g==", "dev": true, + "optional": true, "requires": { "hoek": "0.9.x" } @@ -812,7 +813,7 @@ "browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "integrity": "sha512-7Rfk377tpSM9TWBEeHs0FlDZGoAIei2V/4MdZJoFMBFAK6BqLpxAIUepGRHGdPFgGsLb02PXovC4qddyHvQqTg==", "dev": true }, "bson": { @@ -823,17 +824,17 @@ "buffer-crc32": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz", - "integrity": "sha1-vj5TgvwCttYySVasGvmKqYsIU0w=" + "integrity": "sha512-vMfBIRp/wjlpueSz7Sb0OmO7C5SH58SSmbsT8G4D48YfO/Zgbr29xNXMpZVSC14ujVJfrZZH1Bl+kXYRQPuvfQ==" }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" + "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==" }, "builtin-modules": { "version": "3.1.0", @@ -843,7 +844,7 @@ "bunyan": { "version": "0.22.3", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", - "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", + "integrity": "sha512-v9dd5qmd6nJHEi7fiNo1fR2pMpE8AiB47Ap984p4iJKj+dEA69jSccmq6grFQn6pxIh0evvKpC5XO1SKfiaRoQ==", "dev": true, "requires": { "dtrace-provider": "0.2.8", @@ -853,7 +854,7 @@ "bytes": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=" + "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==" }, "callsites": { "version": "3.1.0", @@ -881,12 +882,12 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, "chai": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", - "integrity": "sha1-Pxog+CsLnXQ3V30k1vErGmnTtZA=", + "integrity": "sha512-olRoaitftnzWHFEAza6MXR4w+FfZrOVyV7r7U/Z8ObJefCgL8IuWkAuASJjSXrpP9wvgoL8+1dB9RbMLc2FkNg==", "dev": true, "requires": { "assertion-error": "1.0.0", @@ -907,7 +908,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { @@ -939,7 +940,7 @@ "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "integrity": "sha512-EJLbKSuvHTrVRynOXCYFTbQKZOFXWNe3/6DN1yrEH3TuuZT1x4dMQnCHnfCrBUUiGjO63enEIfaB17VaRl2d4A==", "dev": true }, "cliui": { @@ -962,7 +963,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "string-width": { @@ -990,13 +991,13 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "combined-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "integrity": "sha512-qfexlmLp9MyrkajQVyjEDb0Vj+KhRgR/rxLiVhaihlT+ZkX0lReqtH6Ack40CvMDERR4b5eFp3CreskpBs1Pig==", "dev": true, "optional": true, "requires": { @@ -1018,7 +1019,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "console-log-level": { "version": "1.4.1", @@ -1028,7 +1029,7 @@ "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==", "dev": true }, "continuation-local-storage": { @@ -1043,12 +1044,12 @@ "cookie": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", - "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" + "integrity": "sha512-+mHmWbhevLwkiBf7QcbZXHr0v4ZQQ/OgHk3fsQHrsMMiGzuvAmU/YMUR+ZfrO/BLAGIWFfx2Z7Oyso0tZR/wiA==" }, "cookie-signature": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", - "integrity": "sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k=" + "integrity": "sha512-/KzKzsm0OlguYov01OlOpTkX5MhBKUmfL/KMum7R80rPKheb9AwUzr78TwtBt1OdbnWrt4X+wxbTfcQ3noZqHw==" }, "core-js": { "version": "3.6.4", @@ -1059,7 +1060,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cross-spawn": { "version": "6.0.5", @@ -1077,7 +1078,7 @@ "cryptiles": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", + "integrity": "sha512-gvWSbgqP+569DdslUiCelxIv3IYK5Lgmq1UrRnk+s1WxQOQ16j3GPDcjdtgL5Au65DU/xQi6q3xPtf5Kta+3IQ==", "dev": true, "optional": true, "requires": { @@ -1087,7 +1088,7 @@ "ctype": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", + "integrity": "sha512-T6CEkoSV4q50zW3TlTHMbzy1E5+zlnNcY+yb7tWVYlTwPhx9LpnfAkd4wecpWknDyptp4k97LUZeInlf6jdzBg==", "dev": true, "optional": true }, @@ -1100,7 +1101,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "requires": { "assert-plus": "^1.0.0" }, @@ -1108,25 +1109,25 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, "debug": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz", - "integrity": "sha1-IP9NJvXkIstoobrLu2EDmtjBwTA=" + "integrity": "sha512-HlXEJm99YsRjLJ8xmuz0Lq8YUwrv7hAJkTEr6/Em3sUlSUNl0UdFA+1SrY4fnykeq1FVkUEUtwRGHs9VvlYbGA==" }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "deep-eql": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "integrity": "sha512-6sEotTRGBFiNcqVoeHwnfopbSpi5NbH1VWJmYCVkmxMmaVTT0bUTrNaGyBwhgP4MZL012W/mkzIn3Da+iDYweg==", "dev": true, "requires": { "type-detect": "0.1.1" @@ -1135,7 +1136,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "integrity": "sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==", "dev": true }, "define-properties": { @@ -1155,7 +1156,7 @@ "delayed-stream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", + "integrity": "sha512-v+7uBd1pqe5YtgPacIIbZ8HuHeLFVNe4mUEyFDXL6KiqzEykjbw+5mXZXpGFgNVasdL4jWKgaKIXrEHiynN1LA==", "dev": true, "optional": true }, @@ -1177,7 +1178,7 @@ "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", - "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", + "integrity": "sha512-wufYnYt4ISHnT9MEiRgQ3trXuolt7mICTa/ckT+KYHR667K9H82lmI8KM7zKUJ8l5I343A34wJnvL++1TJn1iA==", "dev": true, "optional": true }, @@ -1195,12 +1196,12 @@ "each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" + "integrity": "sha512-4MQloCGGCmT5GJZK5ibgJSvTK1c1QSrNlDvLk6fEyRxjZnXjl+NNFfzhfXpmnWh33Owc9D9klrdzCUi7yc9r4Q==" }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -1239,7 +1240,7 @@ "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" }, "error-ex": { "version": "1.3.2", @@ -1283,12 +1284,12 @@ "es6-promise": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + "integrity": "sha512-oj4jOSXvWglTsc3wrw86iom3LDPOx1nbipQk+jaG3dy+sMRM6ReSgVr/VlmBuF6lXUrflN9DCcQHeSbAwGUl4g==" }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "requires": { "es6-promise": "^4.0.3" }, @@ -1303,12 +1304,12 @@ "escape-html": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" + "integrity": "sha512-z6kAnok8fqVTra7Yu77dZF2Y6ETJlxH58wN38wNyuNQLm8xXdKnfNrlSmfXsTePWP03rRVUKHubtUwanwUi7+g==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "eslint": { @@ -1531,7 +1532,7 @@ "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -1767,7 +1768,7 @@ "express": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/express/-/express-4.1.2.tgz", - "integrity": "sha1-yx0RQlVximWhvNaVgDbvcgxSlIc=", + "integrity": "sha512-U7G/TwoXu9uSHtGnvW6WQyLz3rP+qp3sHUiNpKw5Mz2o6DGenpxngH5tGnxgg09Hjqzje2CzZKukPoZfemepYQ==", "requires": { "accepts": "1.0.1", "buffer-crc32": "0.2.1", @@ -1807,12 +1808,12 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, "fast-diff": { "version": "1.2.0", @@ -1823,12 +1824,12 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==" }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fast-text-encoding": { @@ -1862,7 +1863,7 @@ "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -1871,7 +1872,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" + "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" }, "flat-cache": { "version": "2.0.1", @@ -1936,13 +1937,13 @@ "forever-agent": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=", + "integrity": "sha512-PDG5Ef0Dob/JsZUxUltJOhm/Y9mlteAE+46y3M9RBz/Rd3QVENJ75aGRhN56yekTUboaBIkd8KVWX2NjF6+91A==", "dev": true }, "form-data": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", + "integrity": "sha512-x8eE+nzFtAMA0YYlSxf/Qhq6vP1f8wSoZ7Aw1GuctBcmudCNuTUmmx45TfEplyb6cjsZO/jvh6+1VpZn24ez+w==", "dev": true, "optional": true, "requires": { @@ -1954,7 +1955,7 @@ "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "integrity": "sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw==", "dev": true, "optional": true } @@ -1963,7 +1964,7 @@ "formatio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", + "integrity": "sha512-YAF05v8+XCxAyHOdiiAmHdgCVPrWO8X744fYIPtBciIorh5LndWfi1gjeJ16sTbJhzek9kd+j3YByhohtz5Wmg==", "dev": true, "requires": { "samsam": "1.x" @@ -1972,12 +1973,12 @@ "fresh": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", - "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" + "integrity": "sha512-ZGGi8GROK//ijm2gB33sUuN9TjN1tC/dvG4Bt4j6IWrVGpMmudUBCxx+Ir7qePsdREfkpQC4FL8W0jeSOsgv1w==" }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "function-bind": { @@ -1989,7 +1990,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, "gaxios": { @@ -2027,7 +2028,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "requires": { "assert-plus": "^1.0.0" }, @@ -2035,14 +2036,14 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, "glob": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", "optional": true, "requires": { "inflight": "^1.0.4", @@ -2120,7 +2121,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" }, "har-validator": { "version": "5.1.3", @@ -2143,7 +2144,7 @@ "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -2152,7 +2153,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true } } @@ -2160,7 +2161,7 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==", "dev": true }, "has-symbols": { @@ -2172,7 +2173,7 @@ "hawk": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", - "integrity": "sha1-uQuxaYByhUEdp//LjdJZhQLTtS0=", + "integrity": "sha512-Sg+VzrI7TjUomO0rjD6UXawsj50ykn5sB/xKNW/IenxzRVyw/wt9A2FLzYpGL/r0QG5hyXY8nLx/2m8UutoDcg==", "dev": true, "optional": true, "requires": { @@ -2185,7 +2186,7 @@ "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==", "dev": true }, "hex2dec": { @@ -2196,8 +2197,9 @@ "hoek": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", - "dev": true + "integrity": "sha512-ZZ6eGyzGjyMTmpSPYVECXy9uNfqBR7x5CavhUaLOeD6W0vWK1mp/b7O3f86XE0Mtfo9rZ6Bh3fnuw9Xr8MF9zA==", + "dev": true, + "optional": true }, "hosted-git-info": { "version": "2.8.5", @@ -2208,7 +2210,7 @@ "http-signature": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", + "integrity": "sha512-coK8uR5rq2IMj+Hen+sKPA5ldgbCc1/spPdKCL1Fw6h+D0s/2LzMcRK0Cqufs1h0ryx/niwBHGFu8HC3hwU+lA==", "dev": true, "optional": true, "requires": { @@ -2277,7 +2279,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "indent-string": { @@ -2289,7 +2291,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2298,7 +2300,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "inquirer": { "version": "7.0.4", @@ -2340,7 +2342,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, "is-buffer": { @@ -2363,7 +2365,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { @@ -2384,7 +2386,7 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "integrity": "sha512-NECAi6wp6CgMesHuVUEK8JwjCvm/tvnn5pCbB42JOHp3mgUizN0nagXu4HEqQZBkieGEQ+jVcMKWqoVd6CDbLQ==", "dev": true }, "is-regex": { @@ -2414,23 +2416,23 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "js-tokens": { "version": "4.0.0", @@ -2451,7 +2453,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "jsesc": { "version": "2.5.2", @@ -2462,7 +2464,7 @@ "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", + "integrity": "sha512-u+c/u/F+JNPUekHCFyGVycRPyh9UHD5iUhSyIAn10kxbDTJxijwAbT6XHaONEOXuGGfmWUSroheXgHcml4gLgg==", "requires": { "bignumber.js": "^7.0.0" } @@ -2470,7 +2472,7 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==" }, "json-schema-traverse": { "version": "0.4.1", @@ -2480,18 +2482,18 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -2502,7 +2504,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -2544,7 +2546,7 @@ "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", "dev": true, "requires": { "prelude-ls": "~1.1.2", @@ -2554,7 +2556,7 @@ "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -2566,7 +2568,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -2574,7 +2576,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -2590,7 +2592,7 @@ "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, "lodash.merge": { @@ -2602,12 +2604,12 @@ "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" + "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==" }, "lodash.unescape": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "integrity": "sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==", "dev": true }, "logger-sharelatex": { @@ -2623,17 +2625,17 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" }, "bunyan": { "version": "1.8.12", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", "requires": { "dtrace-provider": "~0.8", "moment": "^2.10.6", @@ -2652,12 +2654,12 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "dtrace-provider": { "version": "0.8.7", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz", - "integrity": "sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ=", + "integrity": "sha512-V+HIGbAdxCIxddHNDwzXi6cx8Cz5RRlQOVcsryHfsyVVebpBEnDwHSgqxpgKzqeU/6/0DWqRLAGUwkbg2ecN1Q==", "optional": true, "requires": { "nan": "^2.10.0" @@ -2666,7 +2668,7 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" }, "form-data": { "version": "2.3.3", @@ -2681,7 +2683,7 @@ "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -2737,7 +2739,7 @@ "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "requires": { "safe-buffer": "^5.0.1" } @@ -2758,7 +2760,7 @@ "loglevel-colored-level-prefix": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz", - "integrity": "sha1-akAhj9x64V/HbD0PPmdsRlOIYD4=", + "integrity": "sha512-u45Wcxxc+SdAlh4yeF/uKlC1SPUPCy0gullSNKXod5I4bmifzk+Q4lSLExNEVn19tGaJipbZ4V4jbFn79/6mVA==", "dev": true, "requires": { "chalk": "^1.1.3", @@ -2768,19 +2770,19 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", "dev": true }, "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", "dev": true, "requires": { "ansi-styles": "^2.2.1", @@ -2793,7 +2795,7 @@ "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", "dev": true, "requires": { "ansi-regex": "^2.0.0" @@ -2802,7 +2804,7 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", "dev": true } } @@ -2838,12 +2840,12 @@ "lsmod": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", - "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" + "integrity": "sha512-Y+6V75r+mGWzWEPr9h6PFmStielICu5JBHLUg18jCsD2VFmEfgHbq/EgnY4inElsUD9eKL9id1qp34w46rSIKQ==" }, "lynx": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", - "integrity": "sha1-Mxjc7xaQi4KG6Bisz9sxzXQkj50=", + "integrity": "sha512-JI52N0NwK2b/Md0TFPdPtUBI46kjyJXF7+q08l2yvQ56q6QA8s7ZjZQQRoxFpS2jDXNf/B0p8ID+OIKcTsZwzw==", "requires": { "mersenne": "~0.0.3", "statsd-parser": "~0.0.4" @@ -2861,7 +2863,7 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "integrity": "sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==", "dev": true, "optional": true } @@ -2876,12 +2878,12 @@ "merge-descriptors": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", - "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" + "integrity": "sha512-dYBT4Ep+t/qnPeJcnMymmhTdd4g8/hn48ciaDqLAkfRf8abzLPS6Rb6EBdz5CZCL8tzZuI5ps9MhGQGxk+EuKg==" }, "mersenne": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", - "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" + "integrity": "sha512-XoSUL+nF8hMTKGQxUs8r3Btdsf1yuKKBdCCGbh3YXgCXuVKishpZv1CNc385w9s8t4Ynwc5h61BwW/FCVulkbg==" }, "messageformat": { "version": "2.3.0", @@ -2909,7 +2911,7 @@ "methods": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz", - "integrity": "sha1-M11Cnu/SG3us8unJIqjSvRSjDk8=" + "integrity": "sha512-N4cn4CbDqu7Fp3AT4z3AsO19calgczhsmCGzXLCiUOrWg9sjb1B+yKFKOrnnPGKKvjyJBmw+k6b3adFN2LbuBw==" }, "metrics-sharelatex": { "version": "2.2.0", @@ -2928,14 +2930,14 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" } } }, "mime": { "version": "1.2.11", "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=" + "integrity": "sha512-Ysa2F/nqTNGHhhm9MV8ure4+Hc+Y8AWiqUdHxsO7xu8zc92ND9f3kpALHjaP026Ft17UfxrMt95c50PLUeynBw==" }, "mime-db": { "version": "1.40.0", @@ -2967,12 +2969,12 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==" }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", "requires": { "minimist": "0.0.8" } @@ -3041,7 +3043,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, "moment": { "version": "2.24.0", @@ -3062,7 +3064,7 @@ "readable-stream": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", + "integrity": "sha512-a6ibcfWFhgihuTw/chl+u3fB5ykBZFmnvpyZHebY0MCQE4vvYcsCLpCeaQ1BkH7HdJYavNSqF0WDLeo4IPHQaQ==", "requires": { "buffer-shims": "~1.0.0", "core-util-is": "~1.0.0", @@ -3095,7 +3097,7 @@ "mongojs": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", - "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", + "integrity": "sha512-QqqJ06x5EBBG121dxXbm0kQ8mNVAOGMeG3RKbNvtbiFez5EhCTMDUikYcsa0V9tphlvsheO5riMHcXHxW0q3lw==", "requires": { "each-series": "^1.0.0", "mongodb": "^2.0.45", @@ -3110,7 +3112,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "mute-stream": { "version": "0.0.8", @@ -3121,7 +3123,7 @@ "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -3137,25 +3139,25 @@ "native-promise-only": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "optional": true }, "negotiator": { "version": "0.4.9", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", - "integrity": "sha1-kuRrbbU8fkIe1koryU8IvnYw3z8=" + "integrity": "sha512-fvi5GQce2TGDzanaTxNY3bboxjdce18sqwNylY439wkEkiJIyTMhGFMdlPCvDsIPa9IKIfhKwCMWEQ9YpZgb1Q==" }, "nice-try": { "version": "1.0.5", @@ -3179,13 +3181,13 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "integrity": "sha512-nifX1uj4S9IrK/w3Xe7kKvNEepXivANs9ng60Iq7PU/BlouV3yL/VUhFqTuTq33ykwUqoNcTeGo5vdOBP4jS/Q==", "dev": true, "requires": { "isarray": "0.0.1" @@ -3206,7 +3208,7 @@ "node-uuid": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", + "integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==", "dev": true }, "normalize-package-data": { @@ -3224,14 +3226,14 @@ "oauth-sign": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", - "integrity": "sha1-y1QPk7srIqfVlBaRoojWDo6pOG4=", + "integrity": "sha512-Tr31Sh5FnK9YKm7xTUPyDMsNOvMqkVDND0zvK/Wgj7/H9q8mpye0qG2nVzrnsvLhcsX5DtqXD0la0ks6rkPCGQ==", "dev": true, "optional": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "object-inspect": { @@ -3297,7 +3299,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -3328,7 +3330,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", "dev": true }, "p-limit": { @@ -3342,7 +3344,7 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -3360,7 +3362,7 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true } } @@ -3382,12 +3384,12 @@ "parse-duration": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", - "integrity": "sha1-ExFN3JiRwezSgANiRFVN5DZHoiY=" + "integrity": "sha512-MPkERaX8suJ97HH2TtTN81ASYdFWouJqcnfVYSFHvWCI13vN4NzbvKsBOYN/7o8cTSoaNVMz4H8wG7GjTj0q6g==" }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -3396,7 +3398,7 @@ "parse-mongo-url": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" + "integrity": "sha512-7bZUusQIrFLwvsLHBnCz2WKYQ5LKO/LwKPnvQxbMIh9gDx8H5ZsknRmLjZdn6GVdrgVOwqDrZKsY0qDLNmRgcw==" }, "parse-ms": { "version": "2.1.0", @@ -3406,29 +3408,29 @@ "parseurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", - "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" + "integrity": "sha512-6W9+0+9Ihayqwjgp4OaLLqZ3KDtqPY2PtUPz8YNiy4PamjJv+7x6J9GO93O9rUZOLgaanTPxsKTasxqKkO1iSw==" }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "dev": true }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", "dev": true }, "path-parse": { @@ -3439,12 +3441,12 @@ "path-to-regexp": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", - "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" + "integrity": "sha512-BZU7Qr+qKkXJX9UBypMNikdZ85cQSjtfMhUykJFLJn4SNF0jhEbb9nMRpnNdA76ESryY8JpMA4k6XKdz3JS1pw==" }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", "dev": true, "requires": { "pify": "^2.0.0" @@ -3453,7 +3455,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -3461,7 +3463,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "pify": { "version": "4.0.1", @@ -3471,7 +3473,7 @@ "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "integrity": "sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==", "dev": true, "requires": { "find-up": "^2.1.0" @@ -3480,7 +3482,7 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", "dev": true }, "prettier": { @@ -3519,13 +3521,13 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", "dev": true }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", "dev": true, "requires": { "restore-cursor": "^2.0.0" @@ -3608,7 +3610,7 @@ "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -3669,7 +3671,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "mimic-fn": { @@ -3687,13 +3689,13 @@ "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", "dev": true, "requires": { "mimic-fn": "^1.0.0" @@ -3702,7 +3704,7 @@ "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "requires": { "onetime": "^2.0.0", @@ -3728,7 +3730,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -3737,7 +3739,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true } } @@ -3776,13 +3778,13 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", "dev": true }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", "dev": true, "requires": { "restore-cursor": "^2.0.0" @@ -3873,7 +3875,7 @@ "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -3956,7 +3958,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "locate-path": { @@ -3983,13 +3985,13 @@ "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", "dev": true }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", "dev": true, "requires": { "mimic-fn": "^1.0.0" @@ -4013,7 +4015,7 @@ "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", "dev": true, "requires": { "onetime": "^2.0.0", @@ -4039,7 +4041,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -4048,7 +4050,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true } } @@ -4075,7 +4077,7 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", "dev": true } } @@ -4091,7 +4093,7 @@ "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==" }, "progress": { "version": "2.0.3", @@ -4153,12 +4155,12 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" }, "qs": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", - "integrity": "sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc=" + "integrity": "sha512-kN+yNdAf29Jgp+AYHUmC7X4QdJPR8czuMWLNLc0aRxkQ7tB3vJQEONKKT9ou/rW7EbqVec11srC9q9BiVbcnHA==" }, "quick-lru": { "version": "4.0.1", @@ -4175,12 +4177,12 @@ "range-parser": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", - "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" + "integrity": "sha512-wOH5LIH2ZHo0P7/bwkR+aNbJ+kv3CHVX4B8qs9GqbtY29fi1bGPV5xczrutN20G+Z4XhRqRMTW3q0S4iyJJPfw==" }, "raven": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", - "integrity": "sha1-QnPBrm005CMPUbLAEEGjK5Iygio=", + "integrity": "sha512-RYov4wAaflZasWiCrZuizd3jNXxCOkW1WrXgWsGVb8kRpdHNZ+vPY27R6RhVtqzWp+DG9a5l6iP0QUPK4EgzaQ==", "requires": { "cookie": "0.3.1", "json-stringify-safe": "5.0.1", @@ -4192,19 +4194,19 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" }, "uuid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", - "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" + "integrity": "sha512-rqE1LoOVLv3QrZMjb4NkF5UWlkurCfPyItVnFPNKDDGkHw4dQUdE4zMcLqx28+0Kcf3+bnUk4PisaiRJT4aiaQ==" } } }, "raw-body": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", + "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==", "requires": { "bytes": "1", "string_decoder": "0.10" @@ -4219,7 +4221,7 @@ "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", "dev": true, "requires": { "load-json-file": "^2.0.0", @@ -4230,7 +4232,7 @@ "read-pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", "dev": true, "requires": { "find-up": "^2.0.0", @@ -4291,7 +4293,7 @@ "request": { "version": "2.34.0", "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", - "integrity": "sha1-tdi5UmrdSi1GKfTUFxJFc5lkRa4=", + "integrity": "sha512-mD5mNhfkeaKMg5ZY/hZFbW4lyC/NTn34/ILGQr/XLSuxYOE6vJfL0MTPPXZcZrdt+Nh1Kce+f4B4KbGThIETxQ==", "dev": true, "requires": { "aws-sign2": "~0.5.0", @@ -4311,7 +4313,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "require-in-the-middle": { @@ -4342,7 +4344,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "dev": true }, "require-main-filename": { @@ -4354,7 +4356,7 @@ "require-relative": { "version": "0.8.7", "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", - "integrity": "sha1-eZlTn8ngR6N5KPoZb44VY9q9Nt4=", + "integrity": "sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==", "dev": true }, "require_optional": { @@ -4377,7 +4379,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" }, "restore-cursor": { "version": "3.1.0", @@ -4405,7 +4407,7 @@ "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", "optional": true, "requires": { "glob": "^6.0.1" @@ -4414,7 +4416,7 @@ "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "integrity": "sha512-Fx+QT3fGtS0jk8OvKyKgAB2YHPsrmqBRcMeTC5AZ+lp4vzXKPPrFSY3iLdgvjA3HVBkIvJeM6J80LRjx8bQwhA==", "dev": true, "requires": { "is-promise": "^2.1.0" @@ -4454,7 +4456,7 @@ "sandboxed-module": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", - "integrity": "sha1-8fvvvYCaT2kHO9B8rm/H2y6vX2o=", + "integrity": "sha512-/2IfB1wtca3eNVPXbQrb6UkhE/1pV4Wz+5CdG6DPYqeaDsYDzxglBT7/cVaqyrlRyQKdmw+uTZUTRos9FFD2PQ==", "dev": true, "requires": { "require-like": "0.1.2", @@ -4464,7 +4466,7 @@ "stack-trace": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", - "integrity": "sha1-HnGb1qJin/CcGJ4Xqe+QKpT8XbA=", + "integrity": "sha512-5/6uZt7RYjjAl8z2j1mXWAewz+I4Hk2/L/3n6NRLIQ31+uQ7nMd9O6G69QCdrrufHv0QGRRHl/jwUEGTqhelTA==", "dev": true } } @@ -4477,7 +4479,7 @@ "send": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", - "integrity": "sha1-lxgyRjSAb8dbxPj15R9X2dZmBuc=", + "integrity": "sha512-FPyeqtit9Z3zbusjv0KQyR8vQ9CL57qPNOz4GgcuIPSk+nx9WTUIMQoR6+0a7YOZpQVTtk04qH0IVQG3rohZ0Q==", "requires": { "buffer-crc32": "0.2.1", "debug": "0.8.0", @@ -4489,14 +4491,14 @@ "debug": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz", - "integrity": "sha1-BUHqkfDlA/3wxe7UGKMlUCNJZ/A=" + "integrity": "sha512-jR+JRuwlhTwNPpLU6/JhiMydD6+GnL/33WE8LlmnBUqPHXkEpG2iNargYBO/Wxx7wXn7oxU6XwYIZyH4YuSW9Q==" } } }, "serve-static": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz", - "integrity": "sha1-RU36Bbs93U5wGokVuDoniqkcVkM=", + "integrity": "sha512-vzgWiHz5xrM19pqugiYI6sWP9B0+K6vz4Ep5G1my9lVhuYkRXGYs5xtnXZ06fpLPRumROSZ1CLqiRxdngPkojQ==", "requires": { "parseurl": "1.0.1", "send": "0.3.0" @@ -4505,7 +4507,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, "settings-sharelatex": { @@ -4519,14 +4521,14 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" } } }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", "dev": true, "requires": { "shebang-regex": "^1.0.0" @@ -4535,7 +4537,7 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", "dev": true }, "shimmer": { @@ -4556,7 +4558,7 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "integrity": "sha512-meQNNykwecVxdu1RlYMKpQx4+wefIYpmxi6gexo/KAbwquJrBUrBmKYJrE8KFkVQAAVWEnwNdu21PgrD77J3xA==", "dev": true }, "sinon": { @@ -4585,13 +4587,13 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "integrity": "sha512-nifX1uj4S9IrK/w3Xe7kKvNEepXivANs9ng60Iq7PU/BlouV3yL/VUhFqTuTq33ykwUqoNcTeGo5vdOBP4jS/Q==", "dev": true, "requires": { "isarray": "0.0.1" @@ -4619,7 +4621,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true } } @@ -4627,7 +4629,7 @@ "sntp": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", + "integrity": "sha512-bDLrKa/ywz65gCl+LmOiIhteP1bhEsAAzhfMedPoiHP3dyYnAevlaJshdqb9Yu0sRifyP/fRqSt8t+5qGIWlGQ==", "dev": true, "optional": true, "requires": { @@ -4682,7 +4684,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "sshpk": { @@ -4712,24 +4714,24 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=" + "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==" }, "statsd-parser": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", - "integrity": "sha1-y9JDlTzELv/VSLXSI4jtaJ7GOb0=" + "integrity": "sha512-7XO+ur89EalMXXFQaydsczB8sclr5nDsNIoUu0IzJx1pIbHUhO3LtpSzBwetIuU9DyTLMiVaJBMtWS/Nb2KR4g==" }, "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + "integrity": "sha512-Afuc4BKirbx0fwm9bKOehZPG01DJkm/4qbklw4lo9nMPqd2x0kZTLcgwQUXdGiPPY489l3w8cQ5xEEAGbg8ACQ==" }, "string-width": { "version": "4.2.0", @@ -4790,7 +4792,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, "strip-ansi": { "version": "5.2.0", @@ -4812,7 +4814,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true }, "strip-json-comments": { @@ -4869,7 +4871,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "string-width": { @@ -4888,7 +4890,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", + "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", "requires": { "bintrees": "1.0.1" } @@ -4913,19 +4915,19 @@ "text-encoding": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "integrity": "sha512-hJnc6Qg3dWoOMkqP53F0dzRIgtmsAge09kxUIqGrEUS4qr5rWLckGYaQAVr+opBrIMRErGgy6f5aPnyPpyGRfg==", "dev": true }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "through2": { "version": "2.0.5", @@ -4939,7 +4941,7 @@ "thunky": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", - "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + "integrity": "sha512-vquTt/sKNzFqFK8DKLg33U7deg93WKYH4CE2Ul9hOyMCfm7VXgM7GJQRpPAgnmgnrf407Fcq8TQVEKlbavAu+A==" }, "tmp": { "version": "0.0.33", @@ -4953,13 +4955,13 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, "to-mongodb-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + "integrity": "sha512-vfXXcGYFP8+0L5IPOtUzzVIvPE/G3GN0TKa/PRBlzPqYyhm+UxhPmvv634EQgO4Ot8dHbBFihOslMJQclY8Z9A==" }, "tough-cookie": { "version": "2.3.4", @@ -4980,19 +4982,19 @@ "tunnel-agent": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", - "integrity": "sha1-rWgbaPUyGtKCfEz7G31d8s/pQu4=", + "integrity": "sha512-jlGqHGoKzyyjhwv/c9omAgohntThMcGtw8RV/RDLlkbbc08kni/akVxO62N8HaXMVbVsK1NCnpSK3N2xCt22ww==", "dev": true, "optional": true }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", "dev": true, "requires": { "prelude-ls": "~1.1.2" @@ -5001,7 +5003,7 @@ "type-detect": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "integrity": "sha512-5rqszGVwYgBoDkIm2oUtvkfZMQ0vk29iDMU0W2qCa3rG0vPDNczCMT4hV/bLBgLg8k8ri6+u3Zbt+S/14eMzlA==", "dev": true }, "type-fest": { @@ -5013,7 +5015,7 @@ "type-is": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz", - "integrity": "sha1-0CReyLJnZmjVndDPMlUGBnalfbY=", + "integrity": "sha512-bGTRFAlk7i/YYyx/d1xYm6gLrALwTcY2HLwsVqAIPKJjjtlI/rGXRgjQrcOln2fcHCbAqi0hrueZ2yPnHvCipQ==", "requires": { "mime": "~1.2.11" } @@ -5027,7 +5029,7 @@ "underscore": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + "integrity": "sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==" }, "uri-js": { "version": "4.2.2", @@ -5047,12 +5049,12 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + "integrity": "sha512-HwU9SLQEtyo+0uoKXd1nkLqigUWLB+QuNQR4OcmB73eWqksM5ovuqcycks2x043W8XVb75rG1HQ0h93TMXkzQQ==" }, "v8-compile-cache": { "version": "2.1.0", @@ -5073,7 +5075,7 @@ "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -5083,7 +5085,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -5110,7 +5112,7 @@ "acorn-jsx": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", "dev": true, "requires": { "acorn": "^3.0.4" @@ -5119,7 +5121,7 @@ "acorn": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", "dev": true } } @@ -5173,7 +5175,7 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, "word-wrap": { @@ -5202,7 +5204,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "string-width": { @@ -5221,7 +5223,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write": { "version": "1.0.3", @@ -5235,7 +5237,7 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "integrity": "sha512-iTwvhNBRetXWe81+VcIw5YeadVSWyze7uA7nVnpP13ulrpnJ3UfQm5ApGnrkmxDJFdrblRdZs0EvaTCIfei5oQ==" }, "y18n": { "version": "4.0.0", @@ -5284,7 +5286,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "locate-path": { From 746791766c08e7ec17f6020578abeb67270af9ba Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:06:37 +0000 Subject: [PATCH 233/349] Additional prettier fix --- services/docstore/app/js/MongoManager.js | 1 - 1 file changed, 1 deletion(-) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 413f60be82..66699c9ba3 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -162,7 +162,6 @@ module.exports = MongoManager = { ) } } - ;[ 'findDoc', 'getProjectsDocs', From cfad4b585dc86074191464bae82fc21b3bdef27f Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Sun, 16 Feb 2020 14:10:24 +0000 Subject: [PATCH 234/349] Fix linting errors missed by bulk-decaffienate --- services/docstore/app.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index 725f1265c9..ebf7209b42 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -12,7 +12,6 @@ const express = require('express') const bodyParser = require('body-parser') const Errors = require('./app/js/Errors') const HttpController = require('./app/js/HttpController') -const Path = require('path') logger.initialize('docstore') if (Metrics.event_loop != null) { @@ -25,16 +24,16 @@ app.use(Metrics.http.monitor(logger)) Metrics.injectMetricsRoute(app) -app.param('project_id', function(req, res, next, project_id) { - if (project_id != null ? project_id.match(/^[0-9a-f]{24}$/) : undefined) { +app.param('project_id', function(req, res, next, projectId) { + if (projectId != null ? projectId.match(/^[0-9a-f]{24}$/) : undefined) { return next() } else { return next(new Error('invalid project id')) } }) -app.param('doc_id', function(req, res, next, doc_id) { - if (doc_id != null ? doc_id.match(/^[0-9a-f]{24}$/) : undefined) { +app.param('doc_id', function(req, res, next, docId) { + if (docId != null ? docId.match(/^[0-9a-f]{24}$/) : undefined) { return next() } else { return next(new Error('invalid doc id')) From e57545a532d87d57cbb8c8f7f94364e1b42a19bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2019 11:33:46 +0000 Subject: [PATCH 235/349] Bump express from 4.1.2 to 4.5.0 Bumps [express](https://github.com/expressjs/express) from 4.1.2 to 4.5.0. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.1.2...4.5.0) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 236 +++++++++++++++++++++------- services/docstore/package.json | 2 +- 2 files changed, 182 insertions(+), 56 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index fc2241cbd3..f878ea08df 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -529,12 +529,19 @@ } }, "accepts": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.1.tgz", - "integrity": "sha512-EsBDjbbGp44Tq6UGW6YE4cgD2xF1MIIyK7Vn+sElHW3EiSgqoIetsTiwFytb9YxODl6YVc4IIY28zeQ0JKGCLQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.7.tgz", + "integrity": "sha1-W1AftPBwQwmWTM2wSBclQSCNqxo=", "requires": { - "mime": "~1.2.11", - "negotiator": "~0.4.0" + "mime-types": "~1.0.0", + "negotiator": "0.4.7" + }, + "dependencies": { + "mime-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", + "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" + } } }, "acorn": { @@ -822,9 +829,9 @@ "integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ==" }, "buffer-crc32": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.1.tgz", - "integrity": "sha512-vMfBIRp/wjlpueSz7Sb0OmO7C5SH58SSmbsT8G4D48YfO/Zgbr29xNXMpZVSC14ujVJfrZZH1Bl+kXYRQPuvfQ==" + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.3.tgz", + "integrity": "sha1-u1RRnpXRB8vSQA520MqxRnM22SE=" }, "buffer-equal-constant-time": { "version": "1.0.1", @@ -1044,12 +1051,12 @@ "cookie": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", - "integrity": "sha512-+mHmWbhevLwkiBf7QcbZXHr0v4ZQQ/OgHk3fsQHrsMMiGzuvAmU/YMUR+ZfrO/BLAGIWFfx2Z7Oyso0tZR/wiA==" + "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" }, "cookie-signature": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.3.tgz", - "integrity": "sha512-/KzKzsm0OlguYov01OlOpTkX5MhBKUmfL/KMum7R80rPKheb9AwUzr78TwtBt1OdbnWrt4X+wxbTfcQ3noZqHw==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.4.tgz", + "integrity": "sha1-Dt0iKG46ERuaKnDbNj6SXoZ/aso=" }, "core-js": { "version": "3.6.4", @@ -1114,9 +1121,19 @@ } }, "debug": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz", - "integrity": "sha512-HlXEJm99YsRjLJ8xmuz0Lq8YUwrv7hAJkTEr6/Em3sUlSUNl0UdFA+1SrY4fnykeq1FVkUEUtwRGHs9VvlYbGA==" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.2.tgz", + "integrity": "sha1-OElZHBDM5khHbDx8Li40FttZY8Q=", + "requires": { + "ms": "0.6.2" + }, + "dependencies": { + "ms": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", + "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" + } + } }, "decamelize": { "version": "1.2.0", @@ -1160,6 +1177,11 @@ "dev": true, "optional": true }, + "depd": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-0.3.0.tgz", + "integrity": "sha1-Ecm8KOQlMl+9iziUC+/2n6UyaIM=" + }, "dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -1215,6 +1237,11 @@ "safe-buffer": "^5.0.1" } }, + "ee-first": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.0.3.tgz", + "integrity": "sha1-bJjECJq+y1p7hcGsRJqmA9Oz2r4=" + }, "emitter-listener": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", @@ -1304,7 +1331,7 @@ "escape-html": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "integrity": "sha512-z6kAnok8fqVTra7Yu77dZF2Y6ETJlxH58wN38wNyuNQLm8xXdKnfNrlSmfXsTePWP03rRVUKHubtUwanwUi7+g==" + "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" }, "escape-string-regexp": { "version": "1.0.5", @@ -1766,27 +1793,48 @@ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, "express": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.1.2.tgz", - "integrity": "sha512-U7G/TwoXu9uSHtGnvW6WQyLz3rP+qp3sHUiNpKw5Mz2o6DGenpxngH5tGnxgg09Hjqzje2CzZKukPoZfemepYQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.5.1.tgz", + "integrity": "sha1-S8Pm7J2yjldf5ZHDb7t4H/72/nw=", "requires": { - "accepts": "1.0.1", - "buffer-crc32": "0.2.1", + "accepts": "~1.0.7", + "buffer-crc32": "0.2.3", "cookie": "0.1.2", - "cookie-signature": "1.0.3", - "debug": ">= 0.7.3 < 1", + "cookie-signature": "1.0.4", + "debug": "1.0.2", + "depd": "0.3.0", "escape-html": "1.0.1", + "finalhandler": "0.0.2", "fresh": "0.2.2", + "media-typer": "0.2.0", "merge-descriptors": "0.0.2", - "methods": "0.1.0", + "methods": "1.0.1", "parseurl": "1.0.1", "path-to-regexp": "0.1.2", + "proxy-addr": "1.0.1", "qs": "0.6.6", "range-parser": "1.0.0", - "send": "0.3.0", - "serve-static": "1.1.0", - "type-is": "1.1.0", - "utils-merge": "1.0.0" + "send": "0.5.0", + "serve-static": "~1.3.0", + "type-is": "~1.3.2", + "utils-merge": "1.0.0", + "vary": "0.1.0" + }, + "dependencies": { + "mime-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", + "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" + }, + "type-is": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.3.2.tgz", + "integrity": "sha1-TypdxYd1yhYwJQr8cYb4s2MJ0bs=", + "requires": { + "media-typer": "0.2.0", + "mime-types": "~1.0.1" + } + } } }, "extend": { @@ -1860,6 +1908,15 @@ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, + "finalhandler": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.0.2.tgz", + "integrity": "sha1-BgPYde6H1WeiZmkoFcyK1E/M7to=", + "requires": { + "debug": "1.0.2", + "escape-html": "1.0.1" + } + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -1874,6 +1931,14 @@ "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" }, + "finished": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/finished/-/finished-1.2.2.tgz", + "integrity": "sha1-QWCOr639ZWg7RqEiC8Sx7D2u3Ng=", + "requires": { + "ee-first": "1.0.3" + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -1973,7 +2038,7 @@ "fresh": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", - "integrity": "sha512-ZGGi8GROK//ijm2gB33sUuN9TjN1tC/dvG4Bt4j6IWrVGpMmudUBCxx+Ir7qePsdREfkpQC4FL8W0jeSOsgv1w==" + "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" }, "fs.realpath": { "version": "1.0.0", @@ -2334,6 +2399,11 @@ "side-channel": "^1.0.2" } }, + "ipaddr.js": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-0.1.2.tgz", + "integrity": "sha1-ah/T2FT1ACllw017vNm0qNSwRn4=" + }, "is": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", @@ -2875,10 +2945,15 @@ "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, + "media-typer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.2.0.tgz", + "integrity": "sha1-2KBlITrf6qLnYyGitt2jb/YzWYQ=" + }, "merge-descriptors": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", - "integrity": "sha512-dYBT4Ep+t/qnPeJcnMymmhTdd4g8/hn48ciaDqLAkfRf8abzLPS6Rb6EBdz5CZCL8tzZuI5ps9MhGQGxk+EuKg==" + "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" }, "mersenne": { "version": "0.0.4", @@ -2909,9 +2984,9 @@ "dev": true }, "methods": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/methods/-/methods-0.1.0.tgz", - "integrity": "sha512-N4cn4CbDqu7Fp3AT4z3AsO19calgczhsmCGzXLCiUOrWg9sjb1B+yKFKOrnnPGKKvjyJBmw+k6b3adFN2LbuBw==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.0.1.tgz", + "integrity": "sha1-dbyRlD3/19oDfPPusO1zoAN80Us=" }, "metrics-sharelatex": { "version": "2.2.0", @@ -3155,9 +3230,9 @@ "optional": true }, "negotiator": { - "version": "0.4.9", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.9.tgz", - "integrity": "sha512-fvi5GQce2TGDzanaTxNY3bboxjdce18sqwNylY439wkEkiJIyTMhGFMdlPCvDsIPa9IKIfhKwCMWEQ9YpZgb1Q==" + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.7.tgz", + "integrity": "sha1-pBYPcXfsgGc4Yx0NMFIyXaQqvcg=" }, "nice-try": { "version": "1.0.5", @@ -3408,7 +3483,7 @@ "parseurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", - "integrity": "sha512-6W9+0+9Ihayqwjgp4OaLLqZ3KDtqPY2PtUPz8YNiy4PamjJv+7x6J9GO93O9rUZOLgaanTPxsKTasxqKkO1iSw==" + "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" }, "path-exists": { "version": "3.0.0", @@ -3441,7 +3516,7 @@ "path-to-regexp": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", - "integrity": "sha512-BZU7Qr+qKkXJX9UBypMNikdZ85cQSjtfMhUykJFLJn4SNF0jhEbb9nMRpnNdA76ESryY8JpMA4k6XKdz3JS1pw==" + "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" }, "path-type": { "version": "2.0.0", @@ -4147,6 +4222,14 @@ } } }, + "proxy-addr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.1.tgz", + "integrity": "sha1-x8Vm1etOP61n7rnHfFVYzMObiKg=", + "requires": { + "ipaddr.js": "0.1.2" + } + }, "psl": { "version": "1.1.32", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", @@ -4177,7 +4260,7 @@ "range-parser": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", - "integrity": "sha512-wOH5LIH2ZHo0P7/bwkR+aNbJ+kv3CHVX4B8qs9GqbtY29fi1bGPV5xczrutN20G+Z4XhRqRMTW3q0S4iyJJPfw==" + "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" }, "raven": { "version": "1.1.3", @@ -4477,31 +4560,69 @@ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "send": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.3.0.tgz", - "integrity": "sha512-FPyeqtit9Z3zbusjv0KQyR8vQ9CL57qPNOz4GgcuIPSk+nx9WTUIMQoR6+0a7YOZpQVTtk04qH0IVQG3rohZ0Q==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.5.0.tgz", + "integrity": "sha1-/A9+L5Limuv9ihst60o5TnpTGmg=", "requires": { - "buffer-crc32": "0.2.1", - "debug": "0.8.0", - "fresh": "~0.2.1", + "debug": "1.0.2", + "escape-html": "1.0.1", + "finished": "1.2.2", + "fresh": "0.2.2", "mime": "1.2.11", + "ms": "0.6.2", "range-parser": "~1.0.0" }, "dependencies": { - "debug": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.0.tgz", - "integrity": "sha512-jR+JRuwlhTwNPpLU6/JhiMydD6+GnL/33WE8LlmnBUqPHXkEpG2iNargYBO/Wxx7wXn7oxU6XwYIZyH4YuSW9Q==" + "ms": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", + "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" } } }, "serve-static": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.1.0.tgz", - "integrity": "sha512-vzgWiHz5xrM19pqugiYI6sWP9B0+K6vz4Ep5G1my9lVhuYkRXGYs5xtnXZ06fpLPRumROSZ1CLqiRxdngPkojQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.3.2.tgz", + "integrity": "sha1-2QSmy/VfURx4E49vRe5uadnRBco=", "requires": { - "parseurl": "1.0.1", - "send": "0.3.0" + "escape-html": "1.0.1", + "parseurl": "~1.1.3", + "send": "0.6.0" + }, + "dependencies": { + "debug": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.3.tgz", + "integrity": "sha1-/IxrLWACgEtAgcAgjg9kYLofo+Q=", + "requires": { + "ms": "0.6.2" + } + }, + "ms": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", + "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" + }, + "parseurl": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.1.3.tgz", + "integrity": "sha1-HwBXOKxxtBe8LQhFy9+iqLY+pjk=" + }, + "send": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.6.0.tgz", + "integrity": "sha1-pZ2pJl23w1FB4Qec8fNo7g1Zs6s=", + "requires": { + "debug": "1.0.3", + "depd": "0.3.0", + "escape-html": "1.0.1", + "finished": "1.2.2", + "fresh": "0.2.2", + "mime": "1.2.11", + "ms": "0.6.2", + "range-parser": "~1.0.0" + } + } } }, "set-blocking": { @@ -5054,7 +5175,7 @@ "utils-merge": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha512-HwU9SLQEtyo+0uoKXd1nkLqigUWLB+QuNQR4OcmB73eWqksM5ovuqcycks2x043W8XVb75rG1HQ0h93TMXkzQQ==" + "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" }, "v8-compile-cache": { "version": "2.1.0", @@ -5072,6 +5193,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "vary": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vary/-/vary-0.1.0.tgz", + "integrity": "sha1-3wlFiZ6TwMxb0YzIMh2dIedPYXY=" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", diff --git a/services/docstore/package.json b/services/docstore/package.json index a0b8b1e842..2b2c934d88 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -21,7 +21,7 @@ "dependencies": { "async": "~0.8.0", "body-parser": "~1.0.2", - "express": "~4.1.1", + "express": "~4.5.0", "logger-sharelatex": "^1.7.0", "metrics-sharelatex": "^2.2.0", "mongojs": "2.4.0", From fbece45717d973b370c176b98f596ba811a42945 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2019 11:33:46 +0000 Subject: [PATCH 236/349] Bump request from 2.34.0 to 2.47.0 Bumps [request](https://github.com/request/request) from 2.34.0 to 2.47.0. - [Release notes](https://github.com/request/request/releases) - [Changelog](https://github.com/request/request/blob/master/CHANGELOG.md) - [Commits](https://github.com/request/request/compare/v2.34.0...v2.47.0) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 250 +++++++++++++++++----------- services/docstore/package.json | 2 +- 2 files changed, 155 insertions(+), 97 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index f878ea08df..f241983350 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -531,7 +531,7 @@ "accepts": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.7.tgz", - "integrity": "sha1-W1AftPBwQwmWTM2wSBclQSCNqxo=", + "integrity": "sha512-iq8ew2zitUlNcUca0wye3fYwQ6sSPItDo38oC0R+XA5KTzeXRN+GF7NjOXs3dVItj4J+gQVdpq4/qbnMb1hMHw==", "requires": { "mime-types": "~1.0.0", "negotiator": "0.4.7" @@ -540,7 +540,7 @@ "mime-types": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", - "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" + "integrity": "sha512-echfutj/t5SoTL4WZpqjA1DCud1XO0WQF3/GJ48YBmc4ZMhCK77QA6Z/w6VTQERLKuJ4drze3kw2TUT8xZXVNw==" } } }, @@ -646,16 +646,14 @@ "asn1": { "version": "0.1.11", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "integrity": "sha512-Fh9zh3G2mZ8qM/kwsiKwL2U2FmXxVsboP4x1mXjnhKHv3SmzaBZoYvxEQJz/YS2gnCgd8xlAVWcZnQyC9qZBsA==", - "dev": true, - "optional": true + "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", + "dev": true }, "assert-plus": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha512-brU24g7ryhRwGCI2y+1dGQmQXiZF7TtIj583S96y0jjdajIe6wn8BuXyELYhvD22dtIxDQVFk04YTJwwdwOYJw==", - "dev": true, - "optional": true + "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", + "dev": true }, "assertion-error": { "version": "1.0.0", @@ -697,9 +695,8 @@ "aws-sign2": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "integrity": "sha512-oqUX0DM5j7aPWPCnpWebiyNIj2wiNI87ZxnOMoGv0aE4TGlBy2N+5iWc6dQ/NOKZaBD2W6PVz8jtOGkWzSC5EA==", - "dev": true, - "optional": true + "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", + "dev": true }, "aws4": { "version": "1.8.0", @@ -782,6 +779,35 @@ "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" }, + "bl": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", + "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", + "dev": true, + "requires": { + "readable-stream": "~1.0.26" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, "body-parser": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz", @@ -801,9 +827,8 @@ "boom": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "integrity": "sha512-OvfN8y1oAxxphzkl2SnCS+ztV/uVKTATtgLjWYg/7KwcNyf3rzpHxNQJZCKtsZd4+MteKczhWbSjtEX4bGgU9g==", + "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", "dev": true, - "optional": true, "requires": { "hoek": "0.9.x" } @@ -831,7 +856,7 @@ "buffer-crc32": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.3.tgz", - "integrity": "sha1-u1RRnpXRB8vSQA520MqxRnM22SE=" + "integrity": "sha512-HLvoSqq1z8fJEcT1lUlJZ4OJaXJZ1wsWm0+fBxkz9Bdf/WphA4Da7FtGUguNNyEXL4WB0hNMTaWmdFRFPy8YOQ==" }, "buffer-equal-constant-time": { "version": "1.0.1", @@ -1004,9 +1029,8 @@ "combined-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "integrity": "sha512-qfexlmLp9MyrkajQVyjEDb0Vj+KhRgR/rxLiVhaihlT+ZkX0lReqtH6Ack40CvMDERR4b5eFp3CreskpBs1Pig==", + "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", "dev": true, - "optional": true, "requires": { "delayed-stream": "0.0.5" } @@ -1051,12 +1075,12 @@ "cookie": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", - "integrity": "sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE=" + "integrity": "sha512-+mHmWbhevLwkiBf7QcbZXHr0v4ZQQ/OgHk3fsQHrsMMiGzuvAmU/YMUR+ZfrO/BLAGIWFfx2Z7Oyso0tZR/wiA==" }, "cookie-signature": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.4.tgz", - "integrity": "sha1-Dt0iKG46ERuaKnDbNj6SXoZ/aso=" + "integrity": "sha512-k+lrG38ZC/S7zN6l1/HcF6xF4jMwkIUjnr5afDU7tzFxIfDmKzdqJdXo8HNYaXOuBJ3tPKxSiwCOTA0b3qQfaA==" }, "core-js": { "version": "3.6.4", @@ -1085,9 +1109,8 @@ "cryptiles": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "integrity": "sha512-gvWSbgqP+569DdslUiCelxIv3IYK5Lgmq1UrRnk+s1WxQOQ16j3GPDcjdtgL5Au65DU/xQi6q3xPtf5Kta+3IQ==", + "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", "dev": true, - "optional": true, "requires": { "boom": "0.4.x" } @@ -1095,9 +1118,8 @@ "ctype": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "integrity": "sha512-T6CEkoSV4q50zW3TlTHMbzy1E5+zlnNcY+yb7tWVYlTwPhx9LpnfAkd4wecpWknDyptp4k97LUZeInlf6jdzBg==", - "dev": true, - "optional": true + "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", + "dev": true }, "damerau-levenshtein": { "version": "1.0.6", @@ -1123,7 +1145,7 @@ "debug": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.2.tgz", - "integrity": "sha1-OElZHBDM5khHbDx8Li40FttZY8Q=", + "integrity": "sha512-T9bufXIzQvCa4VrTIpLvvwdLhH+wuBtvIJJA3xgzVcaVETGmTIWMfEXQEd1K4p8BaRmQJPn6MPut38H7YQ+iIA==", "requires": { "ms": "0.6.2" }, @@ -1131,7 +1153,7 @@ "ms": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" + "integrity": "sha512-/pc3eh7TWorTtbvXg8je4GvrvEqCfH7PA3P7iW01yL2E53FKixzgMBaQi0NOPbMJqY34cBSvR0tZtmlTkdUG4A==" } } }, @@ -1173,14 +1195,13 @@ "delayed-stream": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "integrity": "sha512-v+7uBd1pqe5YtgPacIIbZ8HuHeLFVNe4mUEyFDXL6KiqzEykjbw+5mXZXpGFgNVasdL4jWKgaKIXrEHiynN1LA==", - "dev": true, - "optional": true + "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", + "dev": true }, "depd": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/depd/-/depd-0.3.0.tgz", - "integrity": "sha1-Ecm8KOQlMl+9iziUC+/2n6UyaIM=" + "integrity": "sha512-Uyx3FgdvEYlpA3W4lf37Ide++2qOsjLlJ7dap0tbM63j/BxTCcxmyIOO6PXbKbOuNSko+fsDHzzx1DUeo1+3fA==" }, "dlv": { "version": "1.1.3", @@ -1240,7 +1261,7 @@ "ee-first": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.0.3.tgz", - "integrity": "sha1-bJjECJq+y1p7hcGsRJqmA9Oz2r4=" + "integrity": "sha512-1q/3kz+ZwmrrWpJcCCrBZ3JnBzB1BMA5EVW9nxnIP1LxDZ16Cqs9VdolqLWlExet1vU+bar3WSkAa4/YrA9bIw==" }, "emitter-listener": { "version": "1.1.2", @@ -1331,7 +1352,7 @@ "escape-html": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "integrity": "sha1-GBoobq05ejmpKFfPsdQwUuNWv/A=" + "integrity": "sha512-z6kAnok8fqVTra7Yu77dZF2Y6ETJlxH58wN38wNyuNQLm8xXdKnfNrlSmfXsTePWP03rRVUKHubtUwanwUi7+g==" }, "escape-string-regexp": { "version": "1.0.5", @@ -1795,7 +1816,7 @@ "express": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/express/-/express-4.5.1.tgz", - "integrity": "sha1-S8Pm7J2yjldf5ZHDb7t4H/72/nw=", + "integrity": "sha512-36quUqw4ZqgDnQzQpYLnNphPx612kfmQjbZlFt9Mz6Up/27IhkACtYBG9L/dAZkrXD0il3cq58DU+lpSL/Bg1g==", "requires": { "accepts": "~1.0.7", "buffer-crc32": "0.2.3", @@ -1824,12 +1845,12 @@ "mime-types": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", - "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=" + "integrity": "sha512-echfutj/t5SoTL4WZpqjA1DCud1XO0WQF3/GJ48YBmc4ZMhCK77QA6Z/w6VTQERLKuJ4drze3kw2TUT8xZXVNw==" }, "type-is": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.3.2.tgz", - "integrity": "sha1-TypdxYd1yhYwJQr8cYb4s2MJ0bs=", + "integrity": "sha512-sdIhnvhWEyIP2DKjj1o9tL31m8vFxDfLPD56KXz2absqY5AF2QYkJC7Wrw2fkzsZA9mv+PCtgyB7EqYOgR+r3Q==", "requires": { "media-typer": "0.2.0", "mime-types": "~1.0.1" @@ -1911,7 +1932,7 @@ "finalhandler": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.0.2.tgz", - "integrity": "sha1-BgPYde6H1WeiZmkoFcyK1E/M7to=", + "integrity": "sha512-SbpQfvWVwWEBlPTQyaM9gs0D5404ENTC0x2jzbb7t+P+EOD/cBlWjAAvfozIQYtOepUuNkxoLNLCK9/kS29f4w==", "requires": { "debug": "1.0.2", "escape-html": "1.0.1" @@ -1934,7 +1955,7 @@ "finished": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/finished/-/finished-1.2.2.tgz", - "integrity": "sha1-QWCOr639ZWg7RqEiC8Sx7D2u3Ng=", + "integrity": "sha512-HPJ8x7Gn1pmTS1zWyMoXmQ1yxHkYHRoFsBI66ONq4PS9iWBJy1iHYXOSqMWNp3ksMXfrBpenkSwBhl9WG4zr4Q==", "requires": { "ee-first": "1.0.3" } @@ -2002,15 +2023,14 @@ "forever-agent": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "integrity": "sha512-PDG5Ef0Dob/JsZUxUltJOhm/Y9mlteAE+46y3M9RBz/Rd3QVENJ75aGRhN56yekTUboaBIkd8KVWX2NjF6+91A==", + "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=", "dev": true }, "form-data": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "integrity": "sha512-x8eE+nzFtAMA0YYlSxf/Qhq6vP1f8wSoZ7Aw1GuctBcmudCNuTUmmx45TfEplyb6cjsZO/jvh6+1VpZn24ez+w==", + "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", "dev": true, - "optional": true, "requires": { "async": "~0.9.0", "combined-stream": "~0.0.4", @@ -2020,9 +2040,8 @@ "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw==", - "dev": true, - "optional": true + "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", + "dev": true } } }, @@ -2038,7 +2057,7 @@ "fresh": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", - "integrity": "sha1-lzHc9WeMf660T7kDxPct9VGH+nc=" + "integrity": "sha512-ZGGi8GROK//ijm2gB33sUuN9TjN1tC/dvG4Bt4j6IWrVGpMmudUBCxx+Ir7qePsdREfkpQC4FL8W0jeSOsgv1w==" }, "fs.realpath": { "version": "1.0.0", @@ -2236,11 +2255,10 @@ "dev": true }, "hawk": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.0.0.tgz", - "integrity": "sha512-Sg+VzrI7TjUomO0rjD6UXawsj50ykn5sB/xKNW/IenxzRVyw/wt9A2FLzYpGL/r0QG5hyXY8nLx/2m8UutoDcg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", + "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", "dev": true, - "optional": true, "requires": { "boom": "0.4.x", "cryptiles": "0.2.x", @@ -2262,9 +2280,8 @@ "hoek": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "integrity": "sha512-ZZ6eGyzGjyMTmpSPYVECXy9uNfqBR7x5CavhUaLOeD6W0vWK1mp/b7O3f86XE0Mtfo9rZ6Bh3fnuw9Xr8MF9zA==", - "dev": true, - "optional": true + "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", + "dev": true }, "hosted-git-info": { "version": "2.8.5", @@ -2275,9 +2292,8 @@ "http-signature": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "integrity": "sha512-coK8uR5rq2IMj+Hen+sKPA5ldgbCc1/spPdKCL1Fw6h+D0s/2LzMcRK0Cqufs1h0ryx/niwBHGFu8HC3hwU+lA==", + "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", "dev": true, - "optional": true, "requires": { "asn1": "0.1.11", "assert-plus": "^0.1.5", @@ -2399,10 +2415,16 @@ "side-channel": "^1.0.2" } }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, "ipaddr.js": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-0.1.2.tgz", - "integrity": "sha1-ah/T2FT1ACllw017vNm0qNSwRn4=" + "integrity": "sha512-MGrEjHz4Hk5UVpJXZQ2tHB+bp6xgdRKCAEWdrgFsoAmXCgKAPtj8LqMxgvlWEAj9aN+PpTcvE051uZU3K3kLSQ==" }, "is": { "version": "3.3.0", @@ -2948,12 +2970,12 @@ "media-typer": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.2.0.tgz", - "integrity": "sha1-2KBlITrf6qLnYyGitt2jb/YzWYQ=" + "integrity": "sha512-TSggxYk75oP4tae7JkT8InpcFGUP4340zg1dOWjcu9qcphaDKtXEuNUv3OD4vJ+gVTvIDK797W0uYeNm8qqsDg==" }, "merge-descriptors": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", - "integrity": "sha1-w2pSp4FDdRPFcnXzndnTF1FKyMc=" + "integrity": "sha512-dYBT4Ep+t/qnPeJcnMymmhTdd4g8/hn48ciaDqLAkfRf8abzLPS6Rb6EBdz5CZCL8tzZuI5ps9MhGQGxk+EuKg==" }, "mersenne": { "version": "0.0.4", @@ -2986,7 +3008,7 @@ "methods": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/methods/-/methods-1.0.1.tgz", - "integrity": "sha1-dbyRlD3/19oDfPPusO1zoAN80Us=" + "integrity": "sha512-2403MfnVypWSNIEpmQ26/ObZ5kSUx37E8NHRvriw0+I8Sne7k0HGuLGCk0OrCqURh4UIygD0cSsYq+Ll+kzNqA==" }, "metrics-sharelatex": { "version": "2.2.0", @@ -3232,7 +3254,7 @@ "negotiator": { "version": "0.4.7", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.7.tgz", - "integrity": "sha1-pBYPcXfsgGc4Yx0NMFIyXaQqvcg=" + "integrity": "sha512-ujxWwyRfZ6udAgHGECQC3JDO9e6UAsuItfUMcqA0Xf2OLNQTveFVFx+fHGIJ5p0MJaJrZyGQqPwzuN0NxJzEKA==" }, "nice-try": { "version": "1.0.5", @@ -3283,7 +3305,7 @@ "node-uuid": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", "dev": true }, "normalize-package-data": { @@ -3299,11 +3321,10 @@ } }, "oauth-sign": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.3.0.tgz", - "integrity": "sha512-Tr31Sh5FnK9YKm7xTUPyDMsNOvMqkVDND0zvK/Wgj7/H9q8mpye0qG2nVzrnsvLhcsX5DtqXD0la0ks6rkPCGQ==", - "dev": true, - "optional": true + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.4.0.tgz", + "integrity": "sha1-8ilW8x6nFRqCHl8vsywRPK2Ln2k=", + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3483,7 +3504,7 @@ "parseurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", - "integrity": "sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q=" + "integrity": "sha512-6W9+0+9Ihayqwjgp4OaLLqZ3KDtqPY2PtUPz8YNiy4PamjJv+7x6J9GO93O9rUZOLgaanTPxsKTasxqKkO1iSw==" }, "path-exists": { "version": "3.0.0", @@ -3516,7 +3537,7 @@ "path-to-regexp": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", - "integrity": "sha1-mysVH5zDAYye6lDKlXKeBXgXErQ=" + "integrity": "sha512-BZU7Qr+qKkXJX9UBypMNikdZ85cQSjtfMhUykJFLJn4SNF0jhEbb9nMRpnNdA76ESryY8JpMA4k6XKdz3JS1pw==" }, "path-type": { "version": "2.0.0", @@ -4225,7 +4246,7 @@ "proxy-addr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.1.tgz", - "integrity": "sha1-x8Vm1etOP61n7rnHfFVYzMObiKg=", + "integrity": "sha512-rIUGzBlSfkJMWWCgsd4N5wvVSNAcJZg//UwPZumDIbScHRUzuSOjBmIdyICiKkB9yArv+er9qC6RA/NL3AWc6A==", "requires": { "ipaddr.js": "0.1.2" } @@ -4260,7 +4281,7 @@ "range-parser": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", - "integrity": "sha1-pLJkz+C+XONqvjdlrJwqJIdG28A=" + "integrity": "sha512-wOH5LIH2ZHo0P7/bwkR+aNbJ+kv3CHVX4B8qs9GqbtY29fi1bGPV5xczrutN20G+Z4XhRqRMTW3q0S4iyJJPfw==" }, "raven": { "version": "1.1.3", @@ -4374,23 +4395,47 @@ "dev": true }, "request": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.34.0.tgz", - "integrity": "sha512-mD5mNhfkeaKMg5ZY/hZFbW4lyC/NTn34/ILGQr/XLSuxYOE6vJfL0MTPPXZcZrdt+Nh1Kce+f4B4KbGThIETxQ==", + "version": "2.47.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.47.0.tgz", + "integrity": "sha1-Cen9Gk/tZZOoBe+CArIPDF7LSF8=", "dev": true, "requires": { "aws-sign2": "~0.5.0", + "bl": "~0.9.0", + "caseless": "~0.6.0", + "combined-stream": "~0.0.5", "forever-agent": "~0.5.0", "form-data": "~0.1.0", - "hawk": "~1.0.0", + "hawk": "1.1.1", "http-signature": "~0.10.0", "json-stringify-safe": "~5.0.0", - "mime": "~1.2.9", + "mime-types": "~1.0.1", "node-uuid": "~1.4.0", - "oauth-sign": "~0.3.0", - "qs": "~0.6.0", + "oauth-sign": "~0.4.0", + "qs": "~2.3.1", + "stringstream": "~0.0.4", "tough-cookie": ">=0.12.0", - "tunnel-agent": "~0.3.0" + "tunnel-agent": "~0.4.0" + }, + "dependencies": { + "caseless": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.6.0.tgz", + "integrity": "sha1-gWfBq4OX+1u5X5bSjlqBxQ8kesQ=", + "dev": true + }, + "mime-types": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", + "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=", + "dev": true + }, + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } } }, "require-directory": { @@ -4562,7 +4607,7 @@ "send": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/send/-/send-0.5.0.tgz", - "integrity": "sha1-/A9+L5Limuv9ihst60o5TnpTGmg=", + "integrity": "sha512-uuPWJQK6p0btveYhOxRqvcB9Cfcs9ugNrMd0SoM/tqzOC9A86bX4rDEQN84X3Cc5Gpo5Az2cB4Olo5c3Aso2Sg==", "requires": { "debug": "1.0.2", "escape-html": "1.0.1", @@ -4576,14 +4621,14 @@ "ms": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" + "integrity": "sha512-/pc3eh7TWorTtbvXg8je4GvrvEqCfH7PA3P7iW01yL2E53FKixzgMBaQi0NOPbMJqY34cBSvR0tZtmlTkdUG4A==" } } }, "serve-static": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.3.2.tgz", - "integrity": "sha1-2QSmy/VfURx4E49vRe5uadnRBco=", + "integrity": "sha512-KwjCeYUx7IM1neg8/P0+O1DZsl76XcOSuV0ZxrI0r60vwGlcjMjKOYCK/OFLJy/a2CFuIyAa/x0PuQ0yuG+IgQ==", "requires": { "escape-html": "1.0.1", "parseurl": "~1.1.3", @@ -4593,7 +4638,7 @@ "debug": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.3.tgz", - "integrity": "sha1-/IxrLWACgEtAgcAgjg9kYLofo+Q=", + "integrity": "sha512-MltK7Ykj/udtD728gD/RrONStwVnDpBNIP1h+CBcnwnJdHqHxfWHI1E8XLootUl7NOPAYTCCXlb8/Qmy7WyB1w==", "requires": { "ms": "0.6.2" } @@ -4601,17 +4646,17 @@ "ms": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw=" + "integrity": "sha512-/pc3eh7TWorTtbvXg8je4GvrvEqCfH7PA3P7iW01yL2E53FKixzgMBaQi0NOPbMJqY34cBSvR0tZtmlTkdUG4A==" }, "parseurl": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.1.3.tgz", - "integrity": "sha1-HwBXOKxxtBe8LQhFy9+iqLY+pjk=" + "integrity": "sha512-7y9IL/9x2suvr1uIvoAc3yv3f28hZ55g2OM+ybEtnZqV6Ykeg36sy1PCsTN9rQUZYzb9lTKLzzmJM11jaXSloA==" }, "send": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/send/-/send-0.6.0.tgz", - "integrity": "sha1-pZ2pJl23w1FB4Qec8fNo7g1Zs6s=", + "integrity": "sha512-A3EwHmDwcPcmLxIRNjr2YbXiYWq6M9JyUq4303pLKVFs4m5oeME0a9Cpcu9N22fED5XVepldjPYGo9eJifb7Yg==", "requires": { "debug": "1.0.3", "depd": "0.3.0", @@ -4750,9 +4795,8 @@ "sntp": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "integrity": "sha512-bDLrKa/ywz65gCl+LmOiIhteP1bhEsAAzhfMedPoiHP3dyYnAevlaJshdqb9Yu0sRifyP/fRqSt8t+5qGIWlGQ==", + "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", "dev": true, - "optional": true, "requires": { "hoek": "0.9.x" } @@ -4915,6 +4959,12 @@ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" }, + "stringstream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", + "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", + "dev": true + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -5085,13 +5135,22 @@ "integrity": "sha512-vfXXcGYFP8+0L5IPOtUzzVIvPE/G3GN0TKa/PRBlzPqYyhm+UxhPmvv634EQgO4Ot8dHbBFihOslMJQclY8Z9A==" }, "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "dev": true, - "optional": true, "requires": { - "punycode": "^1.4.1" + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } } }, "tslib": { @@ -5101,11 +5160,10 @@ "dev": true }, "tunnel-agent": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.3.0.tgz", - "integrity": "sha512-jlGqHGoKzyyjhwv/c9omAgohntThMcGtw8RV/RDLlkbbc08kni/akVxO62N8HaXMVbVsK1NCnpSK3N2xCt22ww==", - "dev": true, - "optional": true + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", + "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", + "dev": true }, "tweetnacl": { "version": "0.14.5", @@ -5175,7 +5233,7 @@ "utils-merge": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=" + "integrity": "sha512-HwU9SLQEtyo+0uoKXd1nkLqigUWLB+QuNQR4OcmB73eWqksM5ovuqcycks2x043W8XVb75rG1HQ0h93TMXkzQQ==" }, "v8-compile-cache": { "version": "2.1.0", @@ -5196,7 +5254,7 @@ "vary": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/vary/-/vary-0.1.0.tgz", - "integrity": "sha1-3wlFiZ6TwMxb0YzIMh2dIedPYXY=" + "integrity": "sha512-tyyeG46NQdwyVP/RsWLSrT78ouwEuvwk9gK8vQK4jdXmqoXtTXW+vsCfNcnqRhigF8olV34QVZarmAi6wBV2Mw==" }, "verror": { "version": "1.10.0", diff --git a/services/docstore/package.json b/services/docstore/package.json index 2b2c934d88..82d2e34426 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -50,7 +50,7 @@ "mocha": "^4.0.1", "prettier": "^1.19.1", "prettier-eslint-cli": "^5.0.0", - "request": "~2.34.0", + "request": "~2.47.0", "sandboxed-module": "~0.3.0", "sinon": "~3.2.1" }, From f8a5feae18d16169f59bb6545bba7cf69a3bdd2d Mon Sep 17 00:00:00 2001 From: Eric Mc Sween <eric.mcsween@overleaf.com> Date: Mon, 9 Mar 2020 08:36:59 -0400 Subject: [PATCH 237/349] Make max doc length configurable via an env variable --- services/docstore/config/settings.defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 92bf08e324..d22ff8fee1 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -22,7 +22,7 @@ const Settings = { } }, - max_doc_length: 2 * 1024 * 1024 // 2mb + max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024 // 2mb } if (process.env.MONGO_CONNECTION_STRING != null) { From 9f88236f31d878832c66367dac821252753f9dbe Mon Sep 17 00:00:00 2001 From: mserranom <mserranom@gmail.com> Date: Mon, 23 Mar 2020 12:30:16 +0100 Subject: [PATCH 238/349] updated build scripts --- services/docstore/package-lock.json | 882 ++++++++++++++++------------ services/docstore/package.json | 4 +- 2 files changed, 495 insertions(+), 391 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index f241983350..5b5e7d5132 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -244,7 +244,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, "gcp-metadata": { "version": "0.9.3", @@ -341,7 +341,7 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" }, "@protobufjs/base64": { "version": "1.1.2", @@ -356,12 +356,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -370,42 +370,67 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "@sindresorhus/is": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.15.0.tgz", "integrity": "sha512-lu8BpxjAtRCAo5ifytTpCPCj99LF7o/2Myn+NXyNCBqvPYn7Pjd76AMmUB5l7XF1U6t0hcWrlEM5ESufW7wAeA==" }, - "@sinonjs/formatio": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", - "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", + "@sinonjs/commons": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", + "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", "dev": true, "requires": { - "samsam": "1.3.0" + "type-detect": "4.0.8" + }, + "dependencies": { + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + } } }, + "@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, "@types/caseless": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", @@ -529,19 +554,12 @@ } }, "accepts": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.0.7.tgz", - "integrity": "sha512-iq8ew2zitUlNcUca0wye3fYwQ6sSPItDo38oC0R+XA5KTzeXRN+GF7NjOXs3dVItj4J+gQVdpq4/qbnMb1hMHw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "requires": { - "mime-types": "~1.0.0", - "negotiator": "0.4.7" - }, - "dependencies": { - "mime-types": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", - "integrity": "sha512-echfutj/t5SoTL4WZpqjA1DCud1XO0WQF3/GJ48YBmc4ZMhCK77QA6Z/w6VTQERLKuJ4drze3kw2TUT8xZXVNw==" - } + "mime-types": "~2.1.24", + "negotiator": "0.6.2" } }, "acorn": { @@ -566,7 +584,7 @@ "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "integrity": "sha1-kNDVRDnaWHzX6EO/twRfUL0ivfE=", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -617,6 +635,17 @@ "commander": "^2.11.0" } }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, "array-includes": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", @@ -641,7 +670,7 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" + "integrity": "sha1-yWVekzHgq81YjSp8rX6ZVvZnAfo=" }, "asn1": { "version": "0.1.11", @@ -658,7 +687,7 @@ "assertion-error": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "integrity": "sha512-g/gZV+G476cnmtYI+Ko9d5khxSoCSoom/EaNmmCfwpOvBXEJ18qwFrxfP1/CsIqk2no1sAKKwxndV0tP7ROOFQ==", + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", "dev": true }, "ast-types-flow": { @@ -676,7 +705,7 @@ "async": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz", - "integrity": "sha512-M2LC+aqW7VetFcnFiYEbjUsmASW6GSsMNkRzhUzwHoQNfNIRClf5GLgozwuJ4tAMLAfjywrKyQ2wWiODJivQmg==" + "integrity": "sha1-7mXsdymML/FFa8RBigUtDwZDURI=" }, "async-listener": { "version": "0.6.10", @@ -690,7 +719,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "aws-sign2": { "version": "0.5.0", @@ -746,7 +775,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { "version": "1.3.0", @@ -756,7 +785,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "requires": { "tweetnacl": "^0.14.3" } @@ -777,7 +806,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, "bl": { "version": "0.9.5", @@ -809,13 +838,20 @@ } }, "body-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.0.2.tgz", - "integrity": "sha512-/VlRWmVVwfh8rYG/MHGIwesdJYdxBgeddggFG5ssLfX/Qhwt4NKEQhvzwdzVRcy2RhLxni1MKe0uuPfP/unjyw==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", "requires": { - "qs": "~0.6.6", - "raw-body": "~1.1.2", - "type-is": "~1.1.0" + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" } }, "boolify": { @@ -836,7 +872,7 @@ "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -845,28 +881,23 @@ "browser-stdout": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha512-7Rfk377tpSM9TWBEeHs0FlDZGoAIei2V/4MdZJoFMBFAK6BqLpxAIUepGRHGdPFgGsLb02PXovC4qddyHvQqTg==", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, "bson": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz", - "integrity": "sha512-D8zmlb46xfuK2gGvKmUjIklQEouN2nQ0LEHHeZ/NoHM2LDiMk2EYzZ5Ntw/Urk+bgMDosOZxaRzXxvhI5TcAVQ==" - }, - "buffer-crc32": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.3.tgz", - "integrity": "sha512-HLvoSqq1z8fJEcT1lUlJZ4OJaXJZ1wsWm0+fBxkz9Bdf/WphA4Da7FtGUguNNyEXL4WB0hNMTaWmdFRFPy8YOQ==" + "integrity": "sha1-RE21nd1MJPDLBjqr3FyMewzsqRI=" }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, "buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha512-Zy8ZXMyxIT6RMTeY7OP/bDndfj6bwCan7SS98CEndS6deHwWPpseeHlwarNcBim+etXnF9HBc1non5JgDaJU1g==" + "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" }, "builtin-modules": { "version": "3.1.0", @@ -876,7 +907,7 @@ "bunyan": { "version": "0.22.3", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", - "integrity": "sha512-v9dd5qmd6nJHEi7fiNo1fR2pMpE8AiB47Ap984p4iJKj+dEA69jSccmq6grFQn6pxIh0evvKpC5XO1SKfiaRoQ==", + "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", "dev": true, "requires": { "dtrace-provider": "0.2.8", @@ -884,9 +915,9 @@ } }, "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha512-/x68VkHLeTl3/Ll8IvxdwzhrT+IyKc52e/oyHhA2RwqPqswSnjVbSddfPRwAsJtbilMAPSRWwAlpxdYsSWOTKQ==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, "callsites": { "version": "3.1.0", @@ -914,12 +945,12 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chai": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", - "integrity": "sha512-olRoaitftnzWHFEAza6MXR4w+FfZrOVyV7r7U/Z8ObJefCgL8IuWkAuASJjSXrpP9wvgoL8+1dB9RbMLc2FkNg==", + "integrity": "sha1-Pxog+CsLnXQ3V30k1vErGmnTtZA=", "dev": true, "requires": { "assertion-error": "1.0.0", @@ -1050,7 +1081,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-log-level": { "version": "1.4.1", @@ -1063,6 +1094,19 @@ "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==", "dev": true }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, "continuation-local-storage": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", @@ -1073,14 +1117,14 @@ } }, "cookie": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.1.2.tgz", - "integrity": "sha512-+mHmWbhevLwkiBf7QcbZXHr0v4ZQQ/OgHk3fsQHrsMMiGzuvAmU/YMUR+ZfrO/BLAGIWFfx2Z7Oyso0tZR/wiA==" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" }, "cookie-signature": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.4.tgz", - "integrity": "sha512-k+lrG38ZC/S7zN6l1/HcF6xF4jMwkIUjnr5afDU7tzFxIfDmKzdqJdXo8HNYaXOuBJ3tPKxSiwCOTA0b3qQfaA==" + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, "core-js": { "version": "3.6.4", @@ -1091,7 +1135,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cross-spawn": { "version": "6.0.5", @@ -1130,7 +1174,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "requires": { "assert-plus": "^1.0.0" }, @@ -1138,23 +1182,16 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" } } }, "debug": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.2.tgz", - "integrity": "sha512-T9bufXIzQvCa4VrTIpLvvwdLhH+wuBtvIJJA3xgzVcaVETGmTIWMfEXQEd1K4p8BaRmQJPn6MPut38H7YQ+iIA==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "ms": "0.6.2" - }, - "dependencies": { - "ms": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha512-/pc3eh7TWorTtbvXg8je4GvrvEqCfH7PA3P7iW01yL2E53FKixzgMBaQi0NOPbMJqY34cBSvR0tZtmlTkdUG4A==" - } + "ms": "2.0.0" } }, "decamelize": { @@ -1166,7 +1203,7 @@ "deep-eql": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha512-6sEotTRGBFiNcqVoeHwnfopbSpi5NbH1VWJmYCVkmxMmaVTT0bUTrNaGyBwhgP4MZL012W/mkzIn3Da+iDYweg==", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", "dev": true, "requires": { "type-detect": "0.1.1" @@ -1199,9 +1236,14 @@ "dev": true }, "depd": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-0.3.0.tgz", - "integrity": "sha512-Uyx3FgdvEYlpA3W4lf37Ide++2qOsjLlJ7dap0tbM63j/BxTCcxmyIOO6PXbKbOuNSko+fsDHzzx1DUeo1+3fA==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, "dlv": { "version": "1.1.3", @@ -1221,7 +1263,7 @@ "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", - "integrity": "sha512-wufYnYt4ISHnT9MEiRgQ3trXuolt7mICTa/ckT+KYHR667K9H82lmI8KM7zKUJ8l5I343A34wJnvL++1TJn1iA==", + "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", "dev": true, "optional": true }, @@ -1239,12 +1281,12 @@ "each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha512-4MQloCGGCmT5GJZK5ibgJSvTK1c1QSrNlDvLk6fEyRxjZnXjl+NNFfzhfXpmnWh33Owc9D9klrdzCUi7yc9r4Q==" + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -1259,9 +1301,9 @@ } }, "ee-first": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.0.3.tgz", - "integrity": "sha512-1q/3kz+ZwmrrWpJcCCrBZ3JnBzB1BMA5EVW9nxnIP1LxDZ16Cqs9VdolqLWlExet1vU+bar3WSkAa4/YrA9bIw==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "emitter-listener": { "version": "1.1.2", @@ -1277,6 +1319,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -1288,7 +1335,7 @@ "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" }, "error-ex": { "version": "1.3.2", @@ -1332,12 +1379,12 @@ "es6-promise": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha512-oj4jOSXvWglTsc3wrw86iom3LDPOx1nbipQk+jaG3dy+sMRM6ReSgVr/VlmBuF6lXUrflN9DCcQHeSbAwGUl4g==" + "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "requires": { "es6-promise": "^4.0.3" }, @@ -1350,14 +1397,14 @@ } }, "escape-html": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.1.tgz", - "integrity": "sha512-z6kAnok8fqVTra7Yu77dZF2Y6ETJlxH58wN38wNyuNQLm8xXdKnfNrlSmfXsTePWP03rRVUKHubtUwanwUi7+g==" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { @@ -1765,9 +1812,9 @@ }, "dependencies": { "acorn": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", - "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true } } @@ -1808,54 +1855,51 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, "express": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.5.1.tgz", - "integrity": "sha512-36quUqw4ZqgDnQzQpYLnNphPx612kfmQjbZlFt9Mz6Up/27IhkACtYBG9L/dAZkrXD0il3cq58DU+lpSL/Bg1g==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "requires": { - "accepts": "~1.0.7", - "buffer-crc32": "0.2.3", - "cookie": "0.1.2", - "cookie-signature": "1.0.4", - "debug": "1.0.2", - "depd": "0.3.0", - "escape-html": "1.0.1", - "finalhandler": "0.0.2", - "fresh": "0.2.2", - "media-typer": "0.2.0", - "merge-descriptors": "0.0.2", - "methods": "1.0.1", - "parseurl": "1.0.1", - "path-to-regexp": "0.1.2", - "proxy-addr": "1.0.1", - "qs": "0.6.6", - "range-parser": "1.0.0", - "send": "0.5.0", - "serve-static": "~1.3.0", - "type-is": "~1.3.2", - "utils-merge": "1.0.0", - "vary": "0.1.0" - }, - "dependencies": { - "mime-types": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", - "integrity": "sha512-echfutj/t5SoTL4WZpqjA1DCud1XO0WQF3/GJ48YBmc4ZMhCK77QA6Z/w6VTQERLKuJ4drze3kw2TUT8xZXVNw==" - }, - "type-is": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.3.2.tgz", - "integrity": "sha512-sdIhnvhWEyIP2DKjj1o9tL31m8vFxDfLPD56KXz2absqY5AF2QYkJC7Wrw2fkzsZA9mv+PCtgyB7EqYOgR+r3Q==", - "requires": { - "media-typer": "0.2.0", - "mime-types": "~1.0.1" - } - } + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" } }, "extend": { @@ -1877,12 +1921,12 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-diff": { "version": "1.2.0", @@ -1893,7 +1937,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, "fast-levenshtein": { "version": "2.0.6", @@ -1930,12 +1974,17 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, "finalhandler": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-0.0.2.tgz", - "integrity": "sha512-SbpQfvWVwWEBlPTQyaM9gs0D5404ENTC0x2jzbb7t+P+EOD/cBlWjAAvfozIQYtOepUuNkxoLNLCK9/kS29f4w==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "requires": { - "debug": "1.0.2", - "escape-html": "1.0.1" + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" } }, "find-up": { @@ -1950,15 +1999,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" - }, - "finished": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/finished/-/finished-1.2.2.tgz", - "integrity": "sha512-HPJ8x7Gn1pmTS1zWyMoXmQ1yxHkYHRoFsBI66ONq4PS9iWBJy1iHYXOSqMWNp3ksMXfrBpenkSwBhl9WG4zr4Q==", - "requires": { - "ee-first": "1.0.3" - } + "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, "flat-cache": { "version": "2.0.1", @@ -2048,21 +2089,26 @@ "formatio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha512-YAF05v8+XCxAyHOdiiAmHdgCVPrWO8X744fYIPtBciIorh5LndWfi1gjeJ16sTbJhzek9kd+j3YByhohtz5Wmg==", + "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", "dev": true, "requires": { "samsam": "1.x" } }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, "fresh": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.2.2.tgz", - "integrity": "sha512-ZGGi8GROK//ijm2gB33sUuN9TjN1tC/dvG4Bt4j6IWrVGpMmudUBCxx+Ir7qePsdREfkpQC4FL8W0jeSOsgv1w==" + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "function-bind": { @@ -2112,7 +2158,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "requires": { "assert-plus": "^1.0.0" }, @@ -2120,14 +2166,14 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" } } }, "glob": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "optional": true, "requires": { "inflight": "^1.0.4", @@ -2205,7 +2251,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "har-validator": { "version": "5.1.3", @@ -2245,7 +2291,7 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", "dev": true }, "has-symbols": { @@ -2269,7 +2315,7 @@ "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha512-z/GDPjlRMNOa2XJiB4em8wJpuuBfrFOlYKTZxtpkdr1uPdibHI8rYA3MY0KDObpVyaes0e/aunid/t88ZI2EKA==", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, "hex2dec": { @@ -2289,6 +2335,18 @@ "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", "dev": true }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, "http-signature": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", @@ -2301,11 +2359,11 @@ } }, "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "requires": { - "agent-base": "^4.1.0", + "agent-base": "^4.3.0", "debug": "^3.1.0" }, "dependencies": { @@ -2328,7 +2386,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -2372,7 +2429,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -2381,7 +2438,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "inquirer": { "version": "7.0.4", @@ -2422,9 +2479,9 @@ "dev": true }, "ipaddr.js": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-0.1.2.tgz", - "integrity": "sha512-MGrEjHz4Hk5UVpJXZQ2tHB+bp6xgdRKCAEWdrgFsoAmXCgKAPtj8LqMxgvlWEAj9aN+PpTcvE051uZU3K3kLSQ==" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "is": { "version": "3.3.0", @@ -2457,7 +2514,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-fullwidth-code-point": { @@ -2508,12 +2565,12 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", @@ -2524,7 +2581,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "js-tokens": { "version": "4.0.0", @@ -2545,7 +2602,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" }, "jsesc": { "version": "2.5.2", @@ -2556,7 +2613,7 @@ "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha512-u+c/u/F+JNPUekHCFyGVycRPyh9UHD5iUhSyIAn10kxbDTJxijwAbT6XHaONEOXuGGfmWUSroheXgHcml4gLgg==", + "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", "requires": { "bignumber.js": "^7.0.0" } @@ -2564,12 +2621,12 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -2580,12 +2637,12 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -2596,7 +2653,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" } } }, @@ -2610,12 +2667,6 @@ "object.assign": "^4.1.0" } }, - "just-extend": { - "version": "1.1.27", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", - "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", - "dev": true - }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -2696,7 +2747,7 @@ "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==" + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" }, "lodash.unescape": { "version": "4.0.1", @@ -2904,7 +2955,7 @@ "lolex": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.6.0.tgz", - "integrity": "sha512-e1UtIo1pbrIqEXib/yMjHciyqkng5lc0rrIbytgjmRgDR9+2ceNIAcwOWSgylRjoEP9VdVguCSRwnNmlbnOUwA==", + "integrity": "sha1-z5Fm88nezjzetdawH85Q8UoSA+M=", "dev": true }, "long": { @@ -2932,12 +2983,12 @@ "lsmod": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", - "integrity": "sha512-Y+6V75r+mGWzWEPr9h6PFmStielICu5JBHLUg18jCsD2VFmEfgHbq/EgnY4inElsUD9eKL9id1qp34w46rSIKQ==" + "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" }, "lynx": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", - "integrity": "sha512-JI52N0NwK2b/Md0TFPdPtUBI46kjyJXF7+q08l2yvQ56q6QA8s7ZjZQQRoxFpS2jDXNf/B0p8ID+OIKcTsZwzw==", + "integrity": "sha1-Mxjc7xaQi4KG6Bisz9sxzXQkj50=", "requires": { "mersenne": "~0.0.3", "statsd-parser": "~0.0.4" @@ -2953,9 +3004,9 @@ }, "dependencies": { "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha512-7Wl+Jz+IGWuSdgsQEJ4JunV0si/iMhg42MnQQG6h1R6TNeVenp4U9x5CC5v/gYqz/fENLQITAWXidNtVL0NNbw==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true, "optional": true } @@ -2968,19 +3019,19 @@ "dev": true }, "media-typer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.2.0.tgz", - "integrity": "sha512-TSggxYk75oP4tae7JkT8InpcFGUP4340zg1dOWjcu9qcphaDKtXEuNUv3OD4vJ+gVTvIDK797W0uYeNm8qqsDg==" + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "merge-descriptors": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-0.0.2.tgz", - "integrity": "sha512-dYBT4Ep+t/qnPeJcnMymmhTdd4g8/hn48ciaDqLAkfRf8abzLPS6Rb6EBdz5CZCL8tzZuI5ps9MhGQGxk+EuKg==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, "mersenne": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", - "integrity": "sha512-XoSUL+nF8hMTKGQxUs8r3Btdsf1yuKKBdCCGbh3YXgCXuVKishpZv1CNc385w9s8t4Ynwc5h61BwW/FCVulkbg==" + "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" }, "messageformat": { "version": "2.3.0", @@ -3006,9 +3057,9 @@ "dev": true }, "methods": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.0.1.tgz", - "integrity": "sha512-2403MfnVypWSNIEpmQ26/ObZ5kSUx37E8NHRvriw0+I8Sne7k0HGuLGCk0OrCqURh4UIygD0cSsYq+Ll+kzNqA==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "metrics-sharelatex": { "version": "2.2.0", @@ -3034,17 +3085,18 @@ "mime": { "version": "1.2.11", "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha512-Ysa2F/nqTNGHhhm9MV8ure4+Hc+Y8AWiqUdHxsO7xu8zc92ND9f3kpALHjaP026Ft17UfxrMt95c50PLUeynBw==" + "integrity": "sha512-Ysa2F/nqTNGHhhm9MV8ure4+Hc+Y8AWiqUdHxsO7xu8zc92ND9f3kpALHjaP026Ft17UfxrMt95c50PLUeynBw==", + "dev": true }, "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI=" }, "mime-types": { "version": "2.1.24", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=", "requires": { "mime-db": "1.40.0" } @@ -3058,7 +3110,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "^1.1.7" } @@ -3066,20 +3118,28 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==" + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", + "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } } }, "mocha": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "integrity": "sha1-fYbPvPNcuCnidUwy4XNV7AUzh5Q=", "dev": true, "requires": { "browser-stdout": "1.3.0", @@ -3097,13 +3157,13 @@ "commander": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "integrity": "sha1-FXFS/R56bI2YpbcVzzdt+SgARWM=", "dev": true }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -3112,13 +3172,13 @@ "diff": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "integrity": "sha1-qoVnpu7QPFMfyJ0/cRzQ5SWd7HU=", "dev": true }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3132,15 +3192,24 @@ "growl": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "integrity": "sha1-GSa6kM8+3+KttJJ/WIC8IsZseQ8=", "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } } } }, "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { "version": "2.24.0", @@ -3151,7 +3220,7 @@ "mongodb": { "version": "2.2.35", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz", - "integrity": "sha512-3HGLucDg/8EeYMin3k+nFWChTA85hcYDCw1lPsWR6yV9A6RgKb24BkLiZ9ySZR+S0nfBjWoIUS7cyV6ceGx5Gg==", + "integrity": "sha1-zRta+KlGPj+aeH+ls9BVZVeXMPk=", "requires": { "es6-promise": "3.2.1", "mongodb-core": "2.1.19", @@ -3161,7 +3230,7 @@ "readable-stream": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha512-a6ibcfWFhgihuTw/chl+u3fB5ykBZFmnvpyZHebY0MCQE4vvYcsCLpCeaQ1BkH7HdJYavNSqF0WDLeo4IPHQaQ==", + "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", "requires": { "buffer-shims": "~1.0.0", "core-util-is": "~1.0.0", @@ -3175,7 +3244,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "requires": { "safe-buffer": "~5.1.0" } @@ -3185,7 +3254,7 @@ "mongodb-core": { "version": "2.1.19", "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz", - "integrity": "sha512-Jt4AtWUkpuW03kRdYGxga4O65O1UHlFfvvInslEfLlGi+zDMxbBe3J2NVmN9qPJ957Mn6Iz0UpMtV80cmxCVxw==", + "integrity": "sha1-APvV5aNXN2O5Fxz9hE5gqPKjoYs=", "requires": { "bson": "~1.0.4", "require_optional": "~1.0.0" @@ -3194,7 +3263,7 @@ "mongojs": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", - "integrity": "sha512-QqqJ06x5EBBG121dxXbm0kQ8mNVAOGMeG3RKbNvtbiFez5EhCTMDUikYcsa0V9tphlvsheO5riMHcXHxW0q3lw==", + "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", "requires": { "each-series": "^1.0.0", "mongodb": "^2.0.45", @@ -3209,7 +3278,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "mute-stream": { "version": "0.0.8", @@ -3220,7 +3289,7 @@ "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -3236,7 +3305,7 @@ "native-promise-only": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==", + "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", "dev": true }, "natural-compare": { @@ -3248,13 +3317,13 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", "optional": true }, "negotiator": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.4.7.tgz", - "integrity": "sha512-ujxWwyRfZ6udAgHGECQC3JDO9e6UAsuItfUMcqA0Xf2OLNQTveFVFx+fHGIJ5p0MJaJrZyGQqPwzuN0NxJzEKA==" + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, "nice-try": { "version": "1.0.5", @@ -3263,28 +3332,53 @@ "dev": true }, "nise": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.3.3.tgz", - "integrity": "sha512-v1J/FLUB9PfGqZLGDBhQqODkbLotP0WtLo9R4EJY2PPu5f5Xg4o0rA8FDlmrjFSv9vBBKcfnOSpfYYuu5RTHqg==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", + "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", "dev": true, "requires": { - "@sinonjs/formatio": "^2.0.0", - "just-extend": "^1.1.27", - "lolex": "^2.3.2", - "path-to-regexp": "^1.7.0", - "text-encoding": "^0.6.4" + "@sinonjs/formatio": "^3.2.1", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^5.0.1", + "path-to-regexp": "^1.7.0" }, "dependencies": { + "@sinonjs/formatio": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, + "just-extend": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", + "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", + "dev": true + }, + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha512-nifX1uj4S9IrK/w3Xe7kKvNEepXivANs9ng60Iq7PU/BlouV3yL/VUhFqTuTq33ykwUqoNcTeGo5vdOBP4jS/Q==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", "dev": true, "requires": { "isarray": "0.0.1" @@ -3329,7 +3423,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-inspect": { @@ -3392,10 +3486,18 @@ "has": "^1.0.3" } }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } @@ -3432,7 +3534,7 @@ "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "integrity": "sha1-QXyZQeYCepq8ulCS3SkE4lW1+8I=", "requires": { "p-try": "^2.0.0" } @@ -3466,7 +3568,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=" }, "parent-module": { "version": "1.0.1", @@ -3494,7 +3596,7 @@ "parse-mongo-url": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha512-7bZUusQIrFLwvsLHBnCz2WKYQ5LKO/LwKPnvQxbMIh9gDx8H5ZsknRmLjZdn6GVdrgVOwqDrZKsY0qDLNmRgcw==" + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" }, "parse-ms": { "version": "2.1.0", @@ -3502,9 +3604,9 @@ "integrity": "sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==" }, "parseurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.0.1.tgz", - "integrity": "sha512-6W9+0+9Ihayqwjgp4OaLLqZ3KDtqPY2PtUPz8YNiy4PamjJv+7x6J9GO93O9rUZOLgaanTPxsKTasxqKkO1iSw==" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "path-exists": { "version": "3.0.0", @@ -3515,7 +3617,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", @@ -3532,12 +3634,12 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=" }, "path-to-regexp": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.2.tgz", - "integrity": "sha512-BZU7Qr+qKkXJX9UBypMNikdZ85cQSjtfMhUykJFLJn4SNF0jhEbb9nMRpnNdA76ESryY8JpMA4k6XKdz3JS1pw==" + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, "path-type": { "version": "2.0.0", @@ -3559,7 +3661,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "pify": { "version": "4.0.1", @@ -4189,7 +4291,7 @@ "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha512-yN0WQmuCX63LP/TMvAg31nvT6m4vDqJEiiv2CAZqWOGNWutc9DfDk1NPYYmKUFmaVM2UwDowH4u5AHWYP/jxKw==" + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "progress": { "version": "2.0.3", @@ -4244,11 +4346,12 @@ } }, "proxy-addr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.0.1.tgz", - "integrity": "sha512-rIUGzBlSfkJMWWCgsd4N5wvVSNAcJZg//UwPZumDIbScHRUzuSOjBmIdyICiKkB9yArv+er9qC6RA/NL3AWc6A==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "requires": { - "ipaddr.js": "0.1.2" + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" } }, "psl": { @@ -4259,12 +4362,12 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" }, "qs": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/qs/-/qs-0.6.6.tgz", - "integrity": "sha512-kN+yNdAf29Jgp+AYHUmC7X4QdJPR8czuMWLNLc0aRxkQ7tB3vJQEONKKT9ou/rW7EbqVec11srC9q9BiVbcnHA==" + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, "quick-lru": { "version": "4.0.1", @@ -4279,14 +4382,14 @@ "dev": true }, "range-parser": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.0.0.tgz", - "integrity": "sha512-wOH5LIH2ZHo0P7/bwkR+aNbJ+kv3CHVX4B8qs9GqbtY29fi1bGPV5xczrutN20G+Z4XhRqRMTW3q0S4iyJJPfw==" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raven": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", - "integrity": "sha512-RYov4wAaflZasWiCrZuizd3jNXxCOkW1WrXgWsGVb8kRpdHNZ+vPY27R6RhVtqzWp+DG9a5l6iP0QUPK4EgzaQ==", + "integrity": "sha1-QnPBrm005CMPUbLAEEGjK5Iygio=", "requires": { "cookie": "0.3.1", "json-stringify-safe": "5.0.1", @@ -4298,22 +4401,24 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, "uuid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", - "integrity": "sha512-rqE1LoOVLv3QrZMjb4NkF5UWlkurCfPyItVnFPNKDDGkHw4dQUdE4zMcLqx28+0Kcf3+bnUk4PisaiRJT4aiaQ==" + "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" } } }, "raw-body": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha512-WmJJU2e9Y6M5UzTOkHaM7xJGAPQD8PNzx3bAd2+uhZAim6wDk6dAZxPVYLF67XhbR4hmKGh33Lpmh4XWrCH5Mg==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", "requires": { - "bytes": "1", - "string_decoder": "0.10" + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" } }, "react-is": { @@ -4346,7 +4451,7 @@ "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -4360,12 +4465,12 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "requires": { "safe-buffer": "~5.1.0" } @@ -4472,7 +4577,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", "dev": true }, "require-main-filename": { @@ -4490,7 +4595,7 @@ "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=", "requires": { "resolve-from": "^2.0.0", "semver": "^5.1.0" @@ -4499,7 +4604,7 @@ "resolve": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "integrity": "sha1-QBSHC6KWF2uGND1Qtg87UGCc4jI=", "requires": { "path-parse": "^1.0.6" } @@ -4507,7 +4612,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, "restore-cursor": { "version": "3.1.0", @@ -4535,7 +4640,7 @@ "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", "optional": true, "requires": { "glob": "^6.0.1" @@ -4562,7 +4667,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" }, "safe-json-stringify": { "version": "1.2.0", @@ -4573,18 +4678,18 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" }, "samsam": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", + "integrity": "sha1-jR2TUOJWItow3j5EumkrUiGrfFA=", "dev": true }, "sandboxed-module": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", - "integrity": "sha512-/2IfB1wtca3eNVPXbQrb6UkhE/1pV4Wz+5CdG6DPYqeaDsYDzxglBT7/cVaqyrlRyQKdmw+uTZUTRos9FFD2PQ==", + "integrity": "sha1-8fvvvYCaT2kHO9B8rm/H2y6vX2o=", "dev": true, "requires": { "require-like": "0.1.2", @@ -4594,7 +4699,7 @@ "stack-trace": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", - "integrity": "sha512-5/6uZt7RYjjAl8z2j1mXWAewz+I4Hk2/L/3n6NRLIQ31+uQ7nMd9O6G69QCdrrufHv0QGRRHl/jwUEGTqhelTA==", + "integrity": "sha1-HnGb1qJin/CcGJ4Xqe+QKpT8XbA=", "dev": true } } @@ -4602,72 +4707,49 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" + "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=" }, "send": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.5.0.tgz", - "integrity": "sha512-uuPWJQK6p0btveYhOxRqvcB9Cfcs9ugNrMd0SoM/tqzOC9A86bX4rDEQN84X3Cc5Gpo5Az2cB4Olo5c3Aso2Sg==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "requires": { - "debug": "1.0.2", - "escape-html": "1.0.1", - "finished": "1.2.2", - "fresh": "0.2.2", - "mime": "1.2.11", - "ms": "0.6.2", - "range-parser": "~1.0.0" + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, "dependencies": { + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, "ms": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha512-/pc3eh7TWorTtbvXg8je4GvrvEqCfH7PA3P7iW01yL2E53FKixzgMBaQi0NOPbMJqY34cBSvR0tZtmlTkdUG4A==" + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" } } }, "serve-static": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.3.2.tgz", - "integrity": "sha512-KwjCeYUx7IM1neg8/P0+O1DZsl76XcOSuV0ZxrI0r60vwGlcjMjKOYCK/OFLJy/a2CFuIyAa/x0PuQ0yuG+IgQ==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "requires": { - "escape-html": "1.0.1", - "parseurl": "~1.1.3", - "send": "0.6.0" - }, - "dependencies": { - "debug": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-1.0.3.tgz", - "integrity": "sha512-MltK7Ykj/udtD728gD/RrONStwVnDpBNIP1h+CBcnwnJdHqHxfWHI1E8XLootUl7NOPAYTCCXlb8/Qmy7WyB1w==", - "requires": { - "ms": "0.6.2" - } - }, - "ms": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.6.2.tgz", - "integrity": "sha512-/pc3eh7TWorTtbvXg8je4GvrvEqCfH7PA3P7iW01yL2E53FKixzgMBaQi0NOPbMJqY34cBSvR0tZtmlTkdUG4A==" - }, - "parseurl": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.1.3.tgz", - "integrity": "sha512-7y9IL/9x2suvr1uIvoAc3yv3f28hZ55g2OM+ybEtnZqV6Ykeg36sy1PCsTN9rQUZYzb9lTKLzzmJM11jaXSloA==" - }, - "send": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.6.0.tgz", - "integrity": "sha512-A3EwHmDwcPcmLxIRNjr2YbXiYWq6M9JyUq4303pLKVFs4m5oeME0a9Cpcu9N22fED5XVepldjPYGo9eJifb7Yg==", - "requires": { - "debug": "1.0.3", - "depd": "0.3.0", - "escape-html": "1.0.1", - "finished": "1.2.2", - "fresh": "0.2.2", - "mime": "1.2.11", - "ms": "0.6.2", - "range-parser": "~1.0.0" - } - } + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" } }, "set-blocking": { @@ -4676,10 +4758,15 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, "settings-sharelatex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", - "integrity": "sha512-f7D+0lnlohoteSn6IKTH72NE+JnAdMWTKwQglAuimZWTID2FRRItZSGeYMTRpvEnaQApkoVwRp//WRMsiddnqw==", + "integrity": "sha1-Tv4vUpPbjxwVlnEEx5BfqHD/mS0=", "requires": { "coffee-script": "1.6.0" }, @@ -4687,7 +4774,7 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" } } }, @@ -4730,7 +4817,7 @@ "sinon": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", - "integrity": "sha512-KY3OLOWpek/I4NGAMHetuutVgS2aRgMR5g5/1LSYvPJ3qo2BopIvk3esFztPxF40RWf/NNNJzdFPriSkXUVK3A==", + "integrity": "sha1-2K2r2QBzD9SXeIoCcEnGSwi+kcI=", "dev": true, "requires": { "diff": "^3.1.0", @@ -4747,19 +4834,19 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", "dev": true }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha512-nifX1uj4S9IrK/w3Xe7kKvNEepXivANs9ng60Iq7PU/BlouV3yL/VUhFqTuTq33ykwUqoNcTeGo5vdOBP4jS/Q==", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", "dev": true, "requires": { "isarray": "0.0.1" @@ -4768,7 +4855,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=", "dev": true } } @@ -4879,19 +4966,24 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" } } }, "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==" + "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=" }, "statsd-parser": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", - "integrity": "sha512-7XO+ur89EalMXXFQaydsczB8sclr5nDsNIoUu0IzJx1pIbHUhO3LtpSzBwetIuU9DyTLMiVaJBMtWS/Nb2KR4g==" + "integrity": "sha1-y9JDlTzELv/VSLXSI4jtaJ7GOb0=" + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, "stream-shift": { "version": "1.0.0", @@ -4957,7 +5049,8 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true }, "stringstream": { "version": "0.0.6", @@ -4997,7 +5090,7 @@ "supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "integrity": "sha1-iD992rwWUUKyphQn8zUt7RldGj4=", "dev": true, "requires": { "has-flag": "^2.0.0" @@ -5061,7 +5154,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", "requires": { "bintrees": "1.0.1" } @@ -5086,7 +5179,7 @@ "text-encoding": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha512-hJnc6Qg3dWoOMkqP53F0dzRIgtmsAge09kxUIqGrEUS4qr5rWLckGYaQAVr+opBrIMRErGgy6f5aPnyPpyGRfg==", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", "dev": true }, "text-table": { @@ -5098,7 +5191,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.5", @@ -5112,7 +5205,7 @@ "thunky": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", - "integrity": "sha512-vquTt/sKNzFqFK8DKLg33U7deg93WKYH4CE2Ul9hOyMCfm7VXgM7GJQRpPAgnmgnrf407Fcq8TQVEKlbavAu+A==" + "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" }, "tmp": { "version": "0.0.33", @@ -5126,13 +5219,18 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "to-mongodb-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha512-vfXXcGYFP8+0L5IPOtUzzVIvPE/G3GN0TKa/PRBlzPqYyhm+UxhPmvv634EQgO4Ot8dHbBFihOslMJQclY8Z9A==" + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "tough-cookie": { "version": "3.0.1", @@ -5168,7 +5266,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, "type-check": { "version": "0.3.2", @@ -5182,7 +5280,7 @@ "type-detect": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha512-5rqszGVwYgBoDkIm2oUtvkfZMQ0vk29iDMU0W2qCa3rG0vPDNczCMT4hV/bLBgLg8k8ri6+u3Zbt+S/14eMzlA==", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", "dev": true }, "type-fest": { @@ -5192,11 +5290,12 @@ "dev": true }, "type-is": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.1.0.tgz", - "integrity": "sha512-bGTRFAlk7i/YYyx/d1xYm6gLrALwTcY2HLwsVqAIPKJjjtlI/rGXRgjQrcOln2fcHCbAqi0hrueZ2yPnHvCipQ==", + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "requires": { - "mime": "~1.2.11" + "media-typer": "0.3.0", + "mime-types": "~2.1.24" } }, "typescript": { @@ -5210,10 +5309,15 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", "integrity": "sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==" }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", "requires": { "punycode": "^2.1.0" }, @@ -5221,19 +5325,19 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" } } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz", - "integrity": "sha512-HwU9SLQEtyo+0uoKXd1nkLqigUWLB+QuNQR4OcmB73eWqksM5ovuqcycks2x043W8XVb75rG1HQ0h93TMXkzQQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "v8-compile-cache": { "version": "2.1.0", @@ -5252,14 +5356,14 @@ } }, "vary": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/vary/-/vary-0.1.0.tgz", - "integrity": "sha512-tyyeG46NQdwyVP/RsWLSrT78ouwEuvwk9gK8vQK4jdXmqoXtTXW+vsCfNcnqRhigF8olV34QVZarmAi6wBV2Mw==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -5269,7 +5373,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" } } }, @@ -5407,7 +5511,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", @@ -5421,7 +5525,7 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha512-iTwvhNBRetXWe81+VcIw5YeadVSWyze7uA7nVnpP13ulrpnJ3UfQm5ApGnrkmxDJFdrblRdZs0EvaTCIfei5oQ==" + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "4.0.0", diff --git a/services/docstore/package.json b/services/docstore/package.json index 82d2e34426..bfd8372cbc 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -20,8 +20,8 @@ }, "dependencies": { "async": "~0.8.0", - "body-parser": "~1.0.2", - "express": "~4.5.0", + "body-parser": "^1.19.0", + "express": "^4.17.1", "logger-sharelatex": "^1.7.0", "metrics-sharelatex": "^2.2.0", "mongojs": "2.4.0", From d78e8d7d3f405c3dc544fe210588e62b25dc34ab Mon Sep 17 00:00:00 2001 From: mserranom <mserranom@gmail.com> Date: Mon, 23 Mar 2020 12:30:33 +0100 Subject: [PATCH 239/349] npm audit fix --- services/docstore/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 5b5e7d5132..a6df730d0e 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -563,9 +563,9 @@ } }, "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" }, "acorn-jsx": { "version": "5.1.0", From 97a3fd320231eb4a657f29fa75f1579cdeb6c61c Mon Sep 17 00:00:00 2001 From: mserranom <mserranom@gmail.com> Date: Mon, 23 Mar 2020 12:32:25 +0100 Subject: [PATCH 240/349] updated minor/patch dependencies and known safe updates --- services/docstore/package-lock.json | 1839 ++++++++++++++++++++------- services/docstore/package.json | 22 +- 2 files changed, 1371 insertions(+), 490 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index a6df730d0e..40f37cd380 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -14,12 +14,12 @@ } }, "@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", + "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", "dev": true, "requires": { - "@babel/types": "^7.8.3", + "@babel/types": "^7.9.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -28,7 +28,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } @@ -62,6 +62,12 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "dev": true + }, "@babel/highlight": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", @@ -74,9 +80,9 @@ } }, "@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "version": "7.9.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.3.tgz", + "integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==", "dev": true }, "@babel/runtime": { @@ -88,29 +94,47 @@ "regenerator-runtime": "^0.13.2" } }, + "@babel/runtime-corejs3": { + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz", + "integrity": "sha512-HHxmgxbIzOfFlZ+tdeRKtaxWOMUoCG5Mu3wKeUmOxjYrwb3AAHgnmtCUbPPK11/raIWLIBK250t8E2BPO0p7jA==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + } + } + }, "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" } }, "@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", + "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", + "@babel/generator": "^7.9.0", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -134,32 +158,30 @@ } }, "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", + "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", "dev": true, "requires": { - "esutils": "^2.0.2", + "@babel/helper-validator-identifier": "^7.9.0", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, "@google-cloud/common": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz", - "integrity": "sha512-bLdPzFvvBMtVkwsoBtygE9oUm3yrNmPa71gvOgucYI/GqvNP2tb6RYsDHPq98kvignhcgHGDI5wyNgxaCo8bKQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.4.0.tgz", + "integrity": "sha512-zWFjBS35eI9leAHhjfeOYlK5Plcuj/77EzstnrJIZbKgF/nkqjcQuGiMCpzCwOfPyUbz8ZaEOYgbHa759AKbjg==", "requires": { - "@google-cloud/projectify": "^0.3.3", - "@google-cloud/promisify": "^0.4.0", - "@types/request": "^2.48.1", + "@google-cloud/projectify": "^1.0.0", + "@google-cloud/promisify": "^1.0.0", "arrify": "^2.0.0", "duplexify": "^3.6.0", "ent": "^2.2.0", "extend": "^3.0.2", - "google-auth-library": "^3.1.1", - "pify": "^4.0.1", + "google-auth-library": "^5.5.0", "retry-request": "^4.0.0", - "teeny-request": "^3.11.3" + "teeny-request": "^6.0.0" } }, "@google-cloud/debug-agent": { @@ -183,18 +205,235 @@ "split": "^1.0.0" }, "dependencies": { + "@google-cloud/common": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz", + "integrity": "sha512-bLdPzFvvBMtVkwsoBtygE9oUm3yrNmPa71gvOgucYI/GqvNP2tb6RYsDHPq98kvignhcgHGDI5wyNgxaCo8bKQ==", + "requires": { + "@google-cloud/projectify": "^0.3.3", + "@google-cloud/promisify": "^0.4.0", + "@types/request": "^2.48.1", + "arrify": "^2.0.0", + "duplexify": "^3.6.0", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^3.1.1", + "pify": "^4.0.1", + "retry-request": "^4.0.0", + "teeny-request": "^3.11.3" + } + }, + "@google-cloud/projectify": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", + "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + }, + "@google-cloud/promisify": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz", + "integrity": "sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q==" + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, "coffeescript": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.4.1.tgz", - "integrity": "sha512-34GV1aHrsMpTaO3KfMJL40ZNuvKDR/g98THHnE9bQj8HjMaZvSrLik99WWqyMhRtbe8V5hpx5iLgdcSvM/S2wg==" + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", + "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==" + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "gaxios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", + "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.3.0" + } + }, + "gcp-metadata": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz", + "integrity": "sha512-Q6HrgfrCQeEircnNP3rCcEgiDv7eF9+1B+1MMgpE190+/+0mjQR8PxeOaRgxZWmdDAF9EIryHB9g1moPiw1SbQ==", + "requires": { + "gaxios": "^1.0.2", + "json-bigint": "^0.3.0" + } + }, + "google-auth-library": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz", + "integrity": "sha512-cDQMzTotwyWMrg5jRO7q0A4TL/3GWBgO7I7q5xGKNiiFf9SmGY/OJ1YsLMgI2MVHHsEGyrqYnbnmV1AE+Z6DnQ==", + "requires": { + "base64-js": "^1.3.0", + "fast-text-encoding": "^1.0.0", + "gaxios": "^1.2.1", + "gcp-metadata": "^1.0.0", + "gtoken": "^2.3.2", + "https-proxy-agent": "^2.2.1", + "jws": "^3.1.5", + "lru-cache": "^5.0.0", + "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "google-p12-pem": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", + "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", + "requires": { + "node-forge": "^0.8.0", + "pify": "^4.0.0" + } + }, + "gtoken": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", + "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "requires": { + "gaxios": "^1.0.4", + "google-p12-pem": "^1.0.0", + "jws": "^3.1.5", + "mime": "^2.2.0", + "pify": "^4.0.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-forge": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", + "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" }, "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "teeny-request": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", + "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "requires": { + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.2.0", + "uuid": "^3.3.2" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, + "@google-cloud/logging": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@google-cloud/logging/-/logging-7.3.0.tgz", + "integrity": "sha512-xTW1V4MKpYC0mjSugyuiyUoZ9g6A42IhrrO3z7Tt3SmAb2IRj2Gf4RLoguKKncs340ooZFXrrVN/++t2Aj5zgg==", + "requires": { + "@google-cloud/common": "^2.2.2", + "@google-cloud/paginator": "^2.0.0", + "@google-cloud/projectify": "^1.0.0", + "@google-cloud/promisify": "^1.0.0", + "@opencensus/propagation-stackdriver": "0.0.20", + "arrify": "^2.0.0", + "dot-prop": "^5.1.0", + "eventid": "^1.0.0", + "extend": "^3.0.2", + "gcp-metadata": "^3.1.0", + "google-auth-library": "^5.2.2", + "google-gax": "^1.11.0", + "is": "^3.3.0", + "on-finished": "^2.3.0", + "pumpify": "^2.0.0", + "snakecase-keys": "^3.0.0", + "stream-events": "^1.0.4", + "through2": "^3.0.0", + "type-fest": "^0.12.0" + }, + "dependencies": { + "type-fest": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", + "integrity": "sha512-53RyidyjvkGpnWPMF9bQgFtWp+Sl8O2Rp13VavmJgfAP9WWG6q6TkrKU8iyJdnwnfgHI6k2hTlgqH4aSdjoTbg==" + } + } + }, + "@google-cloud/logging-bunyan": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/logging-bunyan/-/logging-bunyan-2.0.3.tgz", + "integrity": "sha512-8n9MwsCRd4v8WZg17+d3m7qInud7lYTm5rpwXHY0/lzWEJYjeiztT09BiCYh56EEhHr+ynymJnzUDZKazkywlg==", + "requires": { + "@google-cloud/logging": "^7.0.0", + "google-auth-library": "^5.0.0" + } + }, + "@google-cloud/paginator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-2.0.3.tgz", + "integrity": "sha512-kp/pkb2p/p0d8/SKUu4mOq8+HGwF8NPzHWkj+VKrIPQPyMRw8deZtrO/OcSiy9C/7bpfU5Txah5ltUNfPkgEXg==", + "requires": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + } + }, "@google-cloud/profiler": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-0.2.3.tgz", @@ -236,16 +475,48 @@ "through2": "^3.0.0" } }, + "@google-cloud/projectify": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", + "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + }, "@google-cloud/promisify": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz", "integrity": "sha512-QzB0/IMvB0eFxFK7Eqh+bfC8NLv3E9ScjWQrPOk6GgfNroxcVITdTlT8NRsRrcp5+QQJVPLkRqKG0PUdaWXmHw==" }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "gaxios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", + "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.3.0" + } + }, "gcp-metadata": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz", @@ -281,25 +552,96 @@ } } }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", + "google-p12-pem": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", + "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", "requires": { - "readable-stream": "2 || 3" + "node-forge": "^0.8.0", + "pify": "^4.0.0" } + }, + "gtoken": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", + "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "requires": { + "gaxios": "^1.0.4", + "google-p12-pem": "^1.0.0", + "jws": "^3.1.5", + "mime": "^2.2.0", + "pify": "^4.0.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-forge": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", + "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" + }, + "teeny-request": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", + "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "requires": { + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.2.0", + "uuid": "^3.3.2" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, "@google-cloud/projectify": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", - "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-1.0.4.tgz", + "integrity": "sha512-ZdzQUN02eRsmTKfBj9FDL0KNDIFNjBn/d6tHQmA/+FImH5DO6ZV8E7FzxMgAUiVAUq41RFAkb25p1oHOZ8psfg==" }, "@google-cloud/promisify": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz", - "integrity": "sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q==" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-1.0.4.tgz", + "integrity": "sha512-VccZDcOql77obTnFh0TbNED/6ZbbmHDf8UMNnzO1d5g9V0Htfm4k5cllY8P1tJsRKC3zWYGRLaViiupcgVjBoQ==" }, "@google-cloud/trace-agent": { "version": "3.6.1", @@ -321,23 +663,249 @@ "uuid": "^3.0.1" }, "dependencies": { - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" + "@google-cloud/common": { + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz", + "integrity": "sha512-bLdPzFvvBMtVkwsoBtygE9oUm3yrNmPa71gvOgucYI/GqvNP2tb6RYsDHPq98kvignhcgHGDI5wyNgxaCo8bKQ==", + "requires": { + "@google-cloud/projectify": "^0.3.3", + "@google-cloud/promisify": "^0.4.0", + "@types/request": "^2.48.1", + "arrify": "^2.0.0", + "duplexify": "^3.6.0", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^3.1.1", + "pify": "^4.0.1", + "retry-request": "^4.0.0", + "teeny-request": "^3.11.3" + } + }, + "@google-cloud/projectify": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", + "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + }, + "@google-cloud/promisify": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz", + "integrity": "sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q==" + }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "gaxios": { + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", + "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.3.0" + } + }, + "gcp-metadata": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz", + "integrity": "sha512-Q6HrgfrCQeEircnNP3rCcEgiDv7eF9+1B+1MMgpE190+/+0mjQR8PxeOaRgxZWmdDAF9EIryHB9g1moPiw1SbQ==", + "requires": { + "gaxios": "^1.0.2", + "json-bigint": "^0.3.0" + } + }, + "google-auth-library": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz", + "integrity": "sha512-cDQMzTotwyWMrg5jRO7q0A4TL/3GWBgO7I7q5xGKNiiFf9SmGY/OJ1YsLMgI2MVHHsEGyrqYnbnmV1AE+Z6DnQ==", + "requires": { + "base64-js": "^1.3.0", + "fast-text-encoding": "^1.0.0", + "gaxios": "^1.2.1", + "gcp-metadata": "^1.0.0", + "gtoken": "^2.3.2", + "https-proxy-agent": "^2.2.1", + "jws": "^3.1.5", + "lru-cache": "^5.0.0", + "semver": "^5.5.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "google-p12-pem": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", + "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", + "requires": { + "node-forge": "^0.8.0", + "pify": "^4.0.0" + } + }, + "gtoken": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", + "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "requires": { + "gaxios": "^1.0.4", + "google-p12-pem": "^1.0.0", + "jws": "^3.1.5", + "mime": "^2.2.0", + "pify": "^4.0.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node-forge": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", + "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" }, "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "teeny-request": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", + "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "requires": { + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.2.0", + "uuid": "^3.3.2" + } }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, + "@grpc/grpc-js": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-0.6.18.tgz", + "integrity": "sha512-uAzv/tM8qpbf1vpx1xPMfcUMzbfdqJtdCYAqY/LsLeQQlnTb4vApylojr+wlCyr7bZeg3AFfHvtihnNOQQt/nA==", + "requires": { + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@grpc/proto-loader": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.3.tgz", + "integrity": "sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ==", + "requires": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + } + }, + "@opencensus/core": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.20.tgz", + "integrity": "sha512-vqOuTd2yuMpKohp8TNNGUAPjWEGjlnGfB9Rh5e3DKqeyR94YgierNs4LbMqxKtsnwB8Dm2yoEtRuUgoe5vD9DA==", + "requires": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^6.0.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } + } + }, + "@opencensus/propagation-stackdriver": { + "version": "0.0.20", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-stackdriver/-/propagation-stackdriver-0.0.20.tgz", + "integrity": "sha512-P8yuHSLtce+yb+2EZjtTVqG7DQ48laC+IuOWi3X9q78s1Gni5F9+hmbmyP6Nb61jb5BEvXQX1s2rtRI6bayUWA==", + "requires": { + "@opencensus/core": "^0.0.20", + "hex2dec": "^1.0.1", + "uuid": "^3.2.1" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } + } + }, + "@overleaf/o-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@overleaf/o-error/-/o-error-2.1.0.tgz", + "integrity": "sha512-Zd9sks9LrLw8ErHt/cXeWIkyxWAqNAvNGn7wIjLQJH6TTEEW835PWOhpch+hQwwWsTxWIx/JDj+IpZ3ouw925g==" + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -431,11 +999,22 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, + "@tootallnate/once": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz", + "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==" + }, "@types/caseless": { "version": "0.12.2", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, "@types/console-log-level": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz", @@ -455,10 +1034,10 @@ "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", "dev": true }, - "@types/form-data": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", - "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "@types/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", "requires": { "@types/node": "*" } @@ -470,24 +1049,49 @@ "dev": true }, "@types/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", - "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", + "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/node": { - "version": "12.0.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz", - "integrity": "sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg==" + "version": "10.17.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.17.tgz", + "integrity": "sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q==" }, "@types/request": { - "version": "2.48.1", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", - "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", + "version": "2.48.4", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz", + "integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==", "requires": { "@types/caseless": "*", - "@types/form-data": "*", "@types/node": "*", - "@types/tough-cookie": "*" + "@types/tough-cookie": "*", + "form-data": "^2.5.0" + }, + "dependencies": { + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + } } }, "@types/semver": { @@ -496,9 +1100,9 @@ "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" }, "@types/tough-cookie": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", - "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz", + "integrity": "sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ==" }, "@typescript-eslint/experimental-utils": { "version": "1.13.0", @@ -574,11 +1178,26 @@ "dev": true }, "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", + "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", "requires": { - "es6-promisify": "^5.0.0" + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "ajv": { @@ -593,12 +1212,20 @@ } }, "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } } }, "ansi-regex": { @@ -672,16 +1299,10 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha1-yWVekzHgq81YjSp8rX6ZVvZnAfo=" }, - "asn1": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz", - "integrity": "sha1-VZvhg3bQik7E2+gId9J4GGObLfc=", - "dev": true - }, "assert-plus": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.5.tgz", - "integrity": "sha1-7nQAlBMALYTOxyGcasgRgS5yMWA=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "assertion-error": { @@ -722,15 +1343,15 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "aws-sign2": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.5.0.tgz", - "integrity": "sha1-xXED96F/wDfwLXwuZLYC6iI/fWM=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, "axios": { "version": "0.18.1", @@ -748,15 +1369,15 @@ "dev": true }, "babel-eslint": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz", - "integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", "eslint-visitor-keys": "^1.0.0", "resolve": "^1.12.0" }, @@ -778,9 +1399,9 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -808,35 +1429,6 @@ "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, - "bl": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/bl/-/bl-0.9.5.tgz", - "integrity": "sha1-wGt5evCF6gC8Unr8jvzxHeIjIFQ=", - "dev": true, - "requires": { - "readable-stream": "~1.0.26" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -860,15 +1452,6 @@ "integrity": "sha512-ma2q0Tc760dW54CdOyJjhrg/a54317o1zYADQJFgperNGKIKgAUGIcKnuMiff8z57+yGlrGNEt4lPgZfCgTJgA==", "dev": true }, - "boom": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/boom/-/boom-0.4.2.tgz", - "integrity": "sha1-emNune1O/O+xnO9JR6PGffrukRs=", - "dev": true, - "requires": { - "hoek": "0.9.x" - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1042,6 +1625,11 @@ } } }, + "coffee-script": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1058,12 +1646,12 @@ "dev": true }, "combined-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", - "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { - "delayed-stream": "0.0.5" + "delayed-stream": "~1.0.0" } }, "commander": { @@ -1132,6 +1720,12 @@ "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", "dev": true }, + "core-js-pure": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz", + "integrity": "sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==", + "dev": true + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -1150,20 +1744,10 @@ "which": "^1.2.9" } }, - "cryptiles": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-0.2.2.tgz", - "integrity": "sha1-7ZH/HxetE9N0gohZT4pIoNJvMlw=", - "dev": true, - "requires": { - "boom": "0.4.x" - } - }, - "ctype": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.3.tgz", - "integrity": "sha1-gsGMJGH3QRTvFsE1IkrQuRRMoS8=", - "dev": true + "d64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", + "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" }, "damerau-levenshtein": { "version": "1.0.6", @@ -1230,9 +1814,9 @@ "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==" }, "delayed-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz", - "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, "depd": { @@ -1260,6 +1844,14 @@ "esutils": "^2.0.2" } }, + "dot-prop": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "requires": { + "is-obj": "^2.0.0" + } + }, "dtrace-provider": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", @@ -1325,9 +1917,9 @@ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "requires": { "once": "^1.4.0" } @@ -1408,9 +2000,9 @@ "dev": true }, "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", @@ -1428,7 +2020,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", @@ -1441,7 +2033,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", @@ -1461,6 +2053,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" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1476,18 +2077,18 @@ } }, "eslint-config-prettier": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.0.tgz", - "integrity": "sha512-AtndijGte1rPILInUdHjvKEGbIV06NuvPrqlIEaEaWtbtvJh464mDeyGMdZEQMsGvC0ZVkiex1fSNcC4HAbRGg==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz", + "integrity": "sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ==", "dev": true, "requires": { "get-stdin": "^6.0.0" } }, "eslint-config-standard": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz", - "integrity": "sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", + "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", "dev": true }, "eslint-config-standard-jsx": { @@ -1671,12 +2272,24 @@ } }, "eslint-plugin-mocha": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.2.2.tgz", - "integrity": "sha512-oNhPzfkT6Q6CJ0HMVJ2KLxEWG97VWGTmuHOoRcDLE0U88ugUyFNV9wrT2XIt5cGtqc5W9k38m4xTN34L09KhBA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz", + "integrity": "sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg==", "dev": true, "requires": { - "ramda": "^0.26.1" + "eslint-utils": "^2.0.0", + "ramda": "^0.27.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } } }, "eslint-plugin-node": { @@ -1732,9 +2345,9 @@ "dev": true }, "eslint-plugin-react": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.18.3.tgz", - "integrity": "sha512-Bt56LNHAQCoou88s8ViKRjMB2+36XRejCQ1VoLj716KI1MoE99HpTVvIThJ0rvFmG4E4Gsq+UgToEjn+j044Bg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz", + "integrity": "sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==", "dev": true, "requires": { "array-includes": "^3.1.1", @@ -1745,8 +2358,10 @@ "object.fromentries": "^2.0.2", "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.14.2", - "string.prototype.matchall": "^4.0.2" + "resolve": "^1.15.1", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.2", + "xregexp": "^4.3.0" }, "dependencies": { "doctrine": { @@ -1766,6 +2381,12 @@ "requires": { "path-parse": "^1.0.6" } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, @@ -1801,13 +2422,13 @@ "dev": true }, "espree": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", - "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", "dev": true, "requires": { - "acorn": "^7.1.0", - "acorn-jsx": "^5.1.0", + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", "eslint-visitor-keys": "^1.1.0" }, "dependencies": { @@ -1816,6 +2437,12 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true + }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true } } }, @@ -1865,6 +2492,22 @@ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" }, + "eventid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eventid/-/eventid-1.0.0.tgz", + "integrity": "sha512-4upSDsvpxhWPsmw4fsJCp0zj8S7I0qh1lCDTmZXP8V3TtryQKDI8CgQPN+e5JakbWwzaAX3lrdp2b3KSoMSUpw==", + "requires": { + "d64": "^1.0.0", + "uuid": "^3.0.1" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + } + } + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -1946,14 +2589,14 @@ "dev": true }, "fast-text-encoding": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", - "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.1.tgz", + "integrity": "sha512-x4FEgaz3zNRtJfLFqJmHWxkMDDvXVtaznj2V9jiP8ACUJrUgist4bP9FmDL2Vew2Y9mEQI/tG4GqabaitYp9CQ==" }, "figures": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", - "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -2062,28 +2705,20 @@ } }, "forever-agent": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.5.2.tgz", - "integrity": "sha1-bQ4JxJIflKJ/Y9O0nF/v8epMUTA=", + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, "form-data": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.1.4.tgz", - "integrity": "sha1-kavXiKupcCsaq/qLwBAxoqyeOxI=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { - "async": "~0.9.0", - "combined-stream": "~0.0.4", - "mime": "~1.2.11" - }, - "dependencies": { - "async": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", - "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", - "dev": true - } + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" } }, "formatio": { @@ -2124,22 +2759,23 @@ "dev": true }, "gaxios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", - "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.2.tgz", + "integrity": "sha512-K/+py7UvKRDaEwEKlLiRKrFr+wjGjsMz5qH7Vs549QJS7cpSCOT/BbWL7pzqECflc46FcNPipjSfB+V1m8PAhw==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", - "https-proxy-agent": "^2.2.1", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", "node-fetch": "^2.3.0" } }, "gcp-metadata": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz", - "integrity": "sha512-Q6HrgfrCQeEircnNP3rCcEgiDv7eF9+1B+1MMgpE190+/+0mjQR8PxeOaRgxZWmdDAF9EIryHB9g1moPiw1SbQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-3.5.0.tgz", + "integrity": "sha512-ZQf+DLZ5aKcRpLzYUyBS3yo3N0JSa82lNDO8rj3nMSlovLcz2riKFBsYgDzeXcv75oo5eqB2lx+B14UvPoCRnA==", "requires": { - "gaxios": "^1.0.2", + "gaxios": "^2.1.0", "json-bigint": "^0.3.0" } }, @@ -2184,9 +2820,9 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -2199,28 +2835,56 @@ "dev": true }, "google-auth-library": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz", - "integrity": "sha512-cDQMzTotwyWMrg5jRO7q0A4TL/3GWBgO7I7q5xGKNiiFf9SmGY/OJ1YsLMgI2MVHHsEGyrqYnbnmV1AE+Z6DnQ==", + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.10.1.tgz", + "integrity": "sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==", "requires": { + "arrify": "^2.0.0", "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", "fast-text-encoding": "^1.0.0", - "gaxios": "^1.2.1", - "gcp-metadata": "^1.0.0", - "gtoken": "^2.3.2", - "https-proxy-agent": "^2.2.1", - "jws": "^3.1.5", - "lru-cache": "^5.0.0", - "semver": "^5.5.0" + "gaxios": "^2.1.0", + "gcp-metadata": "^3.4.0", + "gtoken": "^4.1.0", + "jws": "^4.0.0", + "lru-cache": "^5.0.0" + } + }, + "google-gax": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-1.15.1.tgz", + "integrity": "sha512-1T1PwSZWnbdRusA+NCZMSe56iU6swGvuZuy54eYl9vEHiRXTLYbQmUkWY2CqgYD9Fd/T4WBkUl22+rZG80unyw==", + "requires": { + "@grpc/grpc-js": "^0.6.18", + "@grpc/proto-loader": "^0.5.1", + "@types/fs-extra": "^8.0.1", + "@types/long": "^4.0.0", + "abort-controller": "^3.0.0", + "duplexify": "^3.6.0", + "google-auth-library": "^5.0.0", + "is-stream-ended": "^0.1.4", + "lodash.at": "^4.6.0", + "lodash.has": "^4.5.2", + "node-fetch": "^2.6.0", + "protobufjs": "^6.8.9", + "retry-request": "^4.0.0", + "semver": "^6.0.0", + "walkdir": "^0.4.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } } }, "google-p12-pem": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", - "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.4.tgz", + "integrity": "sha512-S4blHBQWZRnEW44OcR7TL9WR+QCqByRvhNDZ/uuQfpxywfupikf/miba8js1jZi6ZOGv5slgSuoshCWh6EMDzg==", "requires": { - "node-forge": "^0.8.0", - "pify": "^4.0.0" + "node-forge": "^0.9.0" } }, "graceful-fs": { @@ -2230,15 +2894,14 @@ "dev": true }, "gtoken": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", - "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.1.4.tgz", + "integrity": "sha512-VxirzD0SWoFUo5p8RDP8Jt2AGyOmyYcT/pOUgDKJCK+iSw0TMqwrVfY37RXTNmoKwrzmDHSk0GMT9FsgVmnVSA==", "requires": { - "gaxios": "^1.0.4", - "google-p12-pem": "^1.0.0", - "jws": "^3.1.5", - "mime": "^2.2.0", - "pify": "^4.0.0" + "gaxios": "^2.1.0", + "google-p12-pem": "^2.0.0", + "jws": "^4.0.0", + "mime": "^2.2.0" }, "dependencies": { "mime": { @@ -2300,18 +2963,6 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, - "hawk": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-1.1.1.tgz", - "integrity": "sha1-h81JH5tG5OKurKM1QWdmiF0tHtk=", - "dev": true, - "requires": { - "boom": "0.4.x", - "cryptiles": "0.2.x", - "hoek": "0.9.x", - "sntp": "0.2.x" - } - }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", @@ -2323,12 +2974,6 @@ "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz", "integrity": "sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==" }, - "hoek": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz", - "integrity": "sha1-PTIkYrrfB3Fup+uFuviAec3c5QU=", - "dev": true - }, "hosted-git-info": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", @@ -2347,30 +2992,55 @@ "toidentifier": "1.0.0" } }, - "http-signature": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-0.10.1.tgz", - "integrity": "sha1-T72sEyVZqoMjEh5UB3nAoBKyfmY=", - "dev": true, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "requires": { - "asn1": "0.1.11", - "assert-plus": "^0.1.5", - "ctype": "0.5.3" - } - }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "dependencies": { "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { "ms": "^2.1.1" } @@ -2441,24 +3111,94 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "inquirer": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", - "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", - "chalk": "^2.4.2", + "chalk": "^3.0.0", "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.15", "mute-stream": "0.0.8", - "run-async": "^2.2.0", + "run-async": "^2.4.0", "rxjs": "^6.5.3", "string-width": "^4.1.0", - "strip-ansi": "^5.1.0", + "strip-ansi": "^6.0.0", "through": "^2.3.6" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "run-async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", + "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "internal-slot": { @@ -2472,12 +3212,6 @@ "side-channel": "^1.0.2" } }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -2495,9 +3229,9 @@ "dev": true }, "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" }, "is-callable": { "version": "1.1.5", @@ -2532,6 +3266,11 @@ "is-extglob": "^2.1.1" } }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -2547,6 +3286,16 @@ "has": "^1.0.3" } }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" + }, + "is-stream-ended": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", + "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==" + }, "is-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", @@ -2668,9 +3417,9 @@ } }, "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", + "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.11", @@ -2678,11 +3427,11 @@ } }, "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", + "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", "requires": { - "jwa": "^1.4.1", + "jwa": "^2.0.0", "safe-buffer": "^5.0.1" } }, @@ -2732,6 +3481,21 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, + "lodash.at": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", + "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + }, + "lodash.has": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", + "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -2755,30 +3519,38 @@ "integrity": "sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==", "dev": true }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + }, "logger-sharelatex": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.7.0.tgz", - "integrity": "sha512-9sxDGPSphOMDqUqGpOu/KxFAVcpydKggWv60g9D7++FDCxGkhLLn0kmBkDdgB00d1PadgX1CBMWKzIBpptDU/Q==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.9.0.tgz", + "integrity": "sha512-yVTuha82047IiMOQLgQHCZGKkJo6I2+2KtiFKpgkIooR2yZaoTEvAeoMwBesSDSpGUpvUJ/+9UI+PmRyc+PQKQ==", "requires": { + "@google-cloud/logging-bunyan": "^2.0.0", + "@overleaf/o-error": "^2.0.0", "bunyan": "1.8.12", "raven": "1.1.3", - "request": "2.88.0" + "request": "2.88.0", + "yn": "^3.1.1" }, "dependencies": { "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "bunyan": { "version": "1.8.12", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", + "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", "requires": { "dtrace-provider": "~0.8", "moment": "^2.10.6", @@ -2797,21 +3569,21 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "dtrace-provider": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz", - "integrity": "sha512-V+HIGbAdxCIxddHNDwzXi6cx8Cz5RRlQOVcsryHfsyVVebpBEnDwHSgqxpgKzqeU/6/0DWqRLAGUwkbg2ecN1Q==", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", "optional": true, "requires": { - "nan": "^2.10.0" + "nan": "^2.14.0" } }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { "version": "2.3.3", @@ -2826,7 +3598,7 @@ "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -2882,15 +3654,15 @@ "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "requires": { "safe-buffer": "^5.0.1" } }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -3015,8 +3787,7 @@ "map-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", - "dev": true + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==" }, "media-typer": { "version": "0.3.0", @@ -3062,9 +3833,9 @@ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" }, "metrics-sharelatex": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.2.0.tgz", - "integrity": "sha512-kjj3EdkrOJrENLFW/QHiPqBr5AbGEHeti90nMbw6sjKO2TOcuPJHT2Y66m8tqgotnMPKw+kXToRs8Rc9+0xuMQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.6.1.tgz", + "integrity": "sha512-Fkzl3MDjhsFuCl2i3f0bAqyC9lp4MAt6/hF9HxI6CV5r42kCsbqkE81G61HySpna7hMXZ0cE8T+w+91nAMwCQQ==", "requires": { "@google-cloud/debug-agent": "^3.0.0", "@google-cloud/profiler": "^0.2.3", @@ -3072,22 +3843,17 @@ "coffee-script": "1.6.0", "lynx": "~0.1.1", "prom-client": "^11.1.3", - "underscore": "~1.6.0" + "underscore": "~1.6.0", + "yn": "^3.1.1" }, "dependencies": { - "coffee-script": { + "underscore": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" } } }, - "mime": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha512-Ysa2F/nqTNGHhhm9MV8ure4+Hc+Y8AWiqUdHxsO7xu8zc92ND9f3kpALHjaP026Ft17UfxrMt95c50PLUeynBw==", - "dev": true - }, "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", @@ -3298,9 +4064,9 @@ } }, "nan": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, "native-promise-only": { "version": "0.8.1", @@ -3392,15 +4158,9 @@ "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "node-forge": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.4.tgz", - "integrity": "sha512-UOfdpxivIYY4g5tqp5FNRNgROVNxRACUxxJREntJLFaJr1E0UEqFtUIk0F/jYx/E+Y6sVXd0KDi/m5My0yGCVw==" - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", + "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" }, "normalize-package-data": { "version": "2.5.0", @@ -3415,9 +4175,9 @@ } }, "oauth-sign": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.4.0.tgz", - "integrity": "sha1-8ilW8x6nFRqCHl8vsywRPK2Ln2k=", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { @@ -3580,9 +4340,9 @@ } }, "parse-duration": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.1.tgz", - "integrity": "sha512-MPkERaX8suJ97HH2TtTN81ASYdFWouJqcnfVYSFHvWCI13vN4NzbvKsBOYN/7o8cTSoaNVMz4H8wG7GjTj0q6g==" + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.2.tgz", + "integrity": "sha512-0qfMZyjOUFBeEIvJ5EayfXJqaEXxQ+Oj2b7tWJM3hvEXvXsYCk05EDVI23oYnEw2NaFYUWdABEVPBvBMh8L/pA==" }, "parse-json": { "version": "2.2.0", @@ -3684,9 +4444,9 @@ "dev": true }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-piXGBcY1zoFOG0MvHpNE5reAGseLmaCRifQ/fmfF49BcYkInEs/naD/unxGNAeOKFA5+JxVrPyMvMlpzcd20UA==", "dev": true }, "prettier-eslint": { @@ -3899,6 +4659,12 @@ "mimic-fn": "^1.0.0" } }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true + }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -4300,9 +5066,9 @@ "dev": true }, "prom-client": { - "version": "11.5.1", - "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.1.tgz", - "integrity": "sha512-AcFuxVgzoA/4nlpeg9SkM2HkDjNU3V7g2LCLwpudXSbcSLiFpRMVfsCoCY5RYeR/d9jkQng1mCmVKj1mPHvP0Q==", + "version": "11.5.3", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-11.5.3.tgz", + "integrity": "sha512-iz22FmTbtkyL2vt0MdDFY+kWof+S9UB/NACxSn2aJcewtw+EERsen0urSkZ2WrHseNdydsvcxCTAnPcSMZZv4Q==", "requires": { "tdigest": "^0.1.1" } @@ -4319,9 +5085,9 @@ } }, "protobufjs": { - "version": "6.8.8", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "version": "6.8.9", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.9.tgz", + "integrity": "sha512-j2JlRdUeL/f4Z6x4aU4gj9I2LECglC+5qR2TrWb193Tla1qfdaNQTZ8I27Pt7K0Ajmvjjpft7O3KWTGciz4gpw==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -4336,13 +5102,6 @@ "@types/long": "^4.0.0", "@types/node": "^10.1.0", "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "10.14.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.14.9.tgz", - "integrity": "sha512-NelG/dSahlXYtSoVPErrp06tYFrvzj8XLWmKA+X8x0W//4MqbUyZu++giUG/v0bjAT6/Qxa8IjodrfdACyb0Fg==" - } } }, "proxy-addr": { @@ -4355,9 +5114,64 @@ } }, "psl": { - "version": "1.1.32", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", - "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==" + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", + "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", + "requires": { + "duplexify": "^4.1.1", + "inherits": "^2.0.3", + "pump": "^3.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + } + } }, "punycode": { "version": "1.4.1", @@ -4376,9 +5190,9 @@ "dev": true }, "ramda": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.26.1.tgz", - "integrity": "sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==", + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", + "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==", "dev": true }, "range-parser": { @@ -4422,9 +5236,9 @@ } }, "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "read-pkg": { @@ -4500,45 +5314,37 @@ "dev": true }, "request": { - "version": "2.47.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.47.0.tgz", - "integrity": "sha1-Cen9Gk/tZZOoBe+CArIPDF7LSF8=", + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { - "aws-sign2": "~0.5.0", - "bl": "~0.9.0", - "caseless": "~0.6.0", - "combined-stream": "~0.0.5", - "forever-agent": "~0.5.0", - "form-data": "~0.1.0", - "hawk": "1.1.1", - "http-signature": "~0.10.0", - "json-stringify-safe": "~5.0.0", - "mime-types": "~1.0.1", - "node-uuid": "~1.4.0", - "oauth-sign": "~0.4.0", - "qs": "~2.3.1", - "stringstream": "~0.0.4", - "tough-cookie": ">=0.12.0", - "tunnel-agent": "~0.4.0" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" }, "dependencies": { - "caseless": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.6.0.tgz", - "integrity": "sha1-gWfBq4OX+1u5X5bSjlqBxQ8kesQ=", - "dev": true - }, - "mime-types": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-1.0.2.tgz", - "integrity": "sha1-mVrhOSq4r/y/yyZB3QVOlDwNXc4=", - "dev": true - }, "qs": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", - "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true } } @@ -4550,13 +5356,13 @@ "dev": true }, "require-in-the-middle": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.0.tgz", - "integrity": "sha512-GX12iFhCUzzNuIqvei0dTLUbBEjZ420KTY/MmDxe2GQKPDGyH/wgfGMWFABpnM/M6sLwC3IaSg8A95U6gIb+HQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.1.tgz", + "integrity": "sha512-EfkM2zANyGkrfIExsECMeNn/uzjvHrE9h36yLXSavmrDiH4tgDNvltAmEKnt4PNLbqKPHZz+uszW2wTKrLUX0w==", "requires": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", - "resolve": "^1.10.0" + "resolve": "^1.12.0" }, "dependencies": { "debug": { @@ -4571,6 +5377,14 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "requires": { + "path-parse": "^1.0.6" + } } } }, @@ -4605,6 +5419,7 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", "integrity": "sha1-QBSHC6KWF2uGND1Qtg87UGCc4jI=", + "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -4630,11 +5445,27 @@ "integrity": "sha512-jp4YlI0qyDFfXiXGhkCOliBN1G7fRH03Nqy8YdShzGqbY5/9S2x/IR6C88ls2DFkbWuL3ASkP7QD3pVrNpPgwQ==" }, "retry-request": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.0.0.tgz", - "integrity": "sha512-S4HNLaWcMP6r8E4TMH52Y7/pM8uNayOcTDDQNBwsCccL1uI+Ol2TljxRDPzaNfbhOB30+XWP5NnZkB3LiJxi1w==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz", + "integrity": "sha512-BINDzVtLI2BDukjWmjAIRZ0oglnCAkpP2vQjM3jdLhmT62h0xnQgciPwBRDAvHqpkPT2Wo1XuUyLyn6nbGrZQQ==", "requires": { - "through2": "^2.0.0" + "debug": "^4.1.1", + "through2": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } } }, "rimraf": { @@ -4879,13 +5710,13 @@ } } }, - "sntp": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-0.2.4.tgz", - "integrity": "sha1-+4hfGLDzqtGJ+CSGJTa87ux1CQA=", - "dev": true, + "snakecase-keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-3.1.2.tgz", + "integrity": "sha512-NrzHj8ctStnd1LYx3+L4buS7yildFum7WAbQQxkhPCNi3Qeqv7hoBne2c9n++HWxDG9Nv23pNEyyLCITZTv24Q==", "requires": { - "hoek": "0.9.x" + "map-obj": "^4.0.0", + "to-snake-case": "^1.0.0" } }, "source-map": { @@ -4985,10 +5816,18 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "stream-events": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", + "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", + "requires": { + "stubs": "^3.0.0" + } + }, "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha512-Afuc4BKirbx0fwm9bKOehZPG01DJkm/4qbklw4lo9nMPqd2x0kZTLcgwQUXdGiPPY489l3w8cQ5xEEAGbg8ACQ==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, "string-width": { "version": "4.2.0", @@ -5046,18 +5885,6 @@ "function-bind": "^1.1.1" } }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true - }, - "stringstream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", - "dev": true - }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -5087,6 +5914,11 @@ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", "dev": true }, + "stubs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + }, "supports-color": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", @@ -5160,19 +5992,21 @@ } }, "teeny-request": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.3.tgz", + "integrity": "sha512-TZG/dfd2r6yeji19es1cUIwAlVD8y+/svB1kAC2Y0bjEyysrfbO8EZvJBRwIE6WkwmUoB7uvWLwTIhJbMXZ1Dw==", "requires": { - "https-proxy-agent": "^2.2.1", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", "node-fetch": "^2.2.0", - "uuid": "^3.3.2" + "stream-events": "^1.0.5", + "uuid": "^7.0.0" }, "dependencies": { "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", + "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==" } } }, @@ -5194,12 +6028,11 @@ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", + "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "readable-stream": "2 || 3" } }, "thunky": { @@ -5227,18 +6060,38 @@ "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" }, + "to-no-case": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + }, + "to-snake-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", + "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", + "requires": { + "to-space-case": "^1.0.0" + } + }, + "to-space-case": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "requires": { + "to-no-case": "^1.0.0" + } + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "ip-regex": "^2.1.0", "psl": "^1.1.28", "punycode": "^2.1.1" }, @@ -5258,10 +6111,13 @@ "dev": true }, "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } }, "tweetnacl": { "version": "0.14.5", @@ -5305,9 +6161,9 @@ "dev": true }, "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==" + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", + "integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==" }, "unpipe": { "version": "1.0.0", @@ -5339,6 +6195,12 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, "v8-compile-cache": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", @@ -5451,6 +6313,11 @@ } } }, + "walkdir": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", + "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -5522,6 +6389,15 @@ "mkdirp": "^0.5.1" } }, + "xregexp": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", + "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", + "dev": true, + "requires": { + "@babel/runtime-corejs3": "^7.8.3" + } + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", @@ -5534,9 +6410,9 @@ "dev": true }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { "version": "13.3.0", @@ -5618,6 +6494,11 @@ "camelcase": "^5.0.0", "decamelize": "^1.2.0" } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" } } } diff --git a/services/docstore/package.json b/services/docstore/package.json index bfd8372cbc..3d44140479 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -22,35 +22,35 @@ "async": "~0.8.0", "body-parser": "^1.19.0", "express": "^4.17.1", - "logger-sharelatex": "^1.7.0", - "metrics-sharelatex": "^2.2.0", + "logger-sharelatex": "^1.9.0", + "metrics-sharelatex": "^2.6.1", "mongojs": "2.4.0", "settings-sharelatex": "^1.1.0", - "underscore": "~1.6.0" + "underscore": "~1.9.2" }, "devDependencies": { - "babel-eslint": "^10.0.3", + "babel-eslint": "^10.1.0", "bunyan": "~0.22.3", "chai": "~1.9.1", - "eslint": "^6.6.0", - "eslint-config-prettier": "^6.10.0", - "eslint-config-standard": "^14.1.0", + "eslint": "^6.8.0", + "eslint-config-prettier": "^6.10.1", + "eslint-config-standard": "^14.1.1", "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.5.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-mocha": "^6.2.2", + "eslint-plugin-mocha": "^6.3.0", "eslint-plugin-node": "^11.0.0", "eslint-plugin-prettier": "^3.1.2", "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-react": "^7.18.3", + "eslint-plugin-react": "^7.19.0", "eslint-plugin-standard": "^4.0.1", "mocha": "^4.0.1", - "prettier": "^1.19.1", + "prettier": "^2.0.1", "prettier-eslint-cli": "^5.0.0", - "request": "~2.47.0", + "request": "~2.88.2", "sandboxed-module": "~0.3.0", "sinon": "~3.2.1" }, From 25704ea3010d16b32e45b50da3965bd3ebbf4cb8 Mon Sep 17 00:00:00 2001 From: mserranom <mserranom@gmail.com> Date: Mon, 23 Mar 2020 12:39:09 +0100 Subject: [PATCH 241/349] updated chai, mocha, sinon and sandboxed-module --- services/docstore/package-lock.json | 650 +++++++++++++++++++--------- services/docstore/package.json | 8 +- 2 files changed, 457 insertions(+), 201 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 40f37cd380..220de46c98 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -972,25 +972,36 @@ "dev": true, "requires": { "type-detect": "4.0.8" - }, - "dependencies": { - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - } + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.0.tgz", + "integrity": "sha512-atR1J/jRXvQAb47gfzSK8zavXy7BcpnYq21ALon0U99etu99vsir0trzIO3wpeLtW+LLVY6X7EkfVTbjGSH8Ww==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/formatio": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", + "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^5.0.2" } }, "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.0.3.tgz", + "integrity": "sha512-QucHkc2uMJ0pFGjJUDP3F9dq5dx8QIaqISl9QgwLOh6P9yv877uONPGXh/OH/0zmM3tW1JjuJltAZV2l7zU+uQ==", "dev": true, "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" } }, "@sinonjs/text-encoding": { @@ -1211,6 +1222,12 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", @@ -1243,6 +1260,16 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1267,12 +1294,6 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, - "array-from": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", - "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", - "dev": true - }, "array-includes": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", @@ -1306,9 +1327,9 @@ "dev": true }, "assertion-error": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", - "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, "ast-types-flow": { @@ -1416,6 +1437,12 @@ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, "bindings": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", @@ -1461,10 +1488,19 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, "bson": { @@ -1531,13 +1567,17 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "chai": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/chai/-/chai-1.9.2.tgz", - "integrity": "sha1-Pxog+CsLnXQ3V30k1vErGmnTtZA=", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "dev": true, "requires": { - "assertion-error": "1.0.0", - "deep-eql": "0.1.3" + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" } }, "chalk": { @@ -1574,6 +1614,28 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -1785,12 +1847,12 @@ "dev": true }, "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "type-detect": "0.1.1" + "type-detect": "^4.0.0" } }, "deep-is": { @@ -1829,6 +1891,12 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, "dlv": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", @@ -2616,6 +2684,15 @@ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -2644,6 +2721,15 @@ "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -2721,15 +2807,6 @@ "mime-types": "^2.1.12" } }, - "formatio": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.2.0.tgz", - "integrity": "sha1-87IWfZBoxGmKjVH092CjmlTYGOs=", - "dev": true, - "requires": { - "samsam": "1.x" - } - }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -2746,6 +2823,13 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -2785,6 +2869,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", @@ -2893,6 +2983,12 @@ "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "gtoken": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.1.4.tgz", @@ -2952,9 +3048,9 @@ } }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-symbols": { @@ -2964,9 +3060,9 @@ "dev": true }, "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "hex2dec": { @@ -3228,6 +3324,15 @@ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", @@ -3266,6 +3371,12 @@ "is-extglob": "^2.1.1" } }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -3416,6 +3527,12 @@ "object.assign": "^4.1.0" } }, + "just-extend": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", + "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", + "dev": true + }, "jwa": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", @@ -3491,6 +3608,12 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", @@ -3524,6 +3647,15 @@ "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" }, + "log-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2" + } + }, "logger-sharelatex": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.9.0.tgz", @@ -3724,12 +3856,6 @@ } } }, - "lolex": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.6.0.tgz", - "integrity": "sha1-z5Fm88nezjzetdawH85Q8UoSA+M=", - "dev": true - }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -3881,12 +4007,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, "mkdirp": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", @@ -3903,48 +4023,65 @@ } }, "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha1-fYbPvPNcuCnidUwy4XNV7AUzh5Q=", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.1.tgz", + "integrity": "sha512-3qQsu3ijNS3GkWcccT5Zw0hf/rWvu1fTN9sPvEd81hlwsr30GX2GcDSSoBxo24IR8FelmrAydGC6/1J5QQP4WA==", "dev": true, "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "3.0.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.3", + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" }, "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha1-FXFS/R56bI2YpbcVzzdt+SgARWM=", - "dev": true - }, "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha1-qoVnpu7QPFMfyJ0/cRzQ5SWd7HU=", + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -3955,19 +4092,80 @@ "path-is-absolute": "^1.0.0" } }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha1-GSa6kM8+3+KttJJ/WIC8IsZseQ8=", + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "minimist": "0.0.8" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -4068,12 +4266,6 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, - "native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", - "dev": true - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4098,49 +4290,24 @@ "dev": true }, "nise": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.3.tgz", - "integrity": "sha512-Ymbac/94xeIrMf59REBPOv0thr+CJVFMhrlAkW/gjCIE58BGQdCj0x7KRCb3yz+Ga2Rz3E9XXSvUyyxqqhjQAQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.3.tgz", + "integrity": "sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg==", "dev": true, "requires": { - "@sinonjs/formatio": "^3.2.1", + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", - "lolex": "^5.0.1", "path-to-regexp": "^1.7.0" }, "dependencies": { - "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, - "just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", - "dev": true - }, - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -4152,6 +4319,24 @@ } } }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", @@ -4174,6 +4359,12 @@ "validate-npm-package-license": "^3.0.1" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -4234,6 +4425,16 @@ "has": "^1.0.3" } }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "object.values": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", @@ -4418,11 +4619,23 @@ } } }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -5291,6 +5504,15 @@ } } }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, "regenerator-runtime": { "version": "0.13.3", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", @@ -5511,28 +5733,14 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" }, - "samsam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", - "integrity": "sha1-jR2TUOJWItow3j5EumkrUiGrfFA=", - "dev": true - }, "sandboxed-module": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-0.3.0.tgz", - "integrity": "sha1-8fvvvYCaT2kHO9B8rm/H2y6vX2o=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-2.0.3.tgz", + "integrity": "sha1-x+VFkzm7y6KMUwPusz9ug4e/upY=", "dev": true, "requires": { "require-like": "0.1.2", - "stack-trace": "0.0.6" - }, - "dependencies": { - "stack-trace": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.6.tgz", - "integrity": "sha1-HnGb1qJin/CcGJ4Xqe+QKpT8XbA=", - "dev": true - } + "stack-trace": "0.0.9" } }, "semver": { @@ -5646,48 +5854,40 @@ "dev": true }, "sinon": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-3.2.1.tgz", - "integrity": "sha1-2K2r2QBzD9SXeIoCcEnGSwi+kcI=", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.1.tgz", + "integrity": "sha512-iTTyiQo5T94jrOx7X7QLBZyucUJ2WvL9J13+96HMfm2CGoJYbIPqRfl6wgNcqmzk0DI28jeGx5bUTXizkrqBmg==", "dev": true, "requires": { - "diff": "^3.1.0", - "formatio": "1.2.0", - "lolex": "^2.1.2", - "native-promise-only": "^0.8.1", - "nise": "^1.0.1", - "path-to-regexp": "^1.7.0", - "samsam": "^1.1.3", - "text-encoding": "0.6.4", - "type-detect": "^4.0.0" + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/formatio": "^5.0.1", + "@sinonjs/samsam": "^5.0.3", + "diff": "^4.0.2", + "nise": "^4.0.1", + "supports-color": "^7.1.0" }, "dependencies": { "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "path-to-regexp": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", - "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { - "isarray": "0.0.1" + "has-flag": "^4.0.0" } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha1-dkb7XxiHHPu3dJ5pvTmmOI63RQw=", - "dev": true } } }, @@ -5920,12 +6120,12 @@ "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha1-iD992rwWUUKyphQn8zUt7RldGj4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "has-flag": "^3.0.0" } }, "table": { @@ -6010,12 +6210,6 @@ } } }, - "text-encoding": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", - "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", - "dev": true - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6065,6 +6259,15 @@ "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "to-snake-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", @@ -6134,9 +6337,9 @@ } }, "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, "type-fest": { @@ -6333,6 +6536,48 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -6495,6 +6740,17 @@ "decamelize": "^1.2.0" } }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + } + }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/services/docstore/package.json b/services/docstore/package.json index 3d44140479..518b48a3b8 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -31,7 +31,7 @@ "devDependencies": { "babel-eslint": "^10.1.0", "bunyan": "~0.22.3", - "chai": "~1.9.1", + "chai": "~4.2.0", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", "eslint-config-standard": "^14.1.1", @@ -47,12 +47,12 @@ "eslint-plugin-promise": "^4.2.1", "eslint-plugin-react": "^7.19.0", "eslint-plugin-standard": "^4.0.1", - "mocha": "^4.0.1", + "mocha": "^7.1.1", "prettier": "^2.0.1", "prettier-eslint-cli": "^5.0.0", "request": "~2.88.2", - "sandboxed-module": "~0.3.0", - "sinon": "~3.2.1" + "sandboxed-module": "~2.0.3", + "sinon": "~9.0.1" }, "engines": { "node": "~6.14.1" From 91a1fadbb13733a1a5f6744206b43ea5a363e215 Mon Sep 17 00:00:00 2001 From: mserranom <mserranom@gmail.com> Date: Mon, 23 Mar 2020 12:45:29 +0100 Subject: [PATCH 242/349] updated async and bunyan --- services/docstore/package-lock.json | 933 ++++++++++++++++++++++------ services/docstore/package.json | 6 +- 2 files changed, 729 insertions(+), 210 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 220de46c98..25587d1d54 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -8,7 +8,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "dev": true, "requires": { "@babel/highlight": "^7.8.3" } @@ -17,7 +16,6 @@ "version": "7.9.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", - "dev": true, "requires": { "@babel/types": "^7.9.0", "jsesc": "^2.5.1", @@ -28,8 +26,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" } } }, @@ -37,7 +34,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", @@ -48,7 +44,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -57,7 +52,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -65,14 +59,12 @@ "@babel/helper-validator-identifier": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", - "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", - "dev": true + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==" }, "@babel/highlight": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -82,8 +74,7 @@ "@babel/parser": { "version": "7.9.3", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.3.tgz", - "integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==", - "dev": true + "integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==" }, "@babel/runtime": { "version": "7.8.4", @@ -116,7 +107,6 @@ "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.6", @@ -127,7 +117,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", - "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -144,7 +133,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -152,8 +140,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -161,7 +148,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.9.0", "lodash": "^4.17.13", @@ -1255,7 +1241,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1270,11 +1255,23 @@ "picomatch": "^2.0.4" } }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -1345,9 +1342,12 @@ "dev": true }, "async": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/async/-/async-0.8.0.tgz", - "integrity": "sha1-7mXsdymML/FFa8RBigUtDwZDURI=" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "^4.17.14" + } }, "async-listener": { "version": "0.6.10", @@ -1456,6 +1456,15 @@ "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, + "bl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", + "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -1504,33 +1513,30 @@ "dev": true }, "bson": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.6.tgz", - "integrity": "sha1-RE21nd1MJPDLBjqr3FyMewzsqRI=" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", + "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, - "buffer-shims": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" - }, "builtin-modules": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" }, "bunyan": { - "version": "0.22.3", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-0.22.3.tgz", - "integrity": "sha1-ehncG0yMZF90AkGnQPIkUUfGfsI=", + "version": "1.8.12", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", + "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", "dev": true, "requires": { - "dtrace-provider": "0.2.8", - "mv": "~2" + "dtrace-provider": "~0.8", + "moment": "^2.10.6", + "mv": "~2", + "safe-json-stringify": "~1" } }, "bytes": { @@ -1538,6 +1544,17 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1547,8 +1564,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "camelcase-keys": { "version": "6.1.2", @@ -1584,7 +1600,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1594,14 +1609,12 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -1655,7 +1668,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", @@ -1665,20 +1677,17 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -1696,7 +1705,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -1704,8 +1712,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" }, "combined-stream": { "version": "1.0.8", @@ -1728,6 +1735,11 @@ "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", "dev": true }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1766,6 +1778,14 @@ "emitter-listener": "^1.1.1" } }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -1793,6 +1813,18 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -1843,8 +1875,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" }, "deep-eql": { "version": "3.0.1", @@ -1861,6 +1892,14 @@ "integrity": "sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==", "dev": true }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "requires": { + "strip-bom": "^3.0.0" + } + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -1881,6 +1920,11 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, + "denque": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz", + "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ==" + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1921,11 +1965,14 @@ } }, "dtrace-provider": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.2.8.tgz", - "integrity": "sha1-4kPxkhmqlfvw2PL/sH9b1k6U/iA=", + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", + "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", "dev": true, - "optional": true + "optional": true, + "requires": { + "nan": "^2.14.0" + } }, "duplexify": { "version": "3.7.1", @@ -2001,7 +2048,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -2036,10 +2082,10 @@ "is-symbol": "^1.0.2" } }, - "es6-promise": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.2.1.tgz", - "integrity": "sha1-7FYjOGgDKQkgcXDDlEjiREndH8Q=" + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" }, "es6-promisify": { "version": "5.0.0", @@ -2064,8 +2110,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eslint": { "version": "6.8.0", @@ -2517,8 +2562,7 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { "version": "1.1.0", @@ -2547,8 +2591,7 @@ "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "etag": { "version": "1.8.1", @@ -2707,6 +2750,51 @@ "unpipe": "~1.0.0" } }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "requires": { + "find-up": "^3.0.0" + } + } + } + }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -2790,6 +2878,40 @@ } } }, + "foreground-child": { + "version": "1.5.6", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -2820,8 +2942,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.1.2", @@ -2866,8 +2987,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { "version": "2.0.0", @@ -2921,8 +3041,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "google-auth-library": { "version": "5.10.1", @@ -2980,8 +3099,7 @@ "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "growl": { "version": "1.10.5", @@ -3050,8 +3168,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.1", @@ -3059,6 +3176,21 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "requires": { + "is-stream": "^1.0.1" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + } + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -3073,8 +3205,12 @@ "hosted-git-info": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" + }, + "html-escaper": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.1.tgz", + "integrity": "sha512-hNX23TjWwD3q56HpWjUHOKj1+4KKlnjv9PcmBUYKVpga+2cnb9nDx/B1o0yO4n+RZXZdiNxzx6B24C9aNMTkkQ==" }, "http-errors": { "version": "1.7.2", @@ -3183,8 +3319,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" }, "indent-string": { "version": "4.0.0", @@ -3321,8 +3456,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" }, "is-binary-path": { "version": "2.1.0", @@ -3435,25 +3569,132 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" + }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "requires": { + "html-escaper": "^2.0.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -3467,8 +3708,7 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, "json-bigint": { "version": "0.3.0", @@ -3478,6 +3718,11 @@ "bignumber.js": "^7.0.0" } }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -3595,8 +3840,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.at": { "version": "4.6.0", @@ -3608,6 +3852,11 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -3892,6 +4141,22 @@ "statsd-parser": "~0.0.4" } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "make-plural": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", @@ -3920,11 +4185,25 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "memory-pager": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz", + "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==", + "optional": true + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "requires": { + "source-map": "^0.6.1" + } + }, "mersenne": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", @@ -4182,61 +4461,43 @@ "optional": true }, "mongodb": { - "version": "2.2.35", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-2.2.35.tgz", - "integrity": "sha1-zRta+KlGPj+aeH+ls9BVZVeXMPk=", + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.5.tgz", + "integrity": "sha512-GCjDxR3UOltDq00Zcpzql6dQo1sVry60OXJY3TDmFc2SWFY6c8Gn1Ardidc5jDirvJrx2GC3knGOImKphbSL3A==", "requires": { - "es6-promise": "3.2.1", - "mongodb-core": "2.1.19", - "readable-stream": "2.2.7" - }, - "dependencies": { - "readable-stream": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.7.tgz", - "integrity": "sha1-BwV6y+JGeyIELTb5jFrVBwVOlbE=", - "requires": { - "buffer-shims": "~1.0.0", - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~1.0.0", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "mongodb-core": { - "version": "2.1.19", - "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-2.1.19.tgz", - "integrity": "sha1-APvV5aNXN2O5Fxz9hE5gqPKjoYs=", - "requires": { - "bson": "~1.0.4", - "require_optional": "~1.0.0" + "bl": "^2.2.0", + "bson": "^1.1.1", + "denque": "^1.4.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" } }, "mongojs": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-2.4.0.tgz", - "integrity": "sha1-8of7/UV/7fWItakBHmhRPZ3TK/s=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-3.1.0.tgz", + "integrity": "sha512-aXJ4xfXwx9s1cqtKTZ24PypXiWhIgvgENObQzCGbV4QBxEVedy3yuErhx6znk959cF2dOzL2ClgXJvIhfgkpIQ==", "requires": { "each-series": "^1.0.0", - "mongodb": "^2.0.45", - "once": "^1.3.2", - "parse-mongo-url": "^1.1.0", - "readable-stream": "^2.0.2", - "thunky": "^0.1.0", - "to-mongodb-core": "^2.0.0", - "xtend": "^4.0.0" + "mongodb": "^3.3.2", + "nyc": "^14.1.1", + "once": "^1.4.0", + "parse-mongo-url": "^1.1.1", + "readable-stream": "^3.4.0", + "thunky": "^1.1.0", + "to-mongodb-core": "^2.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, "ms": { @@ -4283,6 +4544,11 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -4351,7 +4617,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -4365,6 +4630,91 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "nyc": { + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", + "requires": { + "archy": "^1.0.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -4486,6 +4836,11 @@ "word-wrap": "~1.2.3" } }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -4531,6 +4886,17 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=" }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4572,8 +4938,7 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" }, "path-is-absolute": { "version": "1.0.1", @@ -5267,11 +5632,6 @@ "parse-ms": "^2.0.0" } }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" - }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -5326,6 +5686,11 @@ "ipaddr.js": "1.9.1" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "psl": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", @@ -5535,6 +5900,14 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "requires": { + "es6-error": "^4.0.1" + } + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -5574,8 +5947,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" }, "require-in-the-middle": { "version": "4.0.1", @@ -5619,8 +5991,7 @@ "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "require-relative": { "version": "0.8.7", @@ -5631,7 +6002,7 @@ "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", "requires": { "resolve-from": "^2.0.0", "semver": "^5.1.0" @@ -5641,7 +6012,6 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", "integrity": "sha1-QBSHC6KWF2uGND1Qtg87UGCc4jI=", - "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -5743,6 +6113,15 @@ "stack-trace": "0.0.9" } }, + "saslprep": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz", + "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==", + "optional": true, + "requires": { + "sparse-bitfield": "^3.0.3" + } + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -5794,8 +6173,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "setprototypeof": { "version": "1.1.1", @@ -5850,8 +6228,7 @@ "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha512-meQNNykwecVxdu1RlYMKpQx4+wefIYpmxi6gexo/KAbwquJrBUrBmKYJrE8KFkVQAAVWEnwNdu21PgrD77J3xA==", - "dev": true + "integrity": "sha512-meQNNykwecVxdu1RlYMKpQx4+wefIYpmxi6gexo/KAbwquJrBUrBmKYJrE8KFkVQAAVWEnwNdu21PgrD77J3xA==" }, "sinon": { "version": "9.0.1", @@ -5924,11 +6301,55 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, + "sparse-bitfield": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "optional": true, + "requires": { + "memory-pager": "^1.0.2" + } + }, + "spawn-wrap": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", + "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -5937,14 +6358,12 @@ "spdx-exceptions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -5953,8 +6372,7 @@ "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "split": { "version": "1.0.1", @@ -5967,8 +6385,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "sshpk": { "version": "1.16.1", @@ -6085,11 +6502,25 @@ "function-bind": "^1.1.1" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" + } + } + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" }, @@ -6097,16 +6528,14 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" } } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" }, "strip-json-comments": { "version": "3.0.1", @@ -6210,6 +6639,109 @@ } } }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + } + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -6230,9 +6762,9 @@ } }, "thunky": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz", - "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, "tmp": { "version": "0.0.33", @@ -6246,8 +6778,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-mongodb-core": { "version": "2.0.0", @@ -6401,8 +6932,7 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, "v8-compile-cache": { "version": "2.1.0", @@ -6414,7 +6944,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -6525,7 +7054,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -6533,8 +7061,7 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" }, "wide-align": { "version": "1.1.3", @@ -6588,7 +7115,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -6598,20 +7124,17 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -6634,6 +7157,16 @@ "mkdirp": "^0.5.1" } }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, "xregexp": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", @@ -6643,16 +7176,10 @@ "@babel/runtime-corejs3": "^7.8.3" } }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" - }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { "version": "3.1.1", @@ -6663,7 +7190,6 @@ "version": "13.3.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", - "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -6680,14 +7206,12 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -6695,14 +7219,12 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -6712,7 +7234,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -6721,7 +7242,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -6734,7 +7254,6 @@ "version": "13.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" diff --git a/services/docstore/package.json b/services/docstore/package.json index 518b48a3b8..a06b33ee93 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -19,18 +19,18 @@ "format:fix": "node_modules/.bin/prettier-eslint '**/*.js' --write" }, "dependencies": { - "async": "~0.8.0", + "async": "^2.6.3", "body-parser": "^1.19.0", "express": "^4.17.1", "logger-sharelatex": "^1.9.0", "metrics-sharelatex": "^2.6.1", - "mongojs": "2.4.0", + "mongojs": "3.1.0", "settings-sharelatex": "^1.1.0", "underscore": "~1.9.2" }, "devDependencies": { "babel-eslint": "^10.1.0", - "bunyan": "~0.22.3", + "bunyan": "~1.8.12", "chai": "~4.2.0", "eslint": "^6.8.0", "eslint-config-prettier": "^6.10.1", From 56d044b5462ad6eafa98044058d631e9757b00c9 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween <eric.mcsween@overleaf.com> Date: Wed, 25 Mar 2020 10:07:26 -0400 Subject: [PATCH 243/349] Upgrade metrics-sharelatex to 2.6.2 This version fixes the HTTP request timing metrics, which were not reporting correctly. --- services/docstore/package-lock.json | 410 +++++++++++++--------------- services/docstore/package.json | 2 +- 2 files changed, 185 insertions(+), 227 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 25587d1d54..6cb2fd9f34 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -26,7 +26,7 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" } } }, @@ -332,11 +332,6 @@ "safe-buffer": "^5.0.1" } }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -361,11 +356,6 @@ "node-fetch": "^2.2.0", "uuid": "^3.3.2" } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -482,7 +472,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" }, "debug": { "version": "3.2.6", @@ -587,11 +577,6 @@ "safe-buffer": "^5.0.1" } }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -611,11 +596,6 @@ "node-fetch": "^2.2.0", "uuid": "^3.3.2" } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -785,11 +765,6 @@ "safe-buffer": "^5.0.1" } }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -814,11 +789,6 @@ "node-fetch": "^2.2.0", "uuid": "^3.3.2" } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -895,7 +865,7 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "@protobufjs/base64": { "version": "1.1.2", @@ -910,12 +880,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -924,27 +894,27 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "@sindresorhus/is": { "version": "0.15.0", @@ -1066,19 +1036,6 @@ "form-data": "^2.5.0" }, "dependencies": { - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, "form-data": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", @@ -1200,7 +1157,7 @@ "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha1-kNDVRDnaWHzX6EO/twRfUL0ivfE=", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -1266,7 +1223,7 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==" }, "argparse": { "version": "1.0.10", @@ -1289,7 +1246,7 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-includes": { "version": "3.1.1", @@ -1315,12 +1272,12 @@ "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha1-yWVekzHgq81YjSp8rX6ZVvZnAfo=" + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true }, "assertion-error": { @@ -1361,12 +1318,12 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", "dev": true }, "aws4": { @@ -1417,7 +1374,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==" }, "base64-js": { "version": "1.3.1", @@ -1427,7 +1384,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "requires": { "tweetnacl": "^0.14.3" } @@ -1454,7 +1411,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" + "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" }, "bl": { "version": "2.2.0", @@ -1491,7 +1448,7 @@ "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1520,7 +1477,7 @@ "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "builtin-modules": { "version": "3.1.0", @@ -1530,7 +1487,7 @@ "bunyan": { "version": "1.8.12", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", "dev": true, "requires": { "dtrace-provider": "~0.8", @@ -1580,7 +1537,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, "chai": { "version": "4.2.0", @@ -1630,7 +1587,7 @@ "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "chokidar": { @@ -1699,7 +1656,7 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" }, "color-convert": { "version": "1.9.3", @@ -1718,7 +1675,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -1738,12 +1694,12 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "console-log-level": { "version": "1.4.1", @@ -1794,7 +1750,7 @@ "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "core-js": { "version": "3.6.4", @@ -1811,7 +1767,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cp-file": { "version": "6.2.0", @@ -1841,7 +1797,7 @@ "d64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", - "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" + "integrity": "sha512-5eNy3WZziVYnrogqgXhcdEmqcDB2IHurTqLcrgssJsfkMVCUoUaZpK6cJjxxvLV2dUm5SuJMNcYfVGoin9UIRw==" }, "damerau-levenshtein": { "version": "1.0.6", @@ -1852,7 +1808,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "requires": { "assert-plus": "^1.0.0" }, @@ -1860,7 +1816,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -1895,7 +1851,7 @@ "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "integrity": "sha512-B0n2zDIXpzLzKeoEozorDSa1cHc1t0NjmxP0zuAxbizNU2MBqYJJKYXrrFdKuQliojXynrxgd7l4ahfg/+aA5g==", "requires": { "strip-bom": "^3.0.0" } @@ -1917,8 +1873,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "denque": { "version": "1.4.1", @@ -1928,12 +1883,12 @@ "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==" }, "destroy": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" }, "diff": { "version": "3.5.0", @@ -1988,12 +1943,12 @@ "each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" + "integrity": "sha512-4MQloCGGCmT5GJZK5ibgJSvTK1c1QSrNlDvLk6fEyRxjZnXjl+NNFfzhfXpmnWh33Owc9D9klrdzCUi7yc9r4Q==" }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -2010,7 +1965,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "emitter-listener": { "version": "1.1.2", @@ -2029,7 +1984,7 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" }, "end-of-stream": { "version": "1.4.4", @@ -2042,7 +1997,7 @@ "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" }, "error-ex": { "version": "1.3.2", @@ -2087,30 +2042,28 @@ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "requires": { "es6-promise": "^4.0.3" - }, - "dependencies": { - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - } } }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" }, "eslint": { "version": "6.8.0", @@ -2596,7 +2549,7 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" }, "event-target-shim": { "version": "5.0.1", @@ -2675,12 +2628,12 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, "fast-diff": { "version": "1.2.0", @@ -2691,7 +2644,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==" }, "fast-levenshtein": { "version": "2.0.6", @@ -2807,7 +2760,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" + "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" }, "flat": { "version": "4.1.0", @@ -2881,7 +2834,7 @@ "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", + "integrity": "sha512-3TOY+4TKV0Ml83PXJQY+JFQaHNV38lzQDIzzXYg1kWdBLenGgoZhAs0CKgzI31vi2pWEpQMq/Yi4bpKwCPkw7g==", "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" @@ -2890,7 +2843,7 @@ "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", + "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" @@ -2908,14 +2861,14 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" } } }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", "dev": true }, "form-data": { @@ -2932,17 +2885,17 @@ "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + "integrity": "sha512-Ua9xNhH0b8pwE3yRbFfXJvfdWF0UHNCdeyb2sbi9Ul/M+r3PTdrz7Cv4SCfZRMjmzEM9PhraqfZFbGTIg3OMyA==" }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.1.2", @@ -2992,7 +2945,7 @@ "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, "get-stdin": { @@ -3004,7 +2957,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "requires": { "assert-plus": "^1.0.0" }, @@ -3012,14 +2965,14 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, "glob": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", "optional": true, "requires": { "inflight": "^1.0.4", @@ -3128,7 +3081,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" }, "har-validator": { "version": "5.1.3", @@ -3168,7 +3121,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" }, "has-symbols": { "version": "1.0.1", @@ -3179,7 +3132,7 @@ "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "integrity": "sha512-w0Kz8lJFBoyaurBiNrIvxPqr/gJ6fOfSkpAPOepN3oECqGJag37xPbOv57izi/KP8auHgNYxn5fXtAb+1LsJ6w==", "requires": { "is-stream": "^1.0.1" }, @@ -3187,7 +3140,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" } } }, @@ -3252,7 +3205,7 @@ "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -3330,7 +3283,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3339,7 +3292,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "inquirer": { "version": "7.1.0", @@ -3487,7 +3440,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { @@ -3559,12 +3512,12 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", @@ -3574,7 +3527,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -3703,7 +3656,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "jsesc": { "version": "2.5.2", @@ -3713,7 +3666,7 @@ "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", + "integrity": "sha512-u+c/u/F+JNPUekHCFyGVycRPyh9UHD5iUhSyIAn10kxbDTJxijwAbT6XHaONEOXuGGfmWUSroheXgHcml4gLgg==", "requires": { "bignumber.js": "^7.0.0" } @@ -3726,12 +3679,12 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha1-afaofZUTq4u4/mO9sJecRI5oRmA=" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3742,12 +3695,12 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -3758,7 +3711,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -3845,28 +3798,28 @@ "lodash.at": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=" + "integrity": "sha512-GOTh0SEp+Yosnlpjic+8cl2WM9MykorogkGA9xyIFkkObQ3H3kNZqZ+ohuq4K3FrSVo7hMcZBMataJemrxC3BA==" }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" + "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==" }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" + "integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==" }, "lodash.memoize": { "version": "4.1.2", @@ -3883,7 +3836,7 @@ "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" + "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==" }, "lodash.unescape": { "version": "4.0.1", @@ -3921,17 +3874,17 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" }, "bunyan": { "version": "1.8.12", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=", + "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", "requires": { "dtrace-provider": "~0.8", "moment": "^2.10.6", @@ -3950,7 +3903,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "dtrace-provider": { "version": "0.8.8", @@ -3964,7 +3917,7 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" }, "form-data": { "version": "2.3.3", @@ -3979,7 +3932,7 @@ "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -4035,7 +3988,7 @@ "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "requires": { "safe-buffer": "^5.0.1" } @@ -4130,12 +4083,12 @@ "lsmod": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", - "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" + "integrity": "sha512-Y+6V75r+mGWzWEPr9h6PFmStielICu5JBHLUg18jCsD2VFmEfgHbq/EgnY4inElsUD9eKL9id1qp34w46rSIKQ==" }, "lynx": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", - "integrity": "sha1-Mxjc7xaQi4KG6Bisz9sxzXQkj50=", + "integrity": "sha512-JI52N0NwK2b/Md0TFPdPtUBI46kjyJXF7+q08l2yvQ56q6QA8s7ZjZQQRoxFpS2jDXNf/B0p8ID+OIKcTsZwzw==", "requires": { "mersenne": "~0.0.3", "statsd-parser": "~0.0.4" @@ -4183,7 +4136,7 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" }, "memory-pager": { "version": "1.5.0", @@ -4194,7 +4147,7 @@ "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "merge-source-map": { "version": "1.1.0", @@ -4207,7 +4160,7 @@ "mersenne": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", - "integrity": "sha1-QB/ex+whzbngPNPTAhOY2iGycIU=" + "integrity": "sha512-XoSUL+nF8hMTKGQxUs8r3Btdsf1yuKKBdCCGbh3YXgCXuVKishpZv1CNc385w9s8t4Ynwc5h61BwW/FCVulkbg==" }, "messageformat": { "version": "2.3.0", @@ -4235,12 +4188,12 @@ "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "metrics-sharelatex": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.6.1.tgz", - "integrity": "sha512-Fkzl3MDjhsFuCl2i3f0bAqyC9lp4MAt6/hF9HxI6CV5r42kCsbqkE81G61HySpna7hMXZ0cE8T+w+91nAMwCQQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.6.2.tgz", + "integrity": "sha512-bOLfkSCexiPgB96hdXhoOWyvvrwscgjeZPEqdcJ7BTGxY59anzvymNf5hTGJ1RtS4sblDKxITw3L5a+gYKhRYQ==", "requires": { "@google-cloud/debug-agent": "^3.0.0", "@google-cloud/profiler": "^0.2.3", @@ -4255,19 +4208,24 @@ "underscore": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + "integrity": "sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==" } } }, + "mime": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" + }, "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI=" + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" }, "mime-types": { "version": "2.1.24", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha1-tvjQs+lR77d97eyhlM/20W9nb4E=", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", "requires": { "mime-db": "1.40.0" } @@ -4281,7 +4239,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" } @@ -4374,7 +4332,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "locate-path": { @@ -4416,7 +4374,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true }, "yargs": { @@ -4452,7 +4410,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, "moment": { "version": "2.24.0", @@ -4503,7 +4461,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "mute-stream": { "version": "0.0.8", @@ -4514,7 +4472,7 @@ "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -4536,7 +4494,7 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "optional": true }, "negotiator": { @@ -4571,7 +4529,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "path-to-regexp": { @@ -4724,7 +4682,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "object-inspect": { @@ -4800,7 +4758,7 @@ "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", "requires": { "ee-first": "1.1.1" } @@ -4808,7 +4766,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -4839,7 +4797,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==" }, "os-tmpdir": { "version": "1.0.2", @@ -4850,7 +4808,7 @@ "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha1-QXyZQeYCepq8ulCS3SkE4lW1+8I=", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "requires": { "p-try": "^2.0.0" } @@ -4884,7 +4842,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha1-yyhoVA4xPWHeWPr741zpAE1VQOY=" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-hash": { "version": "3.0.0", @@ -4923,7 +4881,7 @@ "parse-mongo-url": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" + "integrity": "sha512-7bZUusQIrFLwvsLHBnCz2WKYQ5LKO/LwKPnvQxbMIh9gDx8H5ZsknRmLjZdn6GVdrgVOwqDrZKsY0qDLNmRgcw==" }, "parse-ms": { "version": "2.1.0", @@ -4943,7 +4901,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-is-inside": { "version": "1.0.2", @@ -4960,12 +4918,12 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=" + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { "version": "2.0.0", @@ -4987,13 +4945,13 @@ "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "integrity": "sha512-qZ181q3ICkag/+lv1X6frDUF84pqCm30qild3LGbD84n0AC75CYwnWsQRDlpz7zDkU5NVcmhHh4LjXK0goLYZA==", "dev": true }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "picomatch": { "version": "2.2.2", @@ -5689,7 +5647,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" }, "psl": { "version": "1.7.0", @@ -5754,7 +5712,7 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" }, "qs": { "version": "6.7.0", @@ -5781,7 +5739,7 @@ "raven": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", - "integrity": "sha1-QnPBrm005CMPUbLAEEGjK5Iygio=", + "integrity": "sha512-RYov4wAaflZasWiCrZuizd3jNXxCOkW1WrXgWsGVb8kRpdHNZ+vPY27R6RhVtqzWp+DG9a5l6iP0QUPK4EgzaQ==", "requires": { "cookie": "0.3.1", "json-stringify-safe": "5.0.1", @@ -5793,12 +5751,12 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" }, "uuid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", - "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" + "integrity": "sha512-rqE1LoOVLv3QrZMjb4NkF5UWlkurCfPyItVnFPNKDDGkHw4dQUdE4zMcLqx28+0Kcf3+bnUk4PisaiRJT4aiaQ==" } } }, @@ -5843,7 +5801,7 @@ "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -5857,12 +5815,12 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { "safe-buffer": "~5.1.0" } @@ -5903,7 +5861,7 @@ "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", "requires": { "es6-error": "^4.0.1" } @@ -5985,7 +5943,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "dev": true }, "require-main-filename": { @@ -6011,7 +5969,7 @@ "resolve": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha1-QBSHC6KWF2uGND1Qtg87UGCc4jI=", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", "requires": { "path-parse": "^1.0.6" } @@ -6019,7 +5977,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" }, "restore-cursor": { "version": "3.1.0", @@ -6063,7 +6021,7 @@ "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", "optional": true, "requires": { "glob": "^6.0.1" @@ -6090,7 +6048,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "safe-json-stringify": { "version": "1.2.0", @@ -6101,12 +6059,12 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sandboxed-module": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-2.0.3.tgz", - "integrity": "sha1-x+VFkzm7y6KMUwPusz9ug4e/upY=", + "integrity": "sha512-wXiA6ULoGjCDwjn6evQF/Qi+oe77P+aCxizUktLBBKdqNbTxwec4GySJcS+O7iZFhme2ex04m+14KgknKKqFsw==", "dev": true, "requires": { "require-like": "0.1.2", @@ -6125,7 +6083,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=" + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" }, "send": { "version": "0.17.1", @@ -6183,7 +6141,7 @@ "settings-sharelatex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", - "integrity": "sha1-Tv4vUpPbjxwVlnEEx5BfqHD/mS0=", + "integrity": "sha512-f7D+0lnlohoteSn6IKTH72NE+JnAdMWTKwQglAuimZWTID2FRRItZSGeYMTRpvEnaQApkoVwRp//WRMsiddnqw==", "requires": { "coffee-script": "1.6.0" }, @@ -6191,7 +6149,7 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" } } }, @@ -6304,7 +6262,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6414,24 +6372,24 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=" + "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==" }, "statsd-parser": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", - "integrity": "sha1-y9JDlTzELv/VSLXSI4jtaJ7GOb0=" + "integrity": "sha512-7XO+ur89EalMXXFQaydsczB8sclr5nDsNIoUu0IzJx1pIbHUhO3LtpSzBwetIuU9DyTLMiVaJBMtWS/Nb2KR4g==" }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==" }, "stream-events": { "version": "1.0.5", @@ -6546,7 +6504,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" }, "supports-color": { "version": "6.0.0", @@ -6615,7 +6573,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", + "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", "requires": { "bintrees": "1.0.1" } @@ -6674,7 +6632,7 @@ "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -6702,7 +6660,7 @@ "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -6719,12 +6677,12 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -6751,7 +6709,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "through2": { "version": "3.0.1", @@ -6778,17 +6736,17 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" }, "to-mongodb-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + "integrity": "sha512-vfXXcGYFP8+0L5IPOtUzzVIvPE/G3GN0TKa/PRBlzPqYyhm+UxhPmvv634EQgO4Ot8dHbBFihOslMJQclY8Z9A==" }, "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" }, "to-regex-range": { "version": "5.0.1", @@ -6802,7 +6760,7 @@ "to-snake-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", + "integrity": "sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==", "requires": { "to-space-case": "^1.0.0" } @@ -6810,7 +6768,7 @@ "to-space-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", "requires": { "to-no-case": "^1.0.0" } @@ -6847,7 +6805,7 @@ "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "dev": true, "requires": { "safe-buffer": "^5.0.1" @@ -6856,7 +6814,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "type-check": { "version": "0.3.2", @@ -6902,12 +6860,12 @@ "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "requires": { "punycode": "^2.1.0" }, @@ -6915,19 +6873,19 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" } } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { "version": "3.4.0", @@ -6952,12 +6910,12 @@ "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -6967,7 +6925,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -7075,13 +7033,13 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "string-width": { @@ -7097,7 +7055,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -7146,7 +7104,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write": { "version": "1.0.3", diff --git a/services/docstore/package.json b/services/docstore/package.json index a06b33ee93..733c98d7a7 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -23,7 +23,7 @@ "body-parser": "^1.19.0", "express": "^4.17.1", "logger-sharelatex": "^1.9.0", - "metrics-sharelatex": "^2.6.1", + "metrics-sharelatex": "^2.6.2", "mongojs": "3.1.0", "settings-sharelatex": "^1.1.0", "underscore": "~1.9.2" From 80095785b8a7d77f35bce2153dad0d8a1c47a775 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <das7pad@outlook.com> Date: Sun, 19 Apr 2020 21:24:59 +0200 Subject: [PATCH 244/349] [misc] test/unit: fix process usage for node v12 Signed-off-by: Jakob Ackermann <das7pad@outlook.com> --- services/docstore/test/unit/js/HttpControllerTests.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index e282c247ff..46bd5088b1 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -32,7 +32,8 @@ describe('HttpController', function() { error: sinon.stub() }), './HealthChecker': {} - } + }, + globals: { process } }) this.res = { send: sinon.stub(), From 9712f518bd6c3cfee9634cc5ac36656516f4c0ef Mon Sep 17 00:00:00 2001 From: Tim Alby <timothee.alby@gmail.com> Date: Thu, 28 May 2020 15:19:48 +0200 Subject: [PATCH 245/349] update build scripts to 2.2.0 --- services/docstore/.eslintrc | 1 - services/docstore/.prettierrc | 1 - services/docstore/Dockerfile | 3 +- services/docstore/Makefile | 43 +++++++++++++++++++------ services/docstore/buildscript.txt | 12 +++---- services/docstore/docker-compose.ci.yml | 1 - services/docstore/docker-compose.yml | 1 - services/docstore/package.json | 8 ++--- 8 files changed, 45 insertions(+), 25 deletions(-) diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc index 42a4b5cace..2e945d6ffb 100644 --- a/services/docstore/.eslintrc +++ b/services/docstore/.eslintrc @@ -1,7 +1,6 @@ // this file was auto-generated, do not edit it directly. // instead run bin/update_build_scripts from // https://github.com/sharelatex/sharelatex-dev-environment -// Version: 1.3.5 { "extends": [ "standard", diff --git a/services/docstore/.prettierrc b/services/docstore/.prettierrc index 5845b82113..24f9ec526f 100644 --- a/services/docstore/.prettierrc +++ b/services/docstore/.prettierrc @@ -1,7 +1,6 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.3.5 { "semi": false, "singleQuote": true diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 2d8b097e26..4242e7d3be 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -1,7 +1,6 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.3.5 FROM node:10.19.0 as base @@ -12,7 +11,7 @@ FROM base as app #wildcard as some files may not be in all repos COPY package*.json npm-shrink*.json /app/ -RUN npm install --quiet +RUN npm ci --quiet COPY . /app diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 1314c0d76d..f4eab58929 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -1,11 +1,12 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.3.5 BUILD_NUMBER ?= local BRANCH_NAME ?= $(shell git rev-parse --abbrev-ref HEAD) PROJECT_NAME = docstore +BUILD_DIR_NAME = $(shell pwd | xargs basename | tr -cd '[a-zA-Z0-9_.\-]') + DOCKER_COMPOSE_FLAGS ?= -f docker-compose.yml DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ BRANCH_NAME=$(BRANCH_NAME) \ @@ -16,6 +17,12 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ docker-compose ${DOCKER_COMPOSE_FLAGS} +DOCKER_COMPOSE_TEST_ACCEPTANCE = \ + COMPOSE_PROJECT_NAME=test_acceptance_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) + +DOCKER_COMPOSE_TEST_UNIT = \ + COMPOSE_PROJECT_NAME=test_unit_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) + clean: docker rmi ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) docker rmi gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) @@ -32,23 +39,41 @@ lint: test: format lint test_unit test_acceptance test_unit: - @[ ! -d test/unit ] && echo "docstore has no unit tests" || $(DOCKER_COMPOSE) run --rm test_unit +ifneq (,$(wildcard test/unit)) + $(DOCKER_COMPOSE_TEST_UNIT) run --rm test_unit + $(MAKE) test_unit_clean +endif -test_acceptance: test_clean test_acceptance_pre_run test_acceptance_run +test_clean: test_unit_clean +test_unit_clean: +ifneq (,$(wildcard test/unit)) + $(DOCKER_COMPOSE_TEST_UNIT) down -v -t 0 +endif -test_acceptance_debug: test_clean test_acceptance_pre_run test_acceptance_run_debug +test_acceptance: test_acceptance_clean test_acceptance_pre_run test_acceptance_run + $(MAKE) test_acceptance_clean + +test_acceptance_debug: test_acceptance_clean test_acceptance_pre_run test_acceptance_run_debug + $(MAKE) test_acceptance_clean test_acceptance_run: - @[ ! -d test/acceptance ] && echo "docstore has no acceptance tests" || $(DOCKER_COMPOSE) run --rm test_acceptance +ifneq (,$(wildcard test/acceptance)) + $(DOCKER_COMPOSE_TEST_ACCEPTANCE) run --rm test_acceptance +endif test_acceptance_run_debug: - @[ ! -d test/acceptance ] && echo "docstore has no acceptance tests" || $(DOCKER_COMPOSE) run -p 127.0.0.9:19999:19999 --rm test_acceptance npm run test:acceptance -- --inspect=0.0.0.0:19999 --inspect-brk +ifneq (,$(wildcard test/acceptance)) + $(DOCKER_COMPOSE_TEST_ACCEPTANCE) run -p 127.0.0.9:19999:19999 --rm test_acceptance npm run test:acceptance -- --inspect=0.0.0.0:19999 --inspect-brk +endif -test_clean: - $(DOCKER_COMPOSE) down -v -t 0 +test_clean: test_acceptance_clean +test_acceptance_clean: + $(DOCKER_COMPOSE_TEST_ACCEPTANCE) down -v -t 0 test_acceptance_pre_run: - @[ ! -f test/acceptance/js/scripts/pre-run ] && echo "docstore has no pre acceptance tests task" || $(DOCKER_COMPOSE) run --rm test_acceptance test/acceptance/js/scripts/pre-run +ifneq (,$(wildcard test/acceptance/js/scripts/pre-run)) + $(DOCKER_COMPOSE_TEST_ACCEPTANCE) run --rm test_acceptance test/acceptance/js/scripts/pre-run +endif build: docker build --pull --tag ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) \ diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 77a5b00f8c..f57a243595 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,10 +1,10 @@ docstore ---node-version=10.19.0 ---script-version=1.3.5 ---dependencies=mongo ---language=es ---docker-repos=gcr.io/overleaf-ops --acceptance-creds=aws ---env-pass-through= +--dependencies=mongo +--docker-repos=gcr.io/overleaf-ops --env-add= +--env-pass-through= +--language=es +--node-version=10.19.0 --public-repo=True +--script-version=2.2.0 diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index f3d86bb0f9..bc11cc116a 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -1,7 +1,6 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.3.5 version: "2.3" diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 10805fd581..a1dc328bd3 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -1,7 +1,6 @@ # This file was auto-generated, do not edit it directly. # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -# Version: 1.3.5 version: "2.3" diff --git a/services/docstore/package.json b/services/docstore/package.json index 733c98d7a7..21da419b3c 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -15,8 +15,8 @@ "test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP", "nodemon": "nodemon --config nodemon.json", "lint": "node_modules/.bin/eslint .", - "format": "node_modules/.bin/prettier-eslint '**/*.js' --list-different", - "format:fix": "node_modules/.bin/prettier-eslint '**/*.js' --write" + "format": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --list-different", + "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write" }, "dependencies": { "async": "^2.6.3", @@ -33,8 +33,8 @@ "bunyan": "~1.8.12", "chai": "~4.2.0", "eslint": "^6.8.0", - "eslint-config-prettier": "^6.10.1", - "eslint-config-standard": "^14.1.1", + "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", From c854f1f570a48df01ef82f8b39f60f312faeebd0 Mon Sep 17 00:00:00 2001 From: Tim Alby <timothee.alby@gmail.com> Date: Thu, 28 May 2020 15:20:54 +0200 Subject: [PATCH 246/349] prettier auto-format --- services/docstore/app.js | 8 +- services/docstore/app/js/DocArchiveManager.js | 47 ++-- services/docstore/app/js/DocManager.js | 45 ++-- services/docstore/app/js/Errors.js | 2 +- services/docstore/app/js/HealthChecker.js | 10 +- services/docstore/app/js/HttpController.js | 38 ++-- services/docstore/app/js/MongoManager.js | 16 +- services/docstore/app/js/RangeManager.js | 2 +- .../test/acceptance/js/ArchiveDocsTests.js | 146 ++++++------ .../test/acceptance/js/DeletingDocsTests.js | 42 ++-- .../test/acceptance/js/GettingAllDocsTests.js | 20 +- .../test/acceptance/js/GettingDocsTests.js | 24 +- .../test/acceptance/js/UpdatingDocsTests.js | 110 ++++----- .../test/acceptance/js/helpers/DocstoreApp.js | 30 +-- .../acceptance/js/helpers/DocstoreClient.js | 18 +- .../test/unit/js/DocArchiveManagerTests.js | 127 +++++------ .../docstore/test/unit/js/DocManagerTests.js | 212 +++++++++--------- .../test/unit/js/HttpControllerTests.js | 136 +++++------ .../test/unit/js/MongoManagerTests.js | 88 ++++---- .../test/unit/js/RangeManagerTests.js | 44 ++-- 20 files changed, 586 insertions(+), 579 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index ebf7209b42..468dc77983 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -24,7 +24,7 @@ app.use(Metrics.http.monitor(logger)) Metrics.injectMetricsRoute(app) -app.param('project_id', function(req, res, next, projectId) { +app.param('project_id', function (req, res, next, projectId) { if (projectId != null ? projectId.match(/^[0-9a-f]{24}$/) : undefined) { return next() } else { @@ -32,7 +32,7 @@ app.param('project_id', function(req, res, next, projectId) { } }) -app.param('doc_id', function(req, res, next, docId) { +app.param('doc_id', function (req, res, next, docId) { if (docId != null ? docId.match(/^[0-9a-f]{24}$/) : undefined) { return next() } else { @@ -62,7 +62,7 @@ app.get('/health_check', HttpController.healthCheck) app.get('/status', (req, res) => res.send('docstore is alive')) -app.use(function(error, req, res, next) { +app.use(function (error, req, res, next) { logger.error({ err: error, req }, 'request errored') if (error instanceof Errors.NotFoundError) { return res.send(404) @@ -76,7 +76,7 @@ const { host } = Settings.internal.docstore if (!module.parent) { // Called directly - app.listen(port, host, function(error) { + app.listen(port, host, function (error) { if (error != null) { throw error } diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index af1af21957..f763d081ee 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -26,13 +26,13 @@ const thirtySeconds = 30 * 1000 module.exports = DocArchive = { archiveAllDocs(project_id, callback) { if (callback == null) { - callback = function(err, docs) {} + callback = function (err, docs) {} } return MongoManager.getProjectsDocs( project_id, { include_deleted: true }, { lines: true, ranges: true, rev: true, inS3: true }, - function(err, docs) { + function (err, docs) { if (err != null) { return callback(err) } else if (docs == null) { @@ -40,8 +40,8 @@ module.exports = DocArchive = { new Errors.NotFoundError(`No docs for project ${project_id}`) ) } - docs = _.filter(docs, doc => doc.inS3 !== true) - const jobs = _.map(docs, doc => cb => + docs = _.filter(docs, (doc) => doc.inS3 !== true) + const jobs = _.map(docs, (doc) => (cb) => DocArchive.archiveDoc(project_id, doc, cb) ) return async.parallelLimit(jobs, 5, callback) @@ -57,13 +57,13 @@ module.exports = DocArchive = { } catch (e) { return callback(e) } - return DocArchive._mongoDocToS3Doc(doc, function(error, json_doc) { + return DocArchive._mongoDocToS3Doc(doc, function (error, json_doc) { if (error != null) { return callback(error) } options.body = json_doc options.headers = { 'Content-Type': 'application/json' } - return request.put(options, function(err, res) { + return request.put(options, function (err, res) { if (err != null || res.statusCode !== 200) { logger.err( { @@ -94,7 +94,7 @@ module.exports = DocArchive = { ) return callback(new Error('Error in S3 md5 response')) } - return MongoManager.markDocAsArchived(doc._id, doc.rev, function(err) { + return MongoManager.markDocAsArchived(doc._id, doc.rev, function (err) { if (err != null) { return callback(err) } @@ -106,9 +106,12 @@ module.exports = DocArchive = { unArchiveAllDocs(project_id, callback) { if (callback == null) { - callback = function(err) {} + callback = function (err) {} } - return MongoManager.getArchivedProjectDocs(project_id, function(err, docs) { + return MongoManager.getArchivedProjectDocs(project_id, function ( + err, + docs + ) { if (err != null) { logger.err({ err, project_id }, 'error unarchiving all docs') return callback(err) @@ -119,8 +122,8 @@ module.exports = DocArchive = { } const jobs = _.map( docs, - doc => - function(cb) { + (doc) => + function (cb) { if (doc.inS3 == null) { return cb() } else { @@ -141,7 +144,7 @@ module.exports = DocArchive = { return callback(e) } options.json = true - return request.get(options, function(err, res, doc) { + return request.get(options, function (err, res, doc) { if (err != null || res.statusCode !== 200) { logger.err( { err, res, project_id, doc_id }, @@ -149,7 +152,7 @@ module.exports = DocArchive = { ) return callback(new Errors.NotFoundError('Error in S3 request')) } - return DocArchive._s3DocToMongoDoc(doc, function(error, mongo_doc) { + return DocArchive._s3DocToMongoDoc(doc, function (error, mongo_doc) { if (error != null) { return callback(error) } @@ -157,7 +160,7 @@ module.exports = DocArchive = { project_id, doc_id.toString(), mongo_doc, - function(err) { + function (err) { if (err != null) { return callback(err) } @@ -171,20 +174,20 @@ module.exports = DocArchive = { destroyAllDocs(project_id, callback) { if (callback == null) { - callback = function(err) {} + callback = function (err) {} } return MongoManager.getProjectsDocs( project_id, { include_deleted: true }, { _id: 1 }, - function(err, docs) { + function (err, docs) { if (err != null) { logger.err({ err, project_id }, "error getting project's docs") return callback(err) } else if (docs == null) { return callback() } - const jobs = _.map(docs, doc => cb => + const jobs = _.map(docs, (doc) => (cb) => DocArchive.destroyDoc(project_id, doc._id, cb) ) return async.parallelLimit(jobs, 5, callback) @@ -194,7 +197,7 @@ module.exports = DocArchive = { destroyDoc(project_id, doc_id, callback) { logger.log({ project_id, doc_id }, 'removing doc from mongo and s3') - return MongoManager.findDoc(project_id, doc_id, { inS3: 1 }, function( + return MongoManager.findDoc(project_id, doc_id, { inS3: 1 }, function ( error, doc ) { @@ -205,7 +208,7 @@ module.exports = DocArchive = { return callback(new Errors.NotFoundError('Doc not found in Mongo')) } if (doc.inS3 === true) { - return DocArchive._deleteDocFromS3(project_id, doc_id, function(err) { + return DocArchive._deleteDocFromS3(project_id, doc_id, function (err) { if (err != null) { return err } @@ -225,7 +228,7 @@ module.exports = DocArchive = { return callback(e) } options.json = true - return request.del(options, function(err, res, body) { + return request.del(options, function (err, res, body) { if (err != null || res.statusCode !== 204) { logger.err( { err, res, project_id, doc_id }, @@ -239,7 +242,7 @@ module.exports = DocArchive = { _s3DocToMongoDoc(doc, callback) { if (callback == null) { - callback = function(error, mongo_doc) {} + callback = function (error, mongo_doc) {} } const mongo_doc = {} if (doc.schema_v === 1 && doc.lines != null) { @@ -257,7 +260,7 @@ module.exports = DocArchive = { _mongoDocToS3Doc(doc, callback) { if (callback == null) { - callback = function(error, s3_doc) {} + callback = function (error, s3_doc) {} } if (doc.lines == null) { return callback(new Error('doc has no lines')) diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 15a782861b..edd9c0f1cd 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -31,13 +31,16 @@ module.exports = DocManager = { filter = {} } if (callback == null) { - callback = function(error, doc) {} + callback = function (error, doc) {} } if (filter.inS3 !== true) { return callback('must include inS3 when getting doc') } - return MongoManager.findDoc(project_id, doc_id, filter, function(err, doc) { + return MongoManager.findDoc(project_id, doc_id, filter, function ( + err, + doc + ) { if (err != null) { return callback(err) } else if (doc == null) { @@ -47,7 +50,7 @@ module.exports = DocManager = { ) ) } else if (doc != null ? doc.inS3 : undefined) { - return DocArchive.unarchiveDoc(project_id, doc_id, function(err) { + return DocArchive.unarchiveDoc(project_id, doc_id, function (err) { if (err != null) { logger.err({ err, project_id, doc_id }, 'error unarchiving doc') return callback(err) @@ -56,7 +59,7 @@ module.exports = DocManager = { }) } else { if (filter.version) { - return MongoManager.getDocVersion(doc_id, function(error, version) { + return MongoManager.getDocVersion(doc_id, function (error, version) { if (error != null) { return callback(error) } @@ -72,13 +75,13 @@ module.exports = DocManager = { checkDocExists(project_id, doc_id, callback) { if (callback == null) { - callback = function(err, exists) {} + callback = function (err, exists) {} } return DocManager._getDoc( project_id, doc_id, { _id: 1, inS3: true }, - function(err, doc) { + function (err, doc) { if (err != null) { return callback(err) } @@ -89,7 +92,7 @@ module.exports = DocManager = { getFullDoc(project_id, doc_id, callback) { if (callback == null) { - callback = function(err, doc) {} + callback = function (err, doc) {} } return DocManager._getDoc( project_id, @@ -102,7 +105,7 @@ module.exports = DocManager = { ranges: true, inS3: true }, - function(err, doc) { + function (err, doc) { if (err != null) { return callback(err) } @@ -113,13 +116,13 @@ module.exports = DocManager = { getDocLines(project_id, doc_id, callback) { if (callback == null) { - callback = function(err, doc) {} + callback = function (err, doc) {} } return DocManager._getDoc( project_id, doc_id, { lines: true, inS3: true }, - function(err, doc) { + function (err, doc) { if (err != null) { return callback(err) } @@ -130,9 +133,9 @@ module.exports = DocManager = { getAllNonDeletedDocs(project_id, filter, callback) { if (callback == null) { - callback = function(error, docs) {} + callback = function (error, docs) {} } - return DocArchive.unArchiveAllDocs(project_id, function(error) { + return DocArchive.unArchiveAllDocs(project_id, function (error) { if (error != null) { return callback(error) } @@ -140,7 +143,7 @@ module.exports = DocManager = { project_id, { include_deleted: false }, filter, - function(error, docs) { + function (error, docs) { if (typeof err !== 'undefined' && err !== null) { return callback(error) } else if (docs == null) { @@ -157,7 +160,7 @@ module.exports = DocManager = { updateDoc(project_id, doc_id, lines, version, ranges, callback) { if (callback == null) { - callback = function(error, modified, rev) {} + callback = function (error, modified, rev) {} } if (lines == null || version == null || ranges == null) { return callback(new Error('no lines, version or ranges provided')) @@ -174,7 +177,7 @@ module.exports = DocManager = { ranges: true, inS3: true }, - function(err, doc) { + function (err, doc) { let updateLines, updateRanges, updateVersion if (err != null && !(err instanceof Errors.NotFoundError)) { logger.err( @@ -200,7 +203,7 @@ module.exports = DocManager = { let modified = false let rev = (doc != null ? doc.rev : undefined) || 0 - const updateLinesAndRangesIfNeeded = function(cb) { + const updateLinesAndRangesIfNeeded = function (cb) { if (updateLines || updateRanges) { const update = {} if (updateLines) { @@ -228,7 +231,7 @@ module.exports = DocManager = { } } - const updateVersionIfNeeded = function(cb) { + const updateVersionIfNeeded = function (cb) { if (updateVersion) { logger.log( { @@ -250,11 +253,11 @@ module.exports = DocManager = { } } - return updateLinesAndRangesIfNeeded(function(error) { + return updateLinesAndRangesIfNeeded(function (error) { if (error != null) { return callback(error) } - return updateVersionIfNeeded(function(error) { + return updateVersionIfNeeded(function (error) { if (error != null) { return callback(error) } @@ -267,9 +270,9 @@ module.exports = DocManager = { deleteDoc(project_id, doc_id, callback) { if (callback == null) { - callback = function(error) {} + callback = function (error) {} } - return DocManager.checkDocExists(project_id, doc_id, function( + return DocManager.checkDocExists(project_id, doc_id, function ( error, exists ) { diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index f3bc8e37eb..a950b6de20 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -5,7 +5,7 @@ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. let Errors -var NotFoundError = function(message) { +var NotFoundError = function (message) { const error = new Error(message) error.name = 'NotFoundError' error.__proto__ = NotFoundError.prototype diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 87b16a9951..70ebc85ad9 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -34,15 +34,15 @@ module.exports = { }) logger.log({ lines, url, doc_id, project_id }, 'running health check') const jobs = [ - function(cb) { + function (cb) { const opts = getOpts() opts.json = { lines, version: 42, ranges: {} } return request.post(opts, cb) }, - function(cb) { + function (cb) { const opts = getOpts() opts.json = true - return request.get(opts, function(err, res, body) { + return request.get(opts, function (err, res, body) { if (err != null) { logger.err({ err }, 'docstore returned a error in health check get') return cb(err) @@ -60,8 +60,8 @@ module.exports = { } }) }, - cb => db.docs.remove({ _id: doc_id, project_id }, cb), - cb => db.docOps.remove({ doc_id }, cb) + (cb) => db.docs.remove({ _id: doc_id, project_id }, cb), + (cb) => db.docOps.remove({ doc_id }, cb) ] return async.series(jobs, callback) } diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 7e17c15b65..86139e6f45 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -22,14 +22,14 @@ const Settings = require('settings-sharelatex') module.exports = HttpController = { getDoc(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params const { doc_id } = req.params const include_deleted = (req.query != null ? req.query.include_deleted : undefined) === 'true' logger.log({ project_id, doc_id }, 'getting doc') - return DocManager.getFullDoc(project_id, doc_id, function(error, doc) { + return DocManager.getFullDoc(project_id, doc_id, function (error, doc) { if (error != null) { return next(error) } @@ -46,12 +46,12 @@ module.exports = HttpController = { getRawDoc(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params const { doc_id } = req.params logger.log({ project_id, doc_id }, 'getting raw doc') - return DocManager.getDocLines(project_id, doc_id, function(error, doc) { + return DocManager.getDocLines(project_id, doc_id, function (error, doc) { if (error != null) { return next(error) } @@ -66,14 +66,14 @@ module.exports = HttpController = { getAllDocs(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params logger.log({ project_id }, 'getting all docs') return DocManager.getAllNonDeletedDocs( project_id, { lines: true, rev: true }, - function(error, docs) { + function (error, docs) { if (docs == null) { docs = [] } @@ -87,14 +87,14 @@ module.exports = HttpController = { getAllRanges(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params logger.log({ project_id }, 'getting all ranges') return DocManager.getAllNonDeletedDocs( project_id, { ranges: true }, - function(error, docs) { + function (error, docs) { if (docs == null) { docs = [] } @@ -108,7 +108,7 @@ module.exports = HttpController = { updateDoc(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params const { doc_id } = req.params @@ -151,7 +151,7 @@ module.exports = HttpController = { lines, version, ranges, - function(error, modified, rev) { + function (error, modified, rev) { if (error != null) { return next(error) } @@ -165,12 +165,12 @@ module.exports = HttpController = { deleteDoc(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params const { doc_id } = req.params logger.log({ project_id, doc_id }, 'deleting doc') - return DocManager.deleteDoc(project_id, doc_id, function(error) { + return DocManager.deleteDoc(project_id, doc_id, function (error) { if (error != null) { return next(error) } @@ -210,11 +210,11 @@ module.exports = HttpController = { archiveAllDocs(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params logger.log({ project_id }, 'archiving all docs') - return DocArchive.archiveAllDocs(project_id, function(error) { + return DocArchive.archiveAllDocs(project_id, function (error) { if (error != null) { return next(error) } @@ -224,11 +224,11 @@ module.exports = HttpController = { unArchiveAllDocs(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params logger.log({ project_id }, 'unarchiving all docs') - return DocArchive.unArchiveAllDocs(project_id, function(error) { + return DocArchive.unArchiveAllDocs(project_id, function (error) { if (error != null) { return next(error) } @@ -238,11 +238,11 @@ module.exports = HttpController = { destroyAllDocs(req, res, next) { if (next == null) { - next = function(error) {} + next = function (error) {} } const { project_id } = req.params logger.log({ project_id }, 'destroying all docs') - return DocArchive.destroyAllDocs(project_id, function(error) { + return DocArchive.destroyAllDocs(project_id, function (error) { if (error != null) { return next(error) } @@ -251,7 +251,7 @@ module.exports = HttpController = { }, healthCheck(req, res) { - return HealthChecker.check(function(err) { + return HealthChecker.check(function (err) { if (err != null) { logger.err({ err }, 'error performing health check') return res.send(500) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 66699c9ba3..b3e90c63c9 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -18,7 +18,7 @@ const metrics = require('metrics-sharelatex') module.exports = MongoManager = { findDoc(project_id, doc_id, filter, callback) { if (callback == null) { - callback = function(error, doc) {} + callback = function (error, doc) {} } return db.docs.find( { @@ -26,7 +26,7 @@ module.exports = MongoManager = { project_id: ObjectId(project_id.toString()) }, filter, - function(error, docs) { + function (error, docs) { if (docs == null) { docs = [] } @@ -98,12 +98,12 @@ module.exports = MongoManager = { _id: doc_id, rev } - return db.docs.update(query, update, err => callback(err)) + return db.docs.update(query, update, (err) => callback(err)) }, getDocVersion(doc_id, callback) { if (callback == null) { - callback = function(error, version) {} + callback = function (error, version) {} } return db.docOps.find( { @@ -112,7 +112,7 @@ module.exports = MongoManager = { { version: 1 }, - function(error, docs) { + function (error, docs) { if (error != null) { return callback(error) } @@ -127,7 +127,7 @@ module.exports = MongoManager = { setDocVersion(doc_id, version, callback) { if (callback == null) { - callback = function(error) {} + callback = function (error) {} } return db.docOps.update( { @@ -148,7 +148,7 @@ module.exports = MongoManager = { { _id: ObjectId(doc_id) }, - function(err) { + function (err) { if (err != null) { return callback(err) } @@ -170,6 +170,6 @@ module.exports = MongoManager = { 'markDocAsArchived', 'getDocVersion', 'setDocVersion' -].map(method => +].map((method) => metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger) ) diff --git a/services/docstore/app/js/RangeManager.js b/services/docstore/app/js/RangeManager.js index 5a0061a9de..b11019657f 100644 --- a/services/docstore/app/js/RangeManager.js +++ b/services/docstore/app/js/RangeManager.js @@ -36,7 +36,7 @@ module.exports = RangeManager = { return null } - const updateMetadata = function(metadata) { + const updateMetadata = function (metadata) { if ((metadata != null ? metadata.ts : undefined) != null) { metadata.ts = new Date(metadata.ts) } diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 67d5d0e828..3f559f566e 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -23,13 +23,13 @@ const request = require('request') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') -describe('Archiving', function() { - before(function(done) { +describe('Archiving', function () { + before(function (done) { return DocstoreApp.ensureRunning(done) }) - describe('multiple docs in a project', function() { - before(function(done) { + describe('multiple docs in a project', function () { + before(function (done) { this.project_id = ObjectId() this.docs = [ { @@ -45,9 +45,9 @@ describe('Archiving', function() { version: 4 } ] - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { + const jobs = Array.from(this.docs).map((doc) => + ((doc) => { + return (callback) => { return DocstoreClient.createDoc( this.project_id, doc._id, @@ -60,7 +60,7 @@ describe('Archiving', function() { })(doc) ) - return async.series(jobs, error => { + return async.series(jobs, (error) => { if (error != null) { throw error } @@ -71,15 +71,15 @@ describe('Archiving', function() { }) }) - it('should archive all the docs', function(done) { + it('should archive all the docs', function (done) { this.res.statusCode.should.equal(204) return done() }) - it('should set inS3 and unset lines and ranges in each doc', function(done) { - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { + it('should set inS3 and unset lines and ranges in each doc', function (done) { + const jobs = Array.from(this.docs).map((doc) => + ((doc) => { + return (callback) => { return db.docs.findOne({ _id: doc._id }, (error, doc) => { should.not.exist(doc.lines) should.not.exist(doc.ranges) @@ -92,10 +92,10 @@ describe('Archiving', function() { return async.series(jobs, done) }) - it('should set the docs in s3 correctly', function(done) { - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { + it('should set the docs in s3 correctly', function (done) { + const jobs = Array.from(this.docs).map((doc) => + ((doc) => { + return (callback) => { return DocstoreClient.getS3Doc( this.project_id, doc._id, @@ -111,8 +111,8 @@ describe('Archiving', function() { return async.series(jobs, done) }) - return describe('after unarchiving from a request for the project', function() { - before(function(done) { + return describe('after unarchiving from a request for the project', function () { + before(function (done) { return DocstoreClient.getAllDocs( this.project_id, (error, res, fetched_docs) => { @@ -125,7 +125,7 @@ describe('Archiving', function() { ) }) - it('should return the docs', function(done) { + it('should return the docs', function (done) { for (let i = 0; i < this.fetched_docs.length; i++) { const doc = this.fetched_docs[i] doc.lines.should.deep.equal(this.docs[i].lines) @@ -133,10 +133,10 @@ describe('Archiving', function() { return done() }) - return it('should restore the docs to mongo', function(done) { + return it('should restore the docs to mongo', function (done) { const jobs = Array.from(this.docs).map((doc, i) => ((doc, i) => { - return callback => { + return (callback) => { return db.docs.findOne({ _id: doc._id }, (error, doc) => { doc.lines.should.deep.equal(this.docs[i].lines) doc.ranges.should.deep.equal(this.docs[i].ranges) @@ -151,8 +151,8 @@ describe('Archiving', function() { }) }) - describe('a deleted doc', function() { - before(function(done) { + describe('a deleted doc', function () { + before(function (done) { this.project_id = ObjectId() this.doc = { _id: ObjectId(), @@ -166,14 +166,14 @@ describe('Archiving', function() { this.doc.lines, this.doc.version, this.doc.ranges, - error => { + (error) => { if (error != null) { throw error } return DocstoreClient.deleteDoc( this.project_id, this.doc._id, - error => { + (error) => { if (error != null) { throw error } @@ -193,12 +193,12 @@ describe('Archiving', function() { ) }) - it('should successully archive the docs', function(done) { + it('should successully archive the docs', function (done) { this.res.statusCode.should.equal(204) return done() }) - it('should set inS3 and unset lines and ranges in each doc', function(done) { + it('should set inS3 and unset lines and ranges in each doc', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -211,7 +211,7 @@ describe('Archiving', function() { }) }) - it('should set the doc in s3 correctly', function(done) { + it('should set the doc in s3 correctly', function (done) { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, @@ -226,8 +226,8 @@ describe('Archiving', function() { ) }) - return describe('after unarchiving from a request for the project', function() { - before(function(done) { + return describe('after unarchiving from a request for the project', function () { + before(function (done) { return DocstoreClient.getAllDocs( this.project_id, (error, res, fetched_docs) => { @@ -240,12 +240,12 @@ describe('Archiving', function() { ) }) - it('should not included the deleted', function(done) { + it('should not included the deleted', function (done) { this.fetched_docs.length.should.equal(0) return done() }) - return it('should restore the doc to mongo', function(done) { + return it('should restore the doc to mongo', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -260,8 +260,8 @@ describe('Archiving', function() { }) }) - describe('a doc with large lines', function() { - before(function(done) { + describe('a doc with large lines', function () { + before(function (done) { this.project_id = ObjectId() this.timeout(1000 * 30) const quarterMegInBytes = 250000 @@ -280,7 +280,7 @@ describe('Archiving', function() { this.doc.lines, this.doc.version, this.doc.ranges, - error => { + (error) => { if (error != null) { throw error } @@ -295,12 +295,12 @@ describe('Archiving', function() { ) }) - it('should successully archive the docs', function(done) { + it('should successully archive the docs', function (done) { this.res.statusCode.should.equal(204) return done() }) - it('should set inS3 and unset lines and ranges in each doc', function(done) { + it('should set inS3 and unset lines and ranges in each doc', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -312,7 +312,7 @@ describe('Archiving', function() { }) }) - it('should set the doc in s3 correctly', function(done) { + it('should set the doc in s3 correctly', function (done) { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, @@ -327,8 +327,8 @@ describe('Archiving', function() { ) }) - return describe('after unarchiving from a request for the project', function() { - before(function(done) { + return describe('after unarchiving from a request for the project', function () { + before(function (done) { return DocstoreClient.getAllDocs( this.project_id, (error, res, fetched_docs) => { @@ -341,7 +341,7 @@ describe('Archiving', function() { ) }) - return it('should restore the doc to mongo', function(done) { + return it('should restore the doc to mongo', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -355,8 +355,8 @@ describe('Archiving', function() { }) }) - describe('a doc with naughty strings', function() { - before(function(done) { + describe('a doc with naughty strings', function () { + before(function (done) { this.project_id = ObjectId() this.doc = { _id: ObjectId(), @@ -754,7 +754,7 @@ describe('Archiving', function() { this.doc.lines, this.doc.version, this.doc.ranges, - error => { + (error) => { if (error != null) { throw error } @@ -769,12 +769,12 @@ describe('Archiving', function() { ) }) - it('should successully archive the docs', function(done) { + it('should successully archive the docs', function (done) { this.res.statusCode.should.equal(204) return done() }) - it('should set inS3 and unset lines and ranges in each doc', function(done) { + it('should set inS3 and unset lines and ranges in each doc', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -786,7 +786,7 @@ describe('Archiving', function() { }) }) - it('should set the doc in s3 correctly', function(done) { + it('should set the doc in s3 correctly', function (done) { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, @@ -801,8 +801,8 @@ describe('Archiving', function() { ) }) - return describe('after unarchiving from a request for the project', function() { - before(function(done) { + return describe('after unarchiving from a request for the project', function () { + before(function (done) { return DocstoreClient.getAllDocs( this.project_id, (error, res, fetched_docs) => { @@ -815,7 +815,7 @@ describe('Archiving', function() { ) }) - return it('should restore the doc to mongo', function(done) { + return it('should restore the doc to mongo', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -829,8 +829,8 @@ describe('Archiving', function() { }) }) - describe('a doc with ranges', function() { - before(function(done) { + describe('a doc with ranges', function () { + before(function (done) { this.project_id = ObjectId() this.doc = { _id: ObjectId(), @@ -873,7 +873,7 @@ describe('Archiving', function() { this.doc.lines, this.doc.version, this.doc.ranges, - error => { + (error) => { if (error != null) { throw error } @@ -888,12 +888,12 @@ describe('Archiving', function() { ) }) - it('should successully archive the docs', function(done) { + it('should successully archive the docs', function (done) { this.res.statusCode.should.equal(204) return done() }) - it('should set inS3 and unset lines and ranges in each doc', function(done) { + it('should set inS3 and unset lines and ranges in each doc', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -905,7 +905,7 @@ describe('Archiving', function() { }) }) - it('should set the doc in s3 correctly', function(done) { + it('should set the doc in s3 correctly', function (done) { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, @@ -921,8 +921,8 @@ describe('Archiving', function() { ) }) - return describe('after unarchiving from a request for the project', function() { - before(function(done) { + return describe('after unarchiving from a request for the project', function () { + before(function (done) { return DocstoreClient.getAllDocs( this.project_id, (error, res, fetched_docs) => { @@ -935,7 +935,7 @@ describe('Archiving', function() { ) }) - return it('should restore the doc to mongo', function(done) { + return it('should restore the doc to mongo', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -949,8 +949,8 @@ describe('Archiving', function() { }) }) - describe('a doc that is archived twice', function() { - before(function(done) { + describe('a doc that is archived twice', function () { + before(function (done) { this.project_id = ObjectId() this.doc = { _id: ObjectId(), @@ -964,7 +964,7 @@ describe('Archiving', function() { this.doc.lines, this.doc.version, this.doc.ranges, - error => { + (error) => { if (error != null) { throw error } @@ -990,7 +990,7 @@ describe('Archiving', function() { ) }) - it('should set inS3 and unset lines and ranges in each doc', function(done) { + it('should set inS3 and unset lines and ranges in each doc', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -1002,7 +1002,7 @@ describe('Archiving', function() { }) }) - it('should set the doc in s3 correctly', function(done) { + it('should set the doc in s3 correctly', function (done) { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, @@ -1017,8 +1017,8 @@ describe('Archiving', function() { ) }) - return describe('after unarchiving from a request for the project', function() { - before(function(done) { + return describe('after unarchiving from a request for the project', function () { + before(function (done) { return DocstoreClient.getAllDocs( this.project_id, (error, res, fetched_docs) => { @@ -1031,7 +1031,7 @@ describe('Archiving', function() { ) }) - return it('should restore the doc to mongo', function(done) { + return it('should restore the doc to mongo', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -1045,8 +1045,8 @@ describe('Archiving', function() { }) }) - return describe('a doc with the old schema (just an array of lines)', function() { - before(function(done) { + return describe('a doc with the old schema (just an array of lines)', function () { + before(function (done) { this.project_id = ObjectId() this.doc = { _id: ObjectId(), @@ -1070,7 +1070,7 @@ describe('Archiving', function() { rev: this.doc.version, inS3: true }, - error => { + (error) => { if (error != null) { throw error } @@ -1089,7 +1089,7 @@ describe('Archiving', function() { }) }) - it('should restore the doc to mongo', function(done) { + it('should restore the doc to mongo', function (done) { return db.docs.findOne({ _id: this.doc._id }, (error, doc) => { if (error != null) { throw error @@ -1100,7 +1100,7 @@ describe('Archiving', function() { }) }) - return it('should return the doc', function(done) { + return it('should return the doc', function (done) { this.fetched_docs[0].lines.should.deep.equal(this.doc.lines) return done() }) diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 8941567359..fd534da010 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -20,8 +20,8 @@ const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') -describe('Deleting a doc', function() { - beforeEach(function(done) { +describe('Deleting a doc', function () { + beforeEach(function (done) { this.project_id = ObjectId() this.doc_id = ObjectId() this.lines = ['original', 'lines'] @@ -34,7 +34,7 @@ describe('Deleting a doc', function() { this.lines, this.version, this.ranges, - error => { + (error) => { if (error != null) { throw error } @@ -44,8 +44,8 @@ describe('Deleting a doc', function() { }) }) - describe('when the doc exists', function() { - beforeEach(function(done) { + describe('when the doc exists', function () { + beforeEach(function (done) { return DocstoreClient.deleteDoc( this.project_id, this.doc_id, @@ -56,11 +56,11 @@ describe('Deleting a doc', function() { ) }) - afterEach(function(done) { + afterEach(function (done) { return db.docs.remove({ _id: this.doc_id }, done) }) - return it('should insert a deleted doc into the docs collection', function(done) { + return it('should insert a deleted doc into the docs collection', function (done) { return db.docs.find({ _id: this.doc_id }, (error, docs) => { docs[0]._id.should.deep.equal(this.doc_id) docs[0].lines.should.deep.equal(this.lines) @@ -70,8 +70,8 @@ describe('Deleting a doc', function() { }) }) - return describe('when the doc does not exist', function() { - return it('should return a 404', function(done) { + return describe('when the doc does not exist', function () { + return it('should return a 404', function (done) { const missing_doc_id = ObjectId() return DocstoreClient.deleteDoc( this.project_id, @@ -85,12 +85,12 @@ describe('Deleting a doc', function() { }) }) -describe("Destroying a project's documents", function() { - describe('when the doc exists', function() { - beforeEach(function(done) { +describe("Destroying a project's documents", function () { + describe('when the doc exists', function () { + beforeEach(function (done) { return db.docOps.insert( { doc_id: ObjectId(this.doc_id), version: 1 }, - function(err) { + function (err) { if (err != null) { return done(err) } @@ -99,7 +99,7 @@ describe("Destroying a project's documents", function() { ) }) - it('should remove the doc from the docs collection', function(done) { + it('should remove the doc from the docs collection', function (done) { return db.docs.find({ _id: this.doc_id }, (err, docs) => { expect(err).not.to.exist expect(docs).to.deep.equal([]) @@ -107,7 +107,7 @@ describe("Destroying a project's documents", function() { }) }) - return it('should remove the docOps from the docOps collection', function(done) { + return it('should remove the docOps from the docOps collection', function (done) { return db.docOps.find({ doc_id: this.doc_id }, (err, docOps) => { expect(err).not.to.exist expect(docOps).to.deep.equal([]) @@ -116,9 +116,9 @@ describe("Destroying a project's documents", function() { }) }) - return describe('when the doc is archived', function() { - beforeEach(function(done) { - return DocstoreClient.archiveAllDoc(this.project_id, function(err) { + return describe('when the doc is archived', function () { + beforeEach(function (done) { + return DocstoreClient.archiveAllDoc(this.project_id, function (err) { if (err != null) { return done(err) } @@ -126,7 +126,7 @@ describe("Destroying a project's documents", function() { }) }) - it('should remove the doc from the docs collection', function(done) { + it('should remove the doc from the docs collection', function (done) { return db.docs.find({ _id: this.doc_id }, (err, docs) => { expect(err).not.to.exist expect(docs).to.deep.equal([]) @@ -134,7 +134,7 @@ describe("Destroying a project's documents", function() { }) }) - it('should remove the docOps from the docOps collection', function(done) { + it('should remove the docOps from the docOps collection', function (done) { return db.docOps.find({ doc_id: this.doc_id }, (err, docOps) => { expect(err).not.to.exist expect(docOps).to.deep.equal([]) @@ -142,7 +142,7 @@ describe("Destroying a project's documents", function() { }) }) - return it('should remove the doc contents from s3', function(done) { + return it('should remove the doc contents from s3', function (done) { return DocstoreClient.getS3Doc( this.project_id, this.doc_id, diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 4fc7f811d8..01d6662424 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -20,8 +20,8 @@ const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') -describe('Getting all docs', function() { - beforeEach(function(done) { +describe('Getting all docs', function () { + beforeEach(function (done) { this.project_id = ObjectId() this.docs = [ { @@ -50,9 +50,9 @@ describe('Getting all docs', function() { rev: 8 } const version = 42 - const jobs = Array.from(this.docs).map(doc => - (doc => { - return callback => { + const jobs = Array.from(this.docs).map((doc) => + ((doc) => { + return (callback) => { return DocstoreClient.createDoc( this.project_id, doc._id, @@ -64,14 +64,14 @@ describe('Getting all docs', function() { } })(doc) ) - jobs.push(cb => { + jobs.push((cb) => { return DocstoreClient.createDoc( this.project_id, this.deleted_doc._id, this.deleted_doc.lines, version, this.deleted_doc.ranges, - err => { + (err) => { return DocstoreClient.deleteDoc( this.project_id, this.deleted_doc._id, @@ -80,11 +80,11 @@ describe('Getting all docs', function() { } ) }) - jobs.unshift(cb => DocstoreApp.ensureRunning(cb)) + jobs.unshift((cb) => DocstoreApp.ensureRunning(cb)) return async.series(jobs, done) }) - it('getAllDocs should return all the (non-deleted) docs', function(done) { + it('getAllDocs should return all the (non-deleted) docs', function (done) { return DocstoreClient.getAllDocs(this.project_id, (error, res, docs) => { if (error != null) { throw error @@ -98,7 +98,7 @@ describe('Getting all docs', function() { }) }) - return it('getAllRanges should return all the (non-deleted) doc ranges', function(done) { + return it('getAllRanges should return all the (non-deleted) doc ranges', function (done) { return DocstoreClient.getAllRanges(this.project_id, (error, res, docs) => { if (error != null) { throw error diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index fb3df8a657..b41af2827d 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -19,8 +19,8 @@ const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') -describe('Getting a doc', function() { - beforeEach(function(done) { +describe('Getting a doc', function () { + beforeEach(function (done) { this.project_id = ObjectId() this.doc_id = ObjectId() this.lines = ['original', 'lines'] @@ -44,7 +44,7 @@ describe('Getting a doc', function() { this.lines, this.version, this.ranges, - error => { + (error) => { if (error != null) { throw error } @@ -54,8 +54,8 @@ describe('Getting a doc', function() { }) }) - describe('when the doc exists', function() { - return it('should get the doc lines and version', function(done) { + describe('when the doc exists', function () { + return it('should get the doc lines and version', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -70,8 +70,8 @@ describe('Getting a doc', function() { }) }) - describe('when the doc does not exist', function() { - return it('should return a 404', function(done) { + describe('when the doc does not exist', function () { + return it('should return a 404', function (done) { const missing_doc_id = ObjectId() return DocstoreClient.getDoc( this.project_id, @@ -85,8 +85,8 @@ describe('Getting a doc', function() { }) }) - return describe('when the doc is a deleted doc', function() { - beforeEach(function(done) { + return describe('when the doc is a deleted doc', function () { + beforeEach(function (done) { this.deleted_doc_id = ObjectId() return DocstoreClient.createDoc( this.project_id, @@ -94,7 +94,7 @@ describe('Getting a doc', function() { this.lines, this.version, this.ranges, - error => { + (error) => { if (error != null) { throw error } @@ -107,7 +107,7 @@ describe('Getting a doc', function() { ) }) - it('should return the doc', function(done) { + it('should return the doc', function (done) { return DocstoreClient.getDoc( this.project_id, this.deleted_doc_id, @@ -122,7 +122,7 @@ describe('Getting a doc', function() { ) }) - return it('should return a 404 when the query string is not set', function(done) { + return it('should return a 404 when the query string is not set', function (done) { return DocstoreClient.getDoc( this.project_id, this.deleted_doc_id, diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index 96f5dfac47..251378a392 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -18,8 +18,8 @@ const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') -describe('Applying updates to a doc', function() { - beforeEach(function(done) { +describe('Applying updates to a doc', function () { + beforeEach(function (done) { this.project_id = ObjectId() this.doc_id = ObjectId() this.originalLines = ['original', 'lines'] @@ -56,7 +56,7 @@ describe('Applying updates to a doc', function() { this.originalLines, this.version, this.originalRanges, - error => { + (error) => { if (error != null) { throw error } @@ -66,8 +66,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when nothing has been updated', function() { - beforeEach(function(done) { + describe('when nothing has been updated', function () { + beforeEach(function (done) { return DocstoreClient.updateDoc( this.project_id, this.doc_id, @@ -81,11 +81,11 @@ describe('Applying updates to a doc', function() { ) }) - it('should return modified = false', function() { + it('should return modified = false', function () { return this.body.modified.should.equal(false) }) - return it('should not update the doc in the API', function(done) { + return it('should not update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -100,8 +100,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when the lines have changed', function() { - beforeEach(function(done) { + describe('when the lines have changed', function () { + beforeEach(function (done) { return DocstoreClient.updateDoc( this.project_id, this.doc_id, @@ -115,15 +115,15 @@ describe('Applying updates to a doc', function() { ) }) - it('should return modified = true', function() { + it('should return modified = true', function () { return this.body.modified.should.equal(true) }) - it('should return the rev', function() { + it('should return the rev', function () { return this.body.rev.should.equal(2) }) - return it('should update the doc in the API', function(done) { + return it('should update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -138,8 +138,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when the version has changed', function() { - beforeEach(function(done) { + describe('when the version has changed', function () { + beforeEach(function (done) { return DocstoreClient.updateDoc( this.project_id, this.doc_id, @@ -153,15 +153,15 @@ describe('Applying updates to a doc', function() { ) }) - it('should return modified = true', function() { + it('should return modified = true', function () { return this.body.modified.should.equal(true) }) - it('should return the rev', function() { + it('should return the rev', function () { return this.body.rev.should.equal(1) }) - return it('should update the doc in the API', function(done) { + return it('should update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -176,8 +176,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when the ranges have changed', function() { - beforeEach(function(done) { + describe('when the ranges have changed', function () { + beforeEach(function (done) { return DocstoreClient.updateDoc( this.project_id, this.doc_id, @@ -191,15 +191,15 @@ describe('Applying updates to a doc', function() { ) }) - it('should return modified = true', function() { + it('should return modified = true', function () { return this.body.modified.should.equal(true) }) - it('should return the rev', function() { + it('should return the rev', function () { return this.body.rev.should.equal(2) }) - return it('should update the doc in the API', function(done) { + return it('should update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -214,8 +214,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when the doc does not exist', function() { - beforeEach(function(done) { + describe('when the doc does not exist', function () { + beforeEach(function (done) { this.missing_doc_id = ObjectId() return DocstoreClient.updateDoc( this.project_id, @@ -231,11 +231,11 @@ describe('Applying updates to a doc', function() { ) }) - it('should create the doc', function() { + it('should create the doc', function () { return this.body.rev.should.equal(1) }) - return it('should be retreivable', function(done) { + return it('should be retreivable', function (done) { return DocstoreClient.getDoc( this.project_id, this.missing_doc_id, @@ -250,9 +250,9 @@ describe('Applying updates to a doc', function() { }) }) - describe('when malformed doc lines are provided', function() { - describe('when the lines are not an array', function() { - beforeEach(function(done) { + describe('when malformed doc lines are provided', function () { + describe('when the lines are not an array', function () { + beforeEach(function (done) { return DocstoreClient.updateDoc( this.project_id, this.doc_id, @@ -267,11 +267,11 @@ describe('Applying updates to a doc', function() { ) }) - it('should return 400', function() { + it('should return 400', function () { return this.res.statusCode.should.equal(400) }) - return it('should not update the doc in the API', function(done) { + return it('should not update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -284,8 +284,8 @@ describe('Applying updates to a doc', function() { }) }) - return describe('when the lines are not present', function() { - beforeEach(function(done) { + return describe('when the lines are not present', function () { + beforeEach(function (done) { return DocstoreClient.updateDoc( this.project_id, this.doc_id, @@ -300,11 +300,11 @@ describe('Applying updates to a doc', function() { ) }) - it('should return 400', function() { + it('should return 400', function () { return this.res.statusCode.should.equal(400) }) - return it('should not update the doc in the API', function(done) { + return it('should not update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -318,8 +318,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when no version is provided', function() { - beforeEach(function(done) { + describe('when no version is provided', function () { + beforeEach(function (done) { return DocstoreClient.updateDoc( this.project_id, this.doc_id, @@ -334,11 +334,11 @@ describe('Applying updates to a doc', function() { ) }) - it('should return 400', function() { + it('should return 400', function () { return this.res.statusCode.should.equal(400) }) - return it('should not update the doc in the API', function(done) { + return it('should not update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -352,8 +352,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when the content is large', function() { - beforeEach(function(done) { + describe('when the content is large', function () { + beforeEach(function (done) { const line = new Array(1025).join('x') // 1kb this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1mb return DocstoreClient.updateDoc( @@ -369,11 +369,11 @@ describe('Applying updates to a doc', function() { ) }) - it('should return modified = true', function() { + it('should return modified = true', function () { return this.body.modified.should.equal(true) }) - return it('should update the doc in the API', function(done) { + return it('should update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -386,8 +386,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when there is a large json payload', function() { - beforeEach(function(done) { + describe('when there is a large json payload', function () { + beforeEach(function (done) { const line = new Array(1025).join('x') // 1kb this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1kb this.originalRanges.padding = Array.apply(null, Array(2049)).map( @@ -407,11 +407,11 @@ describe('Applying updates to a doc', function() { ) }) - it('should return modified = true', function() { + it('should return modified = true', function () { return this.body.modified.should.equal(true) }) - return it('should update the doc in the API', function(done) { + return it('should update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -424,8 +424,8 @@ describe('Applying updates to a doc', function() { }) }) - describe('when the document body is too large', function() { - beforeEach(function(done) { + describe('when the document body is too large', function () { + beforeEach(function (done) { const line = new Array(1025).join('x') // 1kb this.largeLines = Array.apply(null, Array(2049)).map(() => line) // 2mb + 1kb return DocstoreClient.updateDoc( @@ -442,15 +442,15 @@ describe('Applying updates to a doc', function() { ) }) - it('should return 413', function() { + it('should return 413', function () { return this.res.statusCode.should.equal(413) }) - it('should report body too large', function() { + it('should report body too large', function () { return this.res.body.should.equal('document body too large') }) - return it('should not update the doc in the API', function(done) { + return it('should not update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, @@ -463,8 +463,8 @@ describe('Applying updates to a doc', function() { }) }) - return describe('when the json payload is too large', function() { - beforeEach(function(done) { + return describe('when the json payload is too large', function () { + beforeEach(function (done) { const line = new Array(1025).join('x') // 1kb this.largeLines = Array.apply(null, Array(1024)).map(() => line) // 1kb this.originalRanges.padding = Array.apply(null, Array(4096)).map( @@ -484,7 +484,7 @@ describe('Applying updates to a doc', function() { ) }) - return it('should not update the doc in the API', function(done) { + return it('should not update the doc in the API', function (done) { return DocstoreClient.getDoc( this.project_id, this.doc_id, diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index e29117bd78..67dc1760e4 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -21,7 +21,7 @@ module.exports = { callbacks: [], ensureRunning(callback) { if (callback == null) { - callback = function(error) {} + callback = function (error) {} } if (this.running) { return callback() @@ -30,19 +30,23 @@ module.exports = { } else { this.initing = true this.callbacks.push(callback) - return app.listen(settings.internal.docstore.port, 'localhost', error => { - if (error != null) { - throw error - } - this.running = true - return (() => { - const result = [] - for (callback of Array.from(this.callbacks)) { - result.push(callback()) + return app.listen( + settings.internal.docstore.port, + 'localhost', + (error) => { + if (error != null) { + throw error } - return result - })() - }) + this.running = true + return (() => { + const result = [] + for (callback of Array.from(this.callbacks)) { + result.push(callback()) + } + return result + })() + } + ) } } } diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index da91433880..bec63a261a 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -20,7 +20,7 @@ const DocArchiveManager = require('../../../../app/js/DocArchiveManager.js') module.exports = DocstoreClient = { createDoc(project_id, doc_id, lines, version, ranges, callback) { if (callback == null) { - callback = function(error) {} + callback = function (error) {} } return DocstoreClient.updateDoc( project_id, @@ -34,7 +34,7 @@ module.exports = DocstoreClient = { getDoc(project_id, doc_id, qs, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } return request.get( { @@ -48,7 +48,7 @@ module.exports = DocstoreClient = { getAllDocs(project_id, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } return request.get( { @@ -61,7 +61,7 @@ module.exports = DocstoreClient = { getAllRanges(project_id, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } return request.get( { @@ -74,7 +74,7 @@ module.exports = DocstoreClient = { updateDoc(project_id, doc_id, lines, version, ranges, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } return request.post( { @@ -91,7 +91,7 @@ module.exports = DocstoreClient = { deleteDoc(project_id, doc_id, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } return request.del( { @@ -103,7 +103,7 @@ module.exports = DocstoreClient = { archiveAllDoc(project_id, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } return request.post( { @@ -115,7 +115,7 @@ module.exports = DocstoreClient = { destroyAllDoc(project_id, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } return request.post( { @@ -127,7 +127,7 @@ module.exports = DocstoreClient = { getS3Doc(project_id, doc_id, callback) { if (callback == null) { - callback = function(error, res, body) {} + callback = function (error, res, body) {} } const options = DocArchiveManager.buildS3Options(project_id + '/' + doc_id) options.json = true diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 06bd6db8aa..f950fe4dc8 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -23,8 +23,8 @@ const { ObjectId } = require('mongojs') const Errors = require('../../../app/js/Errors') const crypto = require('crypto') -describe('DocArchiveManager', function() { - beforeEach(function() { +describe('DocArchiveManager', function () { + beforeEach(function () { this.settings = { docstore: { s3: { @@ -135,15 +135,15 @@ describe('DocArchiveManager', function() { })) }) - describe('archiveDoc', function() { - it('should use correct options', function(done) { + describe('archiveDoc', function () { + it('should use correct options', function (done) { this.request.put = sinon .stub() .callsArgWith(1, null, { statusCode: 200, headers: { etag: '' } }) return this.DocArchiveManager.archiveDoc( this.project_id, this.mongoDocs[0], - err => { + (err) => { const opts = this.request.put.args[0][0] assert.deepEqual(opts.aws, { key: this.settings.docstore.s3.key, @@ -166,30 +166,27 @@ describe('DocArchiveManager', function() { ) }) - it('should return no md5 error', function(done) { + it('should return no md5 error', function (done) { const data = JSON.stringify({ lines: this.mongoDocs[0].lines, ranges: this.mongoDocs[0].ranges, schema_v: 1 }) - this.md5 = crypto - .createHash('md5') - .update(data) - .digest('hex') + this.md5 = crypto.createHash('md5').update(data).digest('hex') this.request.put = sinon .stub() .callsArgWith(1, null, { statusCode: 200, headers: { etag: this.md5 } }) return this.DocArchiveManager.archiveDoc( this.project_id, this.mongoDocs[0], - err => { + (err) => { should.not.exist(err) return done() } ) }) - return it('should return the error', function(done) { + return it('should return the error', function (done) { this.request.put = sinon.stub().callsArgWith(1, this.stubbedError, { statusCode: 400, headers: { etag: '' } @@ -197,7 +194,7 @@ describe('DocArchiveManager', function() { return this.DocArchiveManager.archiveDoc( this.project_id, this.mongoDocs[0], - err => { + (err) => { should.exist(err) return done() } @@ -205,8 +202,8 @@ describe('DocArchiveManager', function() { }) }) - describe('unarchiveDoc', function() { - it('should use correct options', function(done) { + describe('unarchiveDoc', function () { + it('should use correct options', function (done) { this.request.get = sinon .stub() .callsArgWith(1, null, { statusCode: 200 }, this.mongoDocs[0].lines) @@ -216,7 +213,7 @@ describe('DocArchiveManager', function() { return this.DocArchiveManager.unarchiveDoc( this.project_id, this.mongoDocs[0]._id, - err => { + (err) => { const opts = this.request.get.args[0][0] assert.deepEqual(opts.aws, { key: this.settings.docstore.s3.key, @@ -233,19 +230,19 @@ describe('DocArchiveManager', function() { ) }) - it('should return the error', function(done) { + it('should return the error', function (done) { this.request.get = sinon.stub().callsArgWith(1, this.stubbedError, {}, {}) return this.DocArchiveManager.unarchiveDoc( this.project_id, this.mongoDocs[0], - err => { + (err) => { should.exist(err) return done() } ) }) - return it('should error if the doc lines are a string not an array', function(done) { + return it('should error if the doc lines are a string not an array', function (done) { this.request.get = sinon .stub() .callsArgWith(1, null, { statusCode: 200 }, 'this is a string') @@ -253,7 +250,7 @@ describe('DocArchiveManager', function() { return this.DocArchiveManager.unarchiveDoc( this.project_id, this.mongoDocs[0], - err => { + (err) => { should.exist(err) this.request.del.called.should.equal(false) return done() @@ -262,14 +259,14 @@ describe('DocArchiveManager', function() { }) }) - describe('archiveAllDocs', function() { - it('should archive all project docs which are not in s3', function(done) { + describe('archiveAllDocs', function () { + it('should archive all project docs which are not in s3', function (done) { this.MongoManager.getProjectsDocs = sinon .stub() .callsArgWith(3, null, this.mongoDocs) this.DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) - return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { this.DocArchiveManager.archiveDoc .calledWith(this.project_id, this.mongoDocs[0]) .should.equal(true) @@ -292,30 +289,30 @@ describe('DocArchiveManager', function() { }) }) - it('should return error if have no docs', function(done) { + it('should return error if have no docs', function (done) { this.MongoManager.getProjectsDocs = sinon .stub() .callsArgWith(3, null, null) - return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { should.exist(err) return done() }) }) - it('should return the error', function(done) { + it('should return the error', function (done) { this.MongoManager.getProjectsDocs = sinon .stub() .callsArgWith(3, this.error, null) - return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { err.should.equal(this.error) return done() }) }) - return describe('when most have been already put in s3', function() { - beforeEach(function() { + return describe('when most have been already put in s3', function () { + beforeEach(function () { let numberOfDocs = 10 * 1000 this.mongoDocs = [] while (--numberOfDocs !== 0) { @@ -330,8 +327,8 @@ describe('DocArchiveManager', function() { .callsArgWith(2, null)) }) - return it('should not throw and error', function(done) { - return this.DocArchiveManager.archiveAllDocs(this.project_id, err => { + return it('should not throw and error', function (done) { + return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { should.not.exist(err) return done() }) @@ -339,13 +336,13 @@ describe('DocArchiveManager', function() { }) }) - describe('unArchiveAllDocs', function() { - it('should unarchive all inS3 docs', function(done) { + describe('unArchiveAllDocs', function () { + it('should unarchive all inS3 docs', function (done) { this.MongoManager.getArchivedProjectDocs = sinon .stub() .callsArgWith(1, null, this.archivedDocs) this.DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null) - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err => { + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, (err) => { for (const doc of Array.from(this.archivedDocs)) { this.DocArchiveManager.unarchiveDoc .calledWith(this.project_id, doc._id) @@ -356,29 +353,29 @@ describe('DocArchiveManager', function() { }) }) - it('should return error if have no docs', function(done) { + it('should return error if have no docs', function (done) { this.MongoManager.getArchivedProjectDocs = sinon .stub() .callsArgWith(1, null, null) - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err => { + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, (err) => { should.exist(err) return done() }) }) - return it('should return the error', function(done) { + return it('should return the error', function (done) { this.MongoManager.getArchivedProjectDocs = sinon .stub() .callsArgWith(1, this.error, null) - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, err => { + return this.DocArchiveManager.unArchiveAllDocs(this.project_id, (err) => { err.should.equal(this.error) return done() }) }) }) - describe('destroyAllDocs', function() { - beforeEach(function() { + describe('destroyAllDocs', function () { + beforeEach(function () { this.request.del = sinon .stub() .callsArgWith(1, null, { statusCode: 204 }, {}) @@ -387,16 +384,16 @@ describe('DocArchiveManager', function() { .callsArgWith(3, null, this.mixedDocs) this.MongoManager.findDoc = sinon.stub().callsArgWith(3, null, null) this.MongoManager.destroyDoc = sinon.stub().yields() - return Array.from(this.mixedDocs).map(doc => + return Array.from(this.mixedDocs).map((doc) => this.MongoManager.findDoc .withArgs(this.project_id, doc._id) .callsArgWith(3, null, doc) ) }) - it('should destroy all the docs', function(done) { + it('should destroy all the docs', function (done) { this.DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null) - return this.DocArchiveManager.destroyAllDocs(this.project_id, err => { + return this.DocArchiveManager.destroyAllDocs(this.project_id, (err) => { for (const doc of Array.from(this.mixedDocs)) { this.DocArchiveManager.destroyDoc .calledWith(this.project_id, doc._id) @@ -407,8 +404,8 @@ describe('DocArchiveManager', function() { }) }) - it('should only the s3 docs from s3', function(done) { - const docOpts = doc => { + it('should only the s3 docs from s3', function (done) { + const docOpts = (doc) => { return JSON.parse( JSON.stringify({ aws: { @@ -423,7 +420,7 @@ describe('DocArchiveManager', function() { ) } - return this.DocArchiveManager.destroyAllDocs(this.project_id, err => { + return this.DocArchiveManager.destroyAllDocs(this.project_id, (err) => { let doc expect(err).not.to.exist @@ -438,8 +435,8 @@ describe('DocArchiveManager', function() { }) }) - return it('should remove the docs from mongo', function(done) { - this.DocArchiveManager.destroyAllDocs(this.project_id, err => { + return it('should remove the docs from mongo', function (done) { + this.DocArchiveManager.destroyAllDocs(this.project_id, (err) => { return expect(err).not.to.exist }) @@ -451,9 +448,9 @@ describe('DocArchiveManager', function() { }) }) - describe('_s3DocToMongoDoc', function() { - describe('with the old schema', function() { - return it('should return the docs lines', function(done) { + describe('_s3DocToMongoDoc', function () { + describe('with the old schema', function () { + return it('should return the docs lines', function (done) { return this.DocArchiveManager._s3DocToMongoDoc( ['doc', 'lines'], (error, doc) => { @@ -466,8 +463,8 @@ describe('DocArchiveManager', function() { }) }) - describe('with the new schema', function() { - it('should return the doc lines and ranges', function(done) { + describe('with the new schema', function () { + it('should return the doc lines and ranges', function (done) { this.RangeManager.jsonRangesToMongo = sinon .stub() .returns({ mongo: 'ranges' }) @@ -487,7 +484,7 @@ describe('DocArchiveManager', function() { ) }) - return it('should return just the doc lines when there are no ranges', function(done) { + return it('should return just the doc lines when there are no ranges', function (done) { return this.DocArchiveManager._s3DocToMongoDoc( { lines: ['doc', 'lines'], @@ -503,8 +500,8 @@ describe('DocArchiveManager', function() { }) }) - return describe('with an unrecognised schema', function() { - return it('should return an error', function(done) { + return describe('with an unrecognised schema', function () { + return it('should return an error', function (done) { return this.DocArchiveManager._s3DocToMongoDoc( { schema_v: 2 @@ -518,9 +515,9 @@ describe('DocArchiveManager', function() { }) }) - return describe('_mongoDocToS3Doc', function() { - describe('with a valid doc', function() { - return it('should return the json version', function(done) { + return describe('_mongoDocToS3Doc', function () { + describe('with a valid doc', function () { + return it('should return the json version', function (done) { let doc return this.DocArchiveManager._mongoDocToS3Doc( (doc = { @@ -541,17 +538,17 @@ describe('DocArchiveManager', function() { }) }) - describe('with null bytes in the result', function() { - beforeEach(function() { + describe('with null bytes in the result', function () { + beforeEach(function () { this._stringify = JSON.stringify return (JSON.stringify = sinon.stub().returns('{"bad": "\u0000"}')) }) - afterEach(function() { + afterEach(function () { return (JSON.stringify = this._stringify) }) - return it('should return an error', function(done) { + return it('should return an error', function (done) { return this.DocArchiveManager._mongoDocToS3Doc( { lines: ['doc', 'lines'], @@ -565,8 +562,8 @@ describe('DocArchiveManager', function() { }) }) - return describe('without doc lines', function() { - return it('should return an error', function(done) { + return describe('without doc lines', function () { + return it('should return an error', function (done) { return this.DocArchiveManager._mongoDocToS3Doc({}, (err, s3_doc) => { expect(err).to.exist return done() diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 9508e74f2e..63b70493a5 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -22,8 +22,8 @@ const modulePath = require('path').join(__dirname, '../../../app/js/DocManager') const { ObjectId } = require('mongojs') const Errors = require('../../../app/js/Errors') -describe('DocManager', function() { - beforeEach(function() { +describe('DocManager', function () { + beforeEach(function () { this.DocManager = SandboxedModule.require(modulePath, { requires: { './MongoManager': (this.MongoManager = {}), @@ -48,12 +48,12 @@ describe('DocManager', function() { return (this.stubbedError = new Error('blew up')) }) - describe('checkDocExists', function() { - beforeEach(function() { + describe('checkDocExists', function () { + beforeEach(function () { return (this.DocManager._getDoc = sinon.stub()) }) - it('should call get doc with a quick filter', function(done) { + it('should call get doc with a quick filter', function (done) { this.DocManager._getDoc.callsArgWith(3, null, { _id: this.doc_id }) return this.DocManager.checkDocExists( this.project_id, @@ -68,7 +68,7 @@ describe('DocManager', function() { ) }) - it('should return false when doc is not there', function(done) { + it('should return false when doc is not there', function (done) { this.DocManager._getDoc.callsArgWith(3, null) return this.DocManager.checkDocExists( this.project_id, @@ -80,7 +80,7 @@ describe('DocManager', function() { ) }) - return it('should return error when get doc errors', function(done) { + return it('should return error when get doc errors', function (done) { this.DocManager._getDoc.callsArgWith(3, 'error') return this.DocManager.checkDocExists( this.project_id, @@ -93,8 +93,8 @@ describe('DocManager', function() { }) }) - describe('getFullDoc', function() { - beforeEach(function() { + describe('getFullDoc', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub() return (this.doc = { _id: this.doc_id, @@ -102,7 +102,7 @@ describe('DocManager', function() { }) }) - it('should call get doc with a quick filter', function(done) { + it('should call get doc with a quick filter', function (done) { this.DocManager._getDoc.callsArgWith(3, null, this.doc) return this.DocManager.getFullDoc( this.project_id, @@ -124,7 +124,7 @@ describe('DocManager', function() { ) }) - return it('should return error when get doc errors', function(done) { + return it('should return error when get doc errors', function (done) { this.DocManager._getDoc.callsArgWith(3, 'error') return this.DocManager.getFullDoc( this.project_id, @@ -137,13 +137,13 @@ describe('DocManager', function() { }) }) - describe('getRawDoc', function() { - beforeEach(function() { + describe('getRawDoc', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub() return (this.doc = { lines: ['2134'] }) }) - it('should call get doc with a quick filter', function(done) { + it('should call get doc with a quick filter', function (done) { this.DocManager._getDoc.callsArgWith(3, null, this.doc) return this.DocManager.getDocLines( this.project_id, @@ -161,7 +161,7 @@ describe('DocManager', function() { ) }) - return it('should return error when get doc errors', function(done) { + return it('should return error when get doc errors', function (done) { this.DocManager._getDoc.callsArgWith(3, 'error') return this.DocManager.getDocLines( this.project_id, @@ -174,8 +174,8 @@ describe('DocManager', function() { }) }) - describe('getDoc', function() { - beforeEach(function() { + describe('getDoc', function () { + beforeEach(function () { this.project = { name: 'mock-project' } this.doc = { _id: this.doc_id, @@ -189,29 +189,29 @@ describe('DocManager', function() { .yields(null, this.version)) }) - describe('when using a filter', function() { - beforeEach(function() { + describe('when using a filter', function () { + beforeEach(function () { return this.MongoManager.findDoc.yields(null, this.doc) }) - it('should error if inS3 is not set to true', function(done) { + it('should error if inS3 is not set to true', function (done) { return this.DocManager._getDoc( this.project_id, this.doc_id, { inS3: false }, - err => { + (err) => { expect(err).to.exist return done() } ) }) - it('should always get inS3 even when no filter is passed', function(done) { + it('should always get inS3 even when no filter is passed', function (done) { return this.DocManager._getDoc( this.project_id, this.doc_id, undefined, - err => { + (err) => { this.MongoManager.findDoc.called.should.equal(false) expect(err).to.exist return done() @@ -219,12 +219,12 @@ describe('DocManager', function() { ) }) - return it('should not error if inS3 is set to true', function(done) { + return it('should not error if inS3 is set to true', function (done) { return this.DocManager._getDoc( this.project_id, this.doc_id, { inS3: true }, - err => { + (err) => { expect(err).to.not.exist return done() } @@ -232,8 +232,8 @@ describe('DocManager', function() { }) }) - describe('when the doc is in the doc collection', function() { - beforeEach(function() { + describe('when the doc is in the doc collection', function () { + beforeEach(function () { this.MongoManager.findDoc.yields(null, this.doc) return this.DocManager._getDoc( this.project_id, @@ -243,19 +243,19 @@ describe('DocManager', function() { ) }) - it('should get the doc from the doc collection', function() { + it('should get the doc from the doc collection', function () { return this.MongoManager.findDoc .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - it('should get the doc version from the docOps collection', function() { + it('should get the doc version from the docOps collection', function () { return this.MongoManager.getDocVersion .calledWith(this.doc_id) .should.equal(true) }) - return it('should return the callback with the doc with the version', function() { + return it('should return the callback with the doc with the version', function () { this.callback.called.should.equal(true) const doc = this.callback.args[0][1] doc.lines.should.equal(this.doc.lines) @@ -263,8 +263,8 @@ describe('DocManager', function() { }) }) - describe('without the version filter', function() { - beforeEach(function() { + describe('without the version filter', function () { + beforeEach(function () { this.MongoManager.findDoc.yields(null, this.doc) return this.DocManager._getDoc( this.project_id, @@ -274,13 +274,13 @@ describe('DocManager', function() { ) }) - return it('should not get the doc version from the docOps collection', function() { + return it('should not get the doc version from the docOps collection', function () { return this.MongoManager.getDocVersion.called.should.equal(false) }) }) - describe('when MongoManager.findDoc errors', function() { - beforeEach(function() { + describe('when MongoManager.findDoc errors', function () { + beforeEach(function () { this.MongoManager.findDoc.yields(this.stubbedError) return this.DocManager._getDoc( this.project_id, @@ -290,13 +290,13 @@ describe('DocManager', function() { ) }) - return it('should return the error', function() { + return it('should return the error', function () { return this.callback.calledWith(this.stubbedError).should.equal(true) }) }) - describe('when the doc is archived', function() { - beforeEach(function() { + describe('when the doc is archived', function () { + beforeEach(function () { this.doc = { _id: this.doc_id, project_id: this.project_id, @@ -321,23 +321,23 @@ describe('DocManager', function() { ) }) - it('should call the DocArchive to unarchive the doc', function() { + it('should call the DocArchive to unarchive the doc', function () { return this.DocArchiveManager.unarchiveDoc .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - it('should look up the doc twice', function() { + it('should look up the doc twice', function () { return this.MongoManager.findDoc.calledTwice.should.equal(true) }) - return it('should return the doc', function() { + return it('should return the doc', function () { return this.callback.calledWith(null, this.doc).should.equal(true) }) }) - return describe('when the doc does not exist in the docs collection', function() { - beforeEach(function() { + return describe('when the doc does not exist in the docs collection', function () { + beforeEach(function () { this.MongoManager.findDoc = sinon.stub().yields(null, null) return this.DocManager._getDoc( this.project_id, @@ -347,7 +347,7 @@ describe('DocManager', function() { ) }) - return it('should return a NotFoundError', function() { + return it('should return a NotFoundError', function () { return this.callback .calledWith( sinon.match.has( @@ -360,9 +360,9 @@ describe('DocManager', function() { }) }) - describe('getAllNonDeletedDocs', function() { - describe('when the project exists', function() { - beforeEach(function() { + describe('getAllNonDeletedDocs', function () { + describe('when the project exists', function () { + beforeEach(function () { this.docs = [ { _id: this.doc_id, @@ -384,19 +384,19 @@ describe('DocManager', function() { ) }) - it('should get the project from the database', function() { + it('should get the project from the database', function () { return this.MongoManager.getProjectsDocs .calledWith(this.project_id, { include_deleted: false }, this.filter) .should.equal(true) }) - return it('should return the docs', function() { + return it('should return the docs', function () { return this.callback.calledWith(null, this.docs).should.equal(true) }) }) - return describe('when there are no docs for the project', function() { - beforeEach(function() { + return describe('when there are no docs for the project', function () { + beforeEach(function () { this.MongoManager.getProjectsDocs = sinon .stub() .callsArgWith(3, null, null) @@ -410,7 +410,7 @@ describe('DocManager', function() { ) }) - return it('should return a NotFoundError', function() { + return it('should return a NotFoundError', function () { return this.callback .calledWith( sinon.match.has('message', `No docs for project ${this.project_id}`) @@ -420,9 +420,9 @@ describe('DocManager', function() { }) }) - describe('deleteDoc', function() { - describe('when the doc exists', function() { - beforeEach(function() { + describe('deleteDoc', function () { + describe('when the doc exists', function () { + beforeEach(function () { this.lines = ['mock', 'doc', 'lines'] this.rev = 77 this.DocManager.checkDocExists = sinon @@ -436,25 +436,25 @@ describe('DocManager', function() { ) }) - it('should get the doc', function() { + it('should get the doc', function () { return this.DocManager.checkDocExists .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - it('should mark doc as deleted', function() { + it('should mark doc as deleted', function () { return this.MongoManager.markDocAsDeleted .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - return it('should return the callback', function() { + return it('should return the callback', function () { return this.callback.called.should.equal(true) }) }) - return describe('when the doc does not exist', function() { - beforeEach(function() { + return describe('when the doc does not exist', function () { + beforeEach(function () { this.DocManager.checkDocExists = sinon .stub() .callsArgWith(2, null, false) @@ -465,7 +465,7 @@ describe('DocManager', function() { ) }) - return it('should return a NotFoundError', function() { + return it('should return a NotFoundError', function () { return this.callback .calledWith( sinon.match.has( @@ -478,8 +478,8 @@ describe('DocManager', function() { }) }) - return describe('updateDoc', function() { - beforeEach(function() { + return describe('updateDoc', function () { + beforeEach(function () { this.oldDocLines = ['old', 'doc', 'lines'] this.newDocLines = ['new', 'doc', 'lines'] this.originalRanges = { @@ -521,8 +521,8 @@ describe('DocManager', function() { return (this.DocManager._getDoc = sinon.stub()) }) - describe('when only the doc lines have changed', function() { - beforeEach(function() { + describe('when only the doc lines have changed', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) return this.DocManager.updateDoc( this.project_id, @@ -534,7 +534,7 @@ describe('DocManager', function() { ) }) - it('should get the existing doc', function() { + it('should get the existing doc', function () { return this.DocManager._getDoc .calledWith(this.project_id, this.doc_id, { version: true, @@ -547,25 +547,25 @@ describe('DocManager', function() { .should.equal(true) }) - it('should upsert the document to the doc collection', function() { + it('should upsert the document to the doc collection', function () { return this.MongoManager.upsertIntoDocCollection .calledWith(this.project_id, this.doc_id, { lines: this.newDocLines }) .should.equal(true) }) - it('should not update the version', function() { + it('should not update the version', function () { return this.MongoManager.setDocVersion.called.should.equal(false) }) - return it('should return the callback with the new rev', function() { + return it('should return the callback with the new rev', function () { return this.callback .calledWith(null, true, this.rev + 1) .should.equal(true) }) }) - describe('when the doc ranges have changed', function() { - beforeEach(function() { + describe('when the doc ranges have changed', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) this.RangeManager.shouldUpdateRanges.returns(true) return this.DocManager.updateDoc( @@ -578,25 +578,25 @@ describe('DocManager', function() { ) }) - it('should upsert the ranges', function() { + it('should upsert the ranges', function () { return this.MongoManager.upsertIntoDocCollection .calledWith(this.project_id, this.doc_id, { ranges: this.newRanges }) .should.equal(true) }) - it('should not update the version', function() { + it('should not update the version', function () { return this.MongoManager.setDocVersion.called.should.equal(false) }) - return it('should return the callback with the new rev', function() { + return it('should return the callback with the new rev', function () { return this.callback .calledWith(null, true, this.rev + 1) .should.equal(true) }) }) - describe('when only the version has changed', function() { - beforeEach(function() { + describe('when only the version has changed', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) return this.DocManager.updateDoc( this.project_id, @@ -608,25 +608,25 @@ describe('DocManager', function() { ) }) - it('should not change the lines or ranges', function() { + it('should not change the lines or ranges', function () { return this.MongoManager.upsertIntoDocCollection.called.should.equal( false ) }) - it('should update the version', function() { + it('should update the version', function () { return this.MongoManager.setDocVersion .calledWith(this.doc_id, this.version + 1) .should.equal(true) }) - return it('should return the callback with the old rev', function() { + return it('should return the callback with the old rev', function () { return this.callback.calledWith(null, true, this.rev).should.equal(true) }) }) - describe('when the doc has not changed at all', function() { - beforeEach(function() { + describe('when the doc has not changed at all', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) return this.DocManager.updateDoc( this.project_id, @@ -638,25 +638,25 @@ describe('DocManager', function() { ) }) - it('should not update the ranges or lines', function() { + it('should not update the ranges or lines', function () { return this.MongoManager.upsertIntoDocCollection.called.should.equal( false ) }) - it('should not update the version', function() { + it('should not update the version', function () { return this.MongoManager.setDocVersion.called.should.equal(false) }) - return it('should return the callback with the old rev and modified == false', function() { + return it('should return the callback with the old rev and modified == false', function () { return this.callback .calledWith(null, false, this.rev) .should.equal(true) }) }) - describe('when the version is null', function() { - beforeEach(function() { + describe('when the version is null', function () { + beforeEach(function () { return this.DocManager.updateDoc( this.project_id, this.doc_id, @@ -667,7 +667,7 @@ describe('DocManager', function() { ) }) - return it('should return an error', function() { + return it('should return an error', function () { return this.callback .calledWith( sinon.match.has('message', 'no lines, version or ranges provided') @@ -676,8 +676,8 @@ describe('DocManager', function() { }) }) - describe('when the lines are null', function() { - beforeEach(function() { + describe('when the lines are null', function () { + beforeEach(function () { return this.DocManager.updateDoc( this.project_id, this.doc_id, @@ -688,7 +688,7 @@ describe('DocManager', function() { ) }) - return it('should return an error', function() { + return it('should return an error', function () { return this.callback .calledWith( sinon.match.has('message', 'no lines, version or ranges provided') @@ -697,8 +697,8 @@ describe('DocManager', function() { }) }) - describe('when the ranges are null', function() { - beforeEach(function() { + describe('when the ranges are null', function () { + beforeEach(function () { return this.DocManager.updateDoc( this.project_id, this.doc_id, @@ -709,7 +709,7 @@ describe('DocManager', function() { ) }) - return it('should return an error', function() { + return it('should return an error', function () { return this.callback .calledWith( sinon.match.has('message', 'no lines, version or ranges provided') @@ -718,8 +718,8 @@ describe('DocManager', function() { }) }) - describe('when there is a generic error getting the doc', function() { - beforeEach(function() { + describe('when there is a generic error getting the doc', function () { + beforeEach(function () { this.error = new Error('doc could not be found') this.DocManager._getDoc = sinon .stub() @@ -734,19 +734,19 @@ describe('DocManager', function() { ) }) - it('should not upsert the document to the doc collection', function() { + it('should not upsert the document to the doc collection', function () { return this.MongoManager.upsertIntoDocCollection.called.should.equal( false ) }) - return it('should return the callback with the error', function() { + return it('should return the callback with the error', function () { return this.callback.calledWith(this.error).should.equal(true) }) }) - describe('when the doc lines have not changed', function() { - beforeEach(function() { + describe('when the doc lines have not changed', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, this.doc) return this.DocManager.updateDoc( this.project_id, @@ -758,21 +758,21 @@ describe('DocManager', function() { ) }) - it('should not update the doc', function() { + it('should not update the doc', function () { return this.MongoManager.upsertIntoDocCollection.called.should.equal( false ) }) - return it('should return the callback with the existing rev', function() { + return it('should return the callback with the existing rev', function () { return this.callback .calledWith(null, false, this.rev) .should.equal(true) }) }) - return describe('when the doc does not exist', function() { - beforeEach(function() { + return describe('when the doc does not exist', function () { + beforeEach(function () { this.DocManager._getDoc = sinon.stub().callsArgWith(3, null, null, null) return this.DocManager.updateDoc( this.project_id, @@ -784,7 +784,7 @@ describe('DocManager', function() { ) }) - it('should upsert the document to the doc collection', function() { + it('should upsert the document to the doc collection', function () { return this.MongoManager.upsertIntoDocCollection .calledWith(this.project_id, this.doc_id, { lines: this.newDocLines, @@ -793,13 +793,13 @@ describe('DocManager', function() { .should.equal(true) }) - it('should set the version', function() { + it('should set the version', function () { return this.MongoManager.setDocVersion .calledWith(this.doc_id, this.version) .should.equal(true) }) - return it('should return the callback with the new rev', function() { + return it('should return the callback with the new rev', function () { return this.callback.calledWith(null, true, 1).should.equal(true) }) }) diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 46bd5088b1..5463660269 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -21,8 +21,8 @@ const modulePath = require('path').join( ) const { ObjectId } = require('mongojs') -describe('HttpController', function() { - beforeEach(function() { +describe('HttpController', function () { + beforeEach(function () { this.HttpController = SandboxedModule.require(modulePath, { requires: { './DocManager': (this.DocManager = {}), @@ -60,9 +60,9 @@ describe('HttpController', function() { }) }) - describe('getDoc', function() { - describe('without deleted docs', function() { - beforeEach(function() { + describe('getDoc', function () { + describe('without deleted docs', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id, doc_id: this.doc_id @@ -73,13 +73,13 @@ describe('HttpController', function() { return this.HttpController.getDoc(this.req, this.res, this.next) }) - it('should get the document with the version (including deleted)', function() { + it('should get the document with the version (including deleted)', function () { return this.DocManager.getFullDoc .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - return it('should return the doc as JSON', function() { + return it('should return the doc as JSON', function () { return this.res.json .calledWith({ _id: this.doc_id, @@ -91,8 +91,8 @@ describe('HttpController', function() { }) }) - return describe('which is deleted', function() { - beforeEach(function() { + return describe('which is deleted', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id, doc_id: this.doc_id @@ -102,19 +102,19 @@ describe('HttpController', function() { .callsArgWith(2, null, this.deletedDoc)) }) - it('should get the doc from the doc manager', function() { + it('should get the doc from the doc manager', function () { this.HttpController.getDoc(this.req, this.res, this.next) return this.DocManager.getFullDoc .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - it('should return 404 if the query string delete is not set ', function() { + it('should return 404 if the query string delete is not set ', function () { this.HttpController.getDoc(this.req, this.res, this.next) return this.res.send.calledWith(404).should.equal(true) }) - return it('should return the doc as JSON if include_deleted is set to true', function() { + return it('should return the doc as JSON if include_deleted is set to true', function () { this.req.query.include_deleted = 'true' this.HttpController.getDoc(this.req, this.res, this.next) return this.res.json @@ -130,8 +130,8 @@ describe('HttpController', function() { }) }) - describe('getRawDoc', function() { - beforeEach(function() { + describe('getRawDoc', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id, doc_id: this.doc_id @@ -140,19 +140,19 @@ describe('HttpController', function() { return this.HttpController.getRawDoc(this.req, this.res, this.next) }) - it('should get the document without the version', function() { + it('should get the document without the version', function () { return this.DocManager.getDocLines .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - it('should set the content type header', function() { + it('should set the content type header', function () { return this.res.setHeader .calledWith('content-type', 'text/plain') .should.equal(true) }) - return it('should send the raw version of the doc', function() { + return it('should send the raw version of the doc', function () { return assert.deepEqual( this.res.send.args[0][0], `${this.doc.lines[0]}\n${this.doc.lines[1]}\n${this.doc.lines[2]}\n${this.doc.lines[3]}\n${this.doc.lines[4]}\n${this.doc.lines[5]}` @@ -160,9 +160,9 @@ describe('HttpController', function() { }) }) - describe('getAllDocs', function() { - describe('normally', function() { - beforeEach(function() { + describe('getAllDocs', function () { + describe('normally', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id } this.docs = [ { @@ -182,13 +182,13 @@ describe('HttpController', function() { return this.HttpController.getAllDocs(this.req, this.res, this.next) }) - it('should get all the (non-deleted) docs', function() { + it('should get all the (non-deleted) docs', function () { return this.DocManager.getAllNonDeletedDocs .calledWith(this.project_id, { lines: true, rev: true }) .should.equal(true) }) - return it('should return the doc as JSON', function() { + return it('should return the doc as JSON', function () { return this.res.json .calledWith([ { @@ -206,8 +206,8 @@ describe('HttpController', function() { }) }) - return describe('with a null doc', function() { - beforeEach(function() { + return describe('with a null doc', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id } this.docs = [ { @@ -228,7 +228,7 @@ describe('HttpController', function() { return this.HttpController.getAllDocs(this.req, this.res, this.next) }) - it('should return the non null docs as JSON', function() { + it('should return the non null docs as JSON', function () { return this.res.json .calledWith([ { @@ -245,7 +245,7 @@ describe('HttpController', function() { .should.equal(true) }) - return it('should log out an error', function() { + return it('should log out an error', function () { return this.logger.error .calledWith( { @@ -259,9 +259,9 @@ describe('HttpController', function() { }) }) - describe('getAllRanges', function() { - return describe('normally', function() { - beforeEach(function() { + describe('getAllRanges', function () { + return describe('normally', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id } this.docs = [ { @@ -279,13 +279,13 @@ describe('HttpController', function() { return this.HttpController.getAllRanges(this.req, this.res, this.next) }) - it('should get all the (non-deleted) doc ranges', function() { + it('should get all the (non-deleted) doc ranges', function () { return this.DocManager.getAllNonDeletedDocs .calledWith(this.project_id, { ranges: true }) .should.equal(true) }) - return it('should return the doc as JSON', function() { + return it('should return the doc as JSON', function () { return this.res.json .calledWith([ { @@ -302,16 +302,16 @@ describe('HttpController', function() { }) }) - describe('updateDoc', function() { - beforeEach(function() { + describe('updateDoc', function () { + beforeEach(function () { return (this.req.params = { project_id: this.project_id, doc_id: this.doc_id }) }) - describe('when the doc lines exist and were updated', function() { - beforeEach(function() { + describe('when the doc lines exist and were updated', function () { + beforeEach(function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), @@ -323,7 +323,7 @@ describe('HttpController', function() { return this.HttpController.updateDoc(this.req, this.res, this.next) }) - it('should update the document', function() { + it('should update the document', function () { return this.DocManager.updateDoc .calledWith( this.project_id, @@ -335,15 +335,15 @@ describe('HttpController', function() { .should.equal(true) }) - return it('should return a modified status', function() { + return it('should return a modified status', function () { return this.res.json .calledWith({ modified: true, rev: this.rev }) .should.equal(true) }) }) - describe('when the doc lines exist and were not updated', function() { - beforeEach(function() { + describe('when the doc lines exist and were not updated', function () { + beforeEach(function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), @@ -355,63 +355,63 @@ describe('HttpController', function() { return this.HttpController.updateDoc(this.req, this.res, this.next) }) - return it('should return a modified status', function() { + return it('should return a modified status', function () { return this.res.json .calledWith({ modified: false, rev: this.rev }) .should.equal(true) }) }) - describe('when the doc lines are not provided', function() { - beforeEach(function() { + describe('when the doc lines are not provided', function () { + beforeEach(function () { this.req.body = { version: 42, ranges: {} } this.DocManager.updateDoc = sinon.stub().yields(null, false) return this.HttpController.updateDoc(this.req, this.res, this.next) }) - it('should not update the document', function() { + it('should not update the document', function () { return this.DocManager.updateDoc.called.should.equal(false) }) - return it('should return a 400 (bad request) response', function() { + return it('should return a 400 (bad request) response', function () { return this.res.send.calledWith(400).should.equal(true) }) }) - describe('when the doc version are not provided', function() { - beforeEach(function() { + describe('when the doc version are not provided', function () { + beforeEach(function () { this.req.body = { version: 42, lines: ['hello world'] } this.DocManager.updateDoc = sinon.stub().yields(null, false) return this.HttpController.updateDoc(this.req, this.res, this.next) }) - it('should not update the document', function() { + it('should not update the document', function () { return this.DocManager.updateDoc.called.should.equal(false) }) - return it('should return a 400 (bad request) response', function() { + return it('should return a 400 (bad request) response', function () { return this.res.send.calledWith(400).should.equal(true) }) }) - describe('when the doc ranges is not provided', function() { - beforeEach(function() { + describe('when the doc ranges is not provided', function () { + beforeEach(function () { this.req.body = { lines: ['foo'], version: 42 } this.DocManager.updateDoc = sinon.stub().yields(null, false) return this.HttpController.updateDoc(this.req, this.res, this.next) }) - it('should not update the document', function() { + it('should not update the document', function () { return this.DocManager.updateDoc.called.should.equal(false) }) - return it('should return a 400 (bad request) response', function() { + return it('should return a 400 (bad request) response', function () { return this.res.send.calledWith(400).should.equal(true) }) }) - return describe('when the doc body is too large', function() { - beforeEach(function() { + return describe('when the doc body is too large', function () { + beforeEach(function () { this.req.body = { lines: (this.lines = Array(2049).fill('a'.repeat(1024))), version: (this.version = 42), @@ -420,18 +420,18 @@ describe('HttpController', function() { return this.HttpController.updateDoc(this.req, this.res, this.next) }) - it('should return a 413 (too large) response', function() { + it('should return a 413 (too large) response', function () { return sinon.assert.calledWith(this.res.status, 413) }) - return it('should report that the document body is too large', function() { + return it('should report that the document body is too large', function () { return sinon.assert.calledWith(this.res.send, 'document body too large') }) }) }) - describe('deleteDoc', function() { - beforeEach(function() { + describe('deleteDoc', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id, doc_id: this.doc_id @@ -440,50 +440,50 @@ describe('HttpController', function() { return this.HttpController.deleteDoc(this.req, this.res, this.next) }) - it('should delete the document', function() { + it('should delete the document', function () { return this.DocManager.deleteDoc .calledWith(this.project_id, this.doc_id) .should.equal(true) }) - return it('should return a 204 (No Content)', function() { + return it('should return a 204 (No Content)', function () { return this.res.send.calledWith(204).should.equal(true) }) }) - describe('archiveAllDocs', function() { - beforeEach(function() { + describe('archiveAllDocs', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id } this.DocArchiveManager.archiveAllDocs = sinon.stub().callsArg(1) return this.HttpController.archiveAllDocs(this.req, this.res, this.next) }) - it('should archive the project', function() { + it('should archive the project', function () { return this.DocArchiveManager.archiveAllDocs .calledWith(this.project_id) .should.equal(true) }) - return it('should return a 204 (No Content)', function() { + return it('should return a 204 (No Content)', function () { return this.res.send.calledWith(204).should.equal(true) }) }) - return describe('destroyAllDocs', function() { - beforeEach(function() { + return describe('destroyAllDocs', function () { + beforeEach(function () { this.req.params = { project_id: this.project_id } this.DocArchiveManager.destroyAllDocs = sinon.stub().callsArg(1) return this.HttpController.destroyAllDocs(this.req, this.res, this.next) }) - it('should destroy the docs', function() { + it('should destroy the docs', function () { return sinon.assert.calledWith( this.DocArchiveManager.destroyAllDocs, this.project_id ) }) - return it('should return 204', function() { + return it('should return 204', function () { return sinon.assert.calledWith(this.res.send, 204) }) }) diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 0af25c5ce7..f26e6539f1 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -19,8 +19,8 @@ const modulePath = require('path').join( const { ObjectId } = require('mongojs') const { assert } = require('chai') -describe('MongoManager', function() { - beforeEach(function() { +describe('MongoManager', function () { + beforeEach(function () { this.MongoManager = SandboxedModule.require(modulePath, { requires: { './mongojs': { @@ -37,8 +37,8 @@ describe('MongoManager', function() { return (this.stubbedErr = new Error('hello world')) }) - describe('findDoc', function() { - beforeEach(function() { + describe('findDoc', function () { + beforeEach(function () { this.doc = { name: 'mock-doc' } this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc]) this.filter = { lines: true } @@ -50,7 +50,7 @@ describe('MongoManager', function() { ) }) - it('should find the doc', function() { + it('should find the doc', function () { return this.db.docs.find .calledWith( { @@ -62,13 +62,13 @@ describe('MongoManager', function() { .should.equal(true) }) - return it('should call the callback with the doc', function() { + return it('should call the callback with the doc', function () { return this.callback.calledWith(null, this.doc).should.equal(true) }) }) - describe('getProjectsDocs', function() { - beforeEach(function() { + describe('getProjectsDocs', function () { + beforeEach(function () { this.filter = { lines: true } this.doc1 = { name: 'mock-doc1' } this.doc2 = { name: 'mock-doc2' } @@ -79,8 +79,8 @@ describe('MongoManager', function() { .callsArgWith(2, null, [this.doc, this.doc3, this.doc4])) }) - describe('with included_deleted = false', function() { - beforeEach(function() { + describe('with included_deleted = false', function () { + beforeEach(function () { return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: false }, @@ -89,7 +89,7 @@ describe('MongoManager', function() { ) }) - it('should find the non-deleted docs via the project_id', function() { + it('should find the non-deleted docs via the project_id', function () { return this.db.docs.find .calledWith( { @@ -101,15 +101,15 @@ describe('MongoManager', function() { .should.equal(true) }) - return it('should call the callback with the docs', function() { + return it('should call the callback with the docs', function () { return this.callback .calledWith(null, [this.doc, this.doc3, this.doc4]) .should.equal(true) }) }) - return describe('with included_deleted = true', function() { - beforeEach(function() { + return describe('with included_deleted = true', function () { + beforeEach(function () { return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: true }, @@ -118,7 +118,7 @@ describe('MongoManager', function() { ) }) - it('should find all via the project_id', function() { + it('should find all via the project_id', function () { return this.db.docs.find .calledWith( { @@ -129,7 +129,7 @@ describe('MongoManager', function() { .should.equal(true) }) - return it('should call the callback with the docs', function() { + return it('should call the callback with the docs', function () { return this.callback .calledWith(null, [this.doc, this.doc3, this.doc4]) .should.equal(true) @@ -137,18 +137,18 @@ describe('MongoManager', function() { }) }) - describe('upsertIntoDocCollection', function() { - beforeEach(function() { + describe('upsertIntoDocCollection', function () { + beforeEach(function () { this.db.docs.update = sinon.stub().callsArgWith(3, this.stubbedErr) return (this.oldRev = 77) }) - it('should upsert the document', function(done) { + it('should upsert the document', function (done) { return this.MongoManager.upsertIntoDocCollection( this.project_id, this.doc_id, { lines: this.lines }, - err => { + (err) => { const args = this.db.docs.update.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id) }) assert.equal(args[1].$set.lines, this.lines) @@ -159,12 +159,12 @@ describe('MongoManager', function() { ) }) - return it('should return the error', function(done) { + return it('should return the error', function (done) { return this.MongoManager.upsertIntoDocCollection( this.project_id, this.doc_id, { lines: this.lines }, - err => { + (err) => { err.should.equal(this.stubbedErr) return done() } @@ -172,17 +172,17 @@ describe('MongoManager', function() { }) }) - describe('markDocAsDeleted', function() { - beforeEach(function() { + describe('markDocAsDeleted', function () { + beforeEach(function () { this.db.docs.update = sinon.stub().callsArgWith(2, this.stubbedErr) return (this.oldRev = 77) }) - it('should process the update', function(done) { + it('should process the update', function (done) { return this.MongoManager.markDocAsDeleted( this.project_id, this.doc_id, - err => { + (err) => { const args = this.db.docs.update.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id), @@ -194,11 +194,11 @@ describe('MongoManager', function() { ) }) - return it('should return the error', function(done) { + return it('should return the error', function (done) { return this.MongoManager.markDocAsDeleted( this.project_id, this.doc_id, - err => { + (err) => { err.should.equal(this.stubbedErr) return done() } @@ -206,59 +206,59 @@ describe('MongoManager', function() { }) }) - describe('destroyDoc', function() { - beforeEach(function(done) { + describe('destroyDoc', function () { + beforeEach(function (done) { this.db.docs.remove = sinon.stub().yields() this.db.docOps.remove = sinon.stub().yields() return this.MongoManager.destroyDoc('123456789012', done) }) - it('should destroy the doc', function() { + it('should destroy the doc', function () { return sinon.assert.calledWith(this.db.docs.remove, { _id: ObjectId('123456789012') }) }) - return it('should destroy the docOps', function() { + return it('should destroy the docOps', function () { return sinon.assert.calledWith(this.db.docOps.remove, { doc_id: ObjectId('123456789012') }) }) }) - describe('getDocVersion', function() { - describe('when the doc exists', function() { - beforeEach(function() { + describe('getDocVersion', function () { + describe('when the doc exists', function () { + beforeEach(function () { this.doc = { version: (this.version = 42) } this.db.docOps.find = sinon.stub().callsArgWith(2, null, [this.doc]) return this.MongoManager.getDocVersion(this.doc_id, this.callback) }) - it('should look for the doc in the database', function() { + it('should look for the doc in the database', function () { return this.db.docOps.find .calledWith({ doc_id: ObjectId(this.doc_id) }, { version: 1 }) .should.equal(true) }) - return it('should call the callback with the version', function() { + return it('should call the callback with the version', function () { return this.callback.calledWith(null, this.version).should.equal(true) }) }) - return describe("when the doc doesn't exist", function() { - beforeEach(function() { + return describe("when the doc doesn't exist", function () { + beforeEach(function () { this.db.docOps.find = sinon.stub().callsArgWith(2, null, []) return this.MongoManager.getDocVersion(this.doc_id, this.callback) }) - return it('should call the callback with 0', function() { + return it('should call the callback with 0', function () { return this.callback.calledWith(null, 0).should.equal(true) }) }) }) - return describe('setDocVersion', function() { - beforeEach(function() { + return describe('setDocVersion', function () { + beforeEach(function () { this.version = 42 this.db.docOps.update = sinon.stub().callsArg(3) return this.MongoManager.setDocVersion( @@ -268,7 +268,7 @@ describe('MongoManager', function() { ) }) - it('should update the doc version', function() { + it('should update the doc version', function () { return this.db.docOps.update .calledWith( { @@ -286,7 +286,7 @@ describe('MongoManager', function() { .should.equal(true) }) - return it('should call the callback', function() { + return it('should call the callback', function () { return this.callback.called.should.equal(true) }) }) diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index ff6d96a0d1..eafc60110b 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -22,8 +22,8 @@ const { ObjectId } = require('mongojs') const { assert } = require('chai') const _ = require('underscore') -describe('RangeManager', function() { - beforeEach(function() { +describe('RangeManager', function () { + beforeEach(function () { return (this.RangeManager = SandboxedModule.require(modulePath, { requires: { './mongojs': { @@ -33,8 +33,8 @@ describe('RangeManager', function() { })) }) - describe('jsonRangesToMongo', function() { - it('should convert ObjectIds and dates to proper objects', function() { + describe('jsonRangesToMongo', function () { + it('should convert ObjectIds and dates to proper objects', function () { const change_id = ObjectId().toString() const comment_id = ObjectId().toString() const user_id = ObjectId().toString() @@ -77,7 +77,7 @@ describe('RangeManager', function() { }) }) - it('should leave malformed ObjectIds as they are', function() { + it('should leave malformed ObjectIds as they are', function () { const change_id = 'foo' const comment_id = 'bar' const user_id = 'baz' @@ -112,7 +112,7 @@ describe('RangeManager', function() { }) }) - return it('should be consistent when transformed through json -> mongo -> json', function() { + return it('should be consistent when transformed through json -> mongo -> json', function () { const change_id = ObjectId().toString() const comment_id = ObjectId().toString() const user_id = ObjectId().toString() @@ -144,8 +144,8 @@ describe('RangeManager', function() { }) }) - return describe('shouldUpdateRanges', function() { - beforeEach(function() { + return describe('shouldUpdateRanges', function () { + beforeEach(function () { this.ranges = { changes: [ { @@ -169,16 +169,16 @@ describe('RangeManager', function() { )) }) - describe('with a blank new range', function() { - return it('should throw an error', function() { + describe('with a blank new range', function () { + return it('should throw an error', function () { return expect(() => { return this.RangeManager.shouldUpdateRanges(this.ranges, null) }).to.throw(Error) }) }) - describe('with a blank old range', function() { - return it('should treat it like {}', function() { + describe('with a blank old range', function () { + return it('should treat it like {}', function () { this.RangeManager.shouldUpdateRanges(null, {}).should.equal(false) return this.RangeManager.shouldUpdateRanges( null, @@ -187,8 +187,8 @@ describe('RangeManager', function() { }) }) - describe('with no changes', function() { - return it('should return false', function() { + describe('with no changes', function () { + return it('should return false', function () { return this.RangeManager.shouldUpdateRanges( this.ranges, this.ranges_copy @@ -196,8 +196,8 @@ describe('RangeManager', function() { }) }) - return describe('with changes', function() { - it('should return true when the change id changes', function() { + return describe('with changes', function () { + it('should return true when the change id changes', function () { this.ranges_copy.changes[0].id = ObjectId() return this.RangeManager.shouldUpdateRanges( this.ranges, @@ -205,7 +205,7 @@ describe('RangeManager', function() { ).should.equal(true) }) - it('should return true when the change user id changes', function() { + it('should return true when the change user id changes', function () { this.ranges_copy.changes[0].metadata.user_id = ObjectId() return this.RangeManager.shouldUpdateRanges( this.ranges, @@ -213,7 +213,7 @@ describe('RangeManager', function() { ).should.equal(true) }) - it('should return true when the change ts changes', function() { + it('should return true when the change ts changes', function () { this.ranges_copy.changes[0].metadata.ts = new Date(Date.now() + 1000) return this.RangeManager.shouldUpdateRanges( this.ranges, @@ -221,7 +221,7 @@ describe('RangeManager', function() { ).should.equal(true) }) - it('should return true when the change op changes', function() { + it('should return true when the change op changes', function () { this.ranges_copy.changes[0].op.i = 'bar' return this.RangeManager.shouldUpdateRanges( this.ranges, @@ -229,7 +229,7 @@ describe('RangeManager', function() { ).should.equal(true) }) - it('should return true when the comment id changes', function() { + it('should return true when the comment id changes', function () { this.ranges_copy.comments[0].id = ObjectId() return this.RangeManager.shouldUpdateRanges( this.ranges, @@ -237,7 +237,7 @@ describe('RangeManager', function() { ).should.equal(true) }) - it('should return true when the comment offset changes', function() { + it('should return true when the comment offset changes', function () { this.ranges_copy.comments[0].op.p = 17 return this.RangeManager.shouldUpdateRanges( this.ranges, @@ -245,7 +245,7 @@ describe('RangeManager', function() { ).should.equal(true) }) - return it('should return true when the comment content changes', function() { + return it('should return true when the comment content changes', function () { this.ranges_copy.comments[0].op.c = 'bar' return this.RangeManager.shouldUpdateRanges( this.ranges, From 7585209fb621e1d910ac0d7a6b80ec1dbb5fa74e Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Wed, 3 Jun 2020 10:22:48 +0100 Subject: [PATCH 247/349] update to node 10.21.0 --- services/docstore/.nvmrc | 2 +- services/docstore/Dockerfile | 2 +- services/docstore/docker-compose.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index 5b7269c0a9..b61c07ffdd 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -10.19.0 +10.21.0 diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 4242e7d3be..b07f7117bc 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -2,7 +2,7 @@ # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -FROM node:10.19.0 as base +FROM node:10.21.0 as base WORKDIR /app diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index a1dc328bd3..8dd824af5d 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -6,7 +6,7 @@ version: "2.3" services: test_unit: - image: node:10.19.0 + image: node:10.21.0 volumes: - .:/app working_dir: /app @@ -17,7 +17,7 @@ services: user: node test_acceptance: - image: node:10.19.0 + image: node:10.21.0 volumes: - .:/app working_dir: /app From 960dbc2e8797fb91ef25f7ff9d68b9a506fbc170 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Wed, 3 Jun 2020 11:12:03 +0100 Subject: [PATCH 248/349] update buildscript.txt to node 10.21.0 --- services/docstore/buildscript.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index f57a243595..268fff6941 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -5,6 +5,6 @@ docstore --env-add= --env-pass-through= --language=es ---node-version=10.19.0 +--node-version=10.21.0 --public-repo=True --script-version=2.2.0 From 19177b68dd68a61b433a78746f3d50b3d8d4df8b Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Wed, 1 Jul 2020 15:57:13 +0100 Subject: [PATCH 249/349] Update logger to 2.1.0 --- services/docstore/package-lock.json | 335 ++++++++-------------------- services/docstore/package.json | 2 +- 2 files changed, 96 insertions(+), 241 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 6cb2fd9f34..b69cba7ca3 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -793,9 +793,9 @@ } }, "@grpc/grpc-js": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-0.6.18.tgz", - "integrity": "sha512-uAzv/tM8qpbf1vpx1xPMfcUMzbfdqJtdCYAqY/LsLeQQlnTb4vApylojr+wlCyr7bZeg3AFfHvtihnNOQQt/nA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.0.5.tgz", + "integrity": "sha512-Hm+xOiqAhcpT9RYM8lc15dbQD7aQurM7ZU8ulmulepiPlN7iwBXXwP3vSBUimoFoApRqz7pSIisXU8pZaCB4og==", "requires": { "semver": "^6.2.0" }, @@ -808,9 +808,9 @@ } }, "@grpc/proto-loader": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.3.tgz", - "integrity": "sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.4.tgz", + "integrity": "sha512-HTM4QpI9B2XFkPz7pjwMyMgZchJ93TVkL3kWPW8GDMDKYxsMnmf4w2TNMJK7+KNiYHS5cJrCEAFlF+AwtXWVPA==", "requires": { "lodash.camelcase": "^4.3.0", "protobufjs": "^6.8.6" @@ -832,11 +832,6 @@ "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -848,19 +843,12 @@ "@opencensus/core": "^0.0.20", "hex2dec": "^1.0.1", "uuid": "^3.2.1" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } } }, "@overleaf/o-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@overleaf/o-error/-/o-error-2.1.0.tgz", - "integrity": "sha512-Zd9sks9LrLw8ErHt/cXeWIkyxWAqNAvNGn7wIjLQJH6TTEEW835PWOhpch+hQwwWsTxWIx/JDj+IpZ3ouw925g==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@overleaf/o-error/-/o-error-3.0.0.tgz", + "integrity": "sha512-LsM2s6Iy9G97ktPo0ys4VxtI/m3ahc1ZHwjo5XnhXtjeIkkkVAehsrcRRoV/yWepPjymB0oZonhcfojpjYR/tg==" }, "@protobufjs/aspromise": { "version": "1.1.2", @@ -967,9 +955,9 @@ "dev": true }, "@tootallnate/once": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz", - "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" }, "@types/caseless": { "version": "0.12.2", @@ -1002,9 +990,9 @@ "dev": true }, "@types/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.1.tgz", + "integrity": "sha512-TcUlBem321DFQzBNuz8p0CLLKp0VvF/XH9E4KHNmgwyp4E3AfgI5cjiIVZWlbfThBop2qxFIh4+LeY6hVWWZ2w==", "requires": { "@types/node": "*" } @@ -1158,6 +1146,7 @@ "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -1329,7 +1318,8 @@ "aws4": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "dev": true }, "axios": { "version": "0.18.1", @@ -1385,6 +1375,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -1488,7 +1479,6 @@ "version": "1.8.12", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", - "dev": true, "requires": { "dtrace-provider": "~0.8", "moment": "^2.10.6", @@ -1537,7 +1527,8 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true }, "chai": { "version": "4.2.0", @@ -1797,7 +1788,7 @@ "d64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", - "integrity": "sha512-5eNy3WZziVYnrogqgXhcdEmqcDB2IHurTqLcrgssJsfkMVCUoUaZpK6cJjxxvLV2dUm5SuJMNcYfVGoin9UIRw==" + "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" }, "damerau-levenshtein": { "version": "1.0.6", @@ -1809,6 +1800,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, "requires": { "assert-plus": "^1.0.0" }, @@ -1816,7 +1808,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true } } }, @@ -1923,7 +1916,6 @@ "version": "0.8.8", "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "dev": true, "optional": true, "requires": { "nan": "^2.14.0" @@ -1949,6 +1941,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -2563,13 +2556,6 @@ "requires": { "d64": "^1.0.0", "uuid": "^3.0.1" - }, - "dependencies": { - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } } }, "express": { @@ -2628,12 +2614,14 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", + "dev": true }, "fast-diff": { "version": "1.2.0", @@ -2644,7 +2632,8 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==" + "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", @@ -2917,9 +2906,9 @@ "dev": true }, "gaxios": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.2.tgz", - "integrity": "sha512-K/+py7UvKRDaEwEKlLiRKrFr+wjGjsMz5qH7Vs549QJS7cpSCOT/BbWL7pzqECflc46FcNPipjSfB+V1m8PAhw==", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.4.tgz", + "integrity": "sha512-US8UMj8C5pRnao3Zykc4AAVr+cffoNKRTg9Rsf2GiuZCW69vgJj38VK2PzlPuQU73FZ/nTk9/Av6/JGcE1N9vA==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", @@ -2958,6 +2947,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, "requires": { "assert-plus": "^1.0.0" }, @@ -2965,7 +2955,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true } } }, @@ -3013,11 +3004,11 @@ } }, "google-gax": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-1.15.1.tgz", - "integrity": "sha512-1T1PwSZWnbdRusA+NCZMSe56iU6swGvuZuy54eYl9vEHiRXTLYbQmUkWY2CqgYD9Fd/T4WBkUl22+rZG80unyw==", + "version": "1.15.3", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-1.15.3.tgz", + "integrity": "sha512-3JKJCRumNm3x2EksUTw4P1Rad43FTpqrtW9jzpf3xSMYXx+ogaqTM1vGo7VixHB4xkAyATXVIa3OcNSh8H9zsQ==", "requires": { - "@grpc/grpc-js": "^0.6.18", + "@grpc/grpc-js": "~1.0.3", "@grpc/proto-loader": "^0.5.1", "@types/fs-extra": "^8.0.1", "@types/long": "^4.0.0", @@ -3069,24 +3060,19 @@ "google-p12-pem": "^2.0.0", "jws": "^4.0.0", "mime": "^2.2.0" - }, - "dependencies": { - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" - } } }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -3512,7 +3498,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true }, "isarray": { "version": "1.0.0", @@ -3527,7 +3514,8 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -3656,7 +3644,8 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true }, "jsesc": { "version": "2.5.2", @@ -3679,12 +3668,14 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==" + "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3701,6 +3692,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", + "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -3711,7 +3703,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true } } }, @@ -3798,12 +3791,12 @@ "lodash.at": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha512-GOTh0SEp+Yosnlpjic+8cl2WM9MykorogkGA9xyIFkkObQ3H3kNZqZ+ohuq4K3FrSVo7hMcZBMataJemrxC3BA==" + "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=" }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, "lodash.flattendeep": { "version": "4.4.0", @@ -3819,7 +3812,7 @@ "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==" + "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" }, "lodash.memoize": { "version": "4.1.2", @@ -3859,145 +3852,15 @@ } }, "logger-sharelatex": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-1.9.0.tgz", - "integrity": "sha512-yVTuha82047IiMOQLgQHCZGKkJo6I2+2KtiFKpgkIooR2yZaoTEvAeoMwBesSDSpGUpvUJ/+9UI+PmRyc+PQKQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-2.1.0.tgz", + "integrity": "sha512-WgAABqnBMOv0VAwQJyw+fY4rpqKX+nPJNRydGEYZTo+6lKtJI2TttmZ+Coryg1LEzAjNagxoU78XOHKQvhg7qg==", "requires": { "@google-cloud/logging-bunyan": "^2.0.0", - "@overleaf/o-error": "^2.0.0", + "@overleaf/o-error": "^3.0.0", "bunyan": "1.8.12", "raven": "1.1.3", - "request": "2.88.0", "yn": "^3.1.1" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" - }, - "bunyan": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", - "requires": { - "dtrace-provider": "~0.8", - "moment": "^2.10.6", - "mv": "~2", - "safe-json-stringify": "~1" - } - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "dtrace-provider": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.8.tgz", - "integrity": "sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg==", - "optional": true, - "requires": { - "nan": "^2.14.0" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" - }, - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - } } }, "loglevel": { @@ -4083,7 +3946,7 @@ "lsmod": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", - "integrity": "sha512-Y+6V75r+mGWzWEPr9h6PFmStielICu5JBHLUg18jCsD2VFmEfgHbq/EgnY4inElsUD9eKL9id1qp34w46rSIKQ==" + "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" }, "lynx": { "version": "0.1.1", @@ -4951,7 +4814,8 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true }, "picomatch": { "version": "2.2.2", @@ -5652,7 +5516,8 @@ "psl": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "dev": true }, "pump": { "version": "3.0.0", @@ -5693,27 +5558,9 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } } } }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -5739,7 +5586,7 @@ "raven": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", - "integrity": "sha512-RYov4wAaflZasWiCrZuizd3jNXxCOkW1WrXgWsGVb8kRpdHNZ+vPY27R6RhVtqzWp+DG9a5l6iP0QUPK4EgzaQ==", + "integrity": "sha1-QnPBrm005CMPUbLAEEGjK5Iygio=", "requires": { "cookie": "0.3.1", "json-stringify-safe": "5.0.1", @@ -5751,12 +5598,12 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, "uuid": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", - "integrity": "sha512-rqE1LoOVLv3QrZMjb4NkF5UWlkurCfPyItVnFPNKDDGkHw4dQUdE4zMcLqx28+0Kcf3+bnUk4PisaiRJT4aiaQ==" + "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" } } }, @@ -6246,9 +6093,9 @@ } }, "snakecase-keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-3.1.2.tgz", - "integrity": "sha512-NrzHj8ctStnd1LYx3+L4buS7yildFum7WAbQQxkhPCNi3Qeqv7hoBne2c9n++HWxDG9Nv23pNEyyLCITZTv24Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-3.2.0.tgz", + "integrity": "sha512-WTJ0NhCH/37J+PU3fuz0x5b6TvtWQChTcKPOndWoUy0pteKOe0hrHMzSRsJOWSIP48EQkzUEsgQPmrG3W8pFNQ==", "requires": { "map-obj": "^4.0.0", "to-snake-case": "^1.0.0" @@ -6349,6 +6196,7 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -6365,6 +6213,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -6372,7 +6221,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true } } }, @@ -6504,7 +6354,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { "version": "6.0.0", @@ -6591,9 +6441,9 @@ }, "dependencies": { "uuid": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", - "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==" + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==" } } }, @@ -6746,7 +6596,7 @@ "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" }, "to-regex-range": { "version": "5.0.1", @@ -6760,7 +6610,7 @@ "to-snake-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==", + "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", "requires": { "to-space-case": "^1.0.0" } @@ -6768,7 +6618,7 @@ "to-space-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", "requires": { "to-no-case": "^1.0.0" } @@ -6814,7 +6664,8 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true }, "type-check": { "version": "0.3.2", @@ -6866,6 +6717,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "requires": { "punycode": "^2.1.0" }, @@ -6873,7 +6725,8 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true } } }, @@ -6916,6 +6769,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -6925,7 +6779,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true } } }, diff --git a/services/docstore/package.json b/services/docstore/package.json index 21da419b3c..1ae7da0d9e 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -22,7 +22,7 @@ "async": "^2.6.3", "body-parser": "^1.19.0", "express": "^4.17.1", - "logger-sharelatex": "^1.9.0", + "logger-sharelatex": "^2.1.0", "metrics-sharelatex": "^2.6.2", "mongojs": "3.1.0", "settings-sharelatex": "^1.1.0", From 06ec5556b094acd7f0e5c2c681e6ab92171b5e81 Mon Sep 17 00:00:00 2001 From: Ersun Warncke <ersun.warncke@overleaf.com> Date: Wed, 18 Mar 2020 10:07:01 -0400 Subject: [PATCH 250/349] [misc] fix express deprecations Co-Authored-By: Jakob Ackermann <jakob.ackermann@overleaf.com> --- services/docstore/app.js | 6 ++--- services/docstore/app/js/HttpController.js | 24 +++++++++---------- .../test/unit/js/HttpControllerTests.js | 15 ++++++------ 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index 468dc77983..555f31137b 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -52,7 +52,7 @@ app.post( bodyParser.json({ limit: (Settings.max_doc_length + 64 * 1024) * 2 }), HttpController.updateDoc ) -app.del('/project/:project_id/doc/:doc_id', HttpController.deleteDoc) +app.delete('/project/:project_id/doc/:doc_id', HttpController.deleteDoc) app.post('/project/:project_id/archive', HttpController.archiveAllDocs) app.post('/project/:project_id/unarchive', HttpController.unArchiveAllDocs) @@ -65,9 +65,9 @@ app.get('/status', (req, res) => res.send('docstore is alive')) app.use(function (error, req, res, next) { logger.error({ err: error, req }, 'request errored') if (error instanceof Errors.NotFoundError) { - return res.send(404) + return res.sendStatus(404) } else { - return res.send(500, 'Oops, something went wrong') + return res.status(500).send('Oops, something went wrong') } }) diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 86139e6f45..50c779736c 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -35,9 +35,9 @@ module.exports = HttpController = { } logger.log({ doc_id, project_id }, 'got doc') if (doc == null) { - return res.send(404) + return res.sendStatus(404) } else if (doc.deleted && !include_deleted) { - return res.send(404) + return res.sendStatus(404) } else { return res.json(HttpController._buildDocView(doc)) } @@ -56,7 +56,7 @@ module.exports = HttpController = { return next(error) } if (doc == null) { - return res.send(404) + return res.sendStatus(404) } else { res.setHeader('content-type', 'text/plain') return res.send(HttpController._buildRawDocView(doc)) @@ -118,19 +118,19 @@ module.exports = HttpController = { if (lines == null || !(lines instanceof Array)) { logger.error({ project_id, doc_id }, 'no doc lines provided') - res.send(400) // Bad Request + res.sendStatus(400) // Bad Request return } if (version == null || typeof version === !'number') { logger.error({ project_id, doc_id }, 'no doc version provided') - res.send(400) // Bad Request + res.sendStatus(400) // Bad Request return } if (ranges == null) { logger.error({ project_id, doc_id }, 'no doc ranges provided') - res.send(400) // Bad Request + res.sendStatus(400) // Bad Request return } @@ -174,7 +174,7 @@ module.exports = HttpController = { if (error != null) { return next(error) } - return res.send(204) + return res.sendStatus(204) }) }, @@ -218,7 +218,7 @@ module.exports = HttpController = { if (error != null) { return next(error) } - return res.send(204) + return res.sendStatus(204) }) }, @@ -232,7 +232,7 @@ module.exports = HttpController = { if (error != null) { return next(error) } - return res.send(200) + return res.sendStatus(200) }) }, @@ -246,7 +246,7 @@ module.exports = HttpController = { if (error != null) { return next(error) } - return res.send(204) + return res.sendStatus(204) }) }, @@ -254,9 +254,9 @@ module.exports = HttpController = { return HealthChecker.check(function (err) { if (err != null) { logger.err({ err }, 'error performing health check') - return res.send(500) + return res.sendStatus(500) } else { - return res.send(200) + return res.sendStatus(200) } }) } diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 5463660269..46132737f2 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -37,6 +37,7 @@ describe('HttpController', function () { }) this.res = { send: sinon.stub(), + sendStatus: sinon.stub(), json: sinon.stub(), setHeader: sinon.stub() } @@ -111,7 +112,7 @@ describe('HttpController', function () { it('should return 404 if the query string delete is not set ', function () { this.HttpController.getDoc(this.req, this.res, this.next) - return this.res.send.calledWith(404).should.equal(true) + return this.res.sendStatus.calledWith(404).should.equal(true) }) return it('should return the doc as JSON if include_deleted is set to true', function () { @@ -374,7 +375,7 @@ describe('HttpController', function () { }) return it('should return a 400 (bad request) response', function () { - return this.res.send.calledWith(400).should.equal(true) + return this.res.sendStatus.calledWith(400).should.equal(true) }) }) @@ -390,7 +391,7 @@ describe('HttpController', function () { }) return it('should return a 400 (bad request) response', function () { - return this.res.send.calledWith(400).should.equal(true) + return this.res.sendStatus.calledWith(400).should.equal(true) }) }) @@ -406,7 +407,7 @@ describe('HttpController', function () { }) return it('should return a 400 (bad request) response', function () { - return this.res.send.calledWith(400).should.equal(true) + return this.res.sendStatus.calledWith(400).should.equal(true) }) }) @@ -447,7 +448,7 @@ describe('HttpController', function () { }) return it('should return a 204 (No Content)', function () { - return this.res.send.calledWith(204).should.equal(true) + return this.res.sendStatus.calledWith(204).should.equal(true) }) }) @@ -465,7 +466,7 @@ describe('HttpController', function () { }) return it('should return a 204 (No Content)', function () { - return this.res.send.calledWith(204).should.equal(true) + return this.res.sendStatus.calledWith(204).should.equal(true) }) }) @@ -484,7 +485,7 @@ describe('HttpController', function () { }) return it('should return 204', function () { - return sinon.assert.calledWith(this.res.send, 204) + return sinon.assert.calledWith(this.res.sendStatus, 204) }) }) }) From bd4b9ed1778ba16de6fdd5f40bd44363690c67e6 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 09:23:23 +0100 Subject: [PATCH 251/349] Bump buildscript to 2.3.0 --- services/docstore/.eslintrc | 2 +- services/docstore/buildscript.txt | 2 +- services/docstore/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc index 2e945d6ffb..76dad1561d 100644 --- a/services/docstore/.eslintrc +++ b/services/docstore/.eslintrc @@ -8,7 +8,7 @@ "prettier/standard" ], "parserOptions": { - "ecmaVersion": 2017 + "ecmaVersion": 2018 }, "plugins": [ "mocha", diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 268fff6941..180a47502d 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -7,4 +7,4 @@ docstore --language=es --node-version=10.21.0 --public-repo=True ---script-version=2.2.0 +--script-version=2.3.0 diff --git a/services/docstore/package.json b/services/docstore/package.json index 1ae7da0d9e..455dc14ed7 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -48,7 +48,7 @@ "eslint-plugin-react": "^7.19.0", "eslint-plugin-standard": "^4.0.1", "mocha": "^7.1.1", - "prettier": "^2.0.1", + "prettier": "^2.0.0", "prettier-eslint-cli": "^5.0.0", "request": "~2.88.2", "sandboxed-module": "~2.0.3", From b42a945a1d9536bd479f9c9a26fffdad73b0b6c8 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 09:29:45 +0100 Subject: [PATCH 252/349] Add note on running tests --- services/docstore/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/docstore/README.md b/services/docstore/README.md index 4fccec8d9c..dacfd2873b 100644 --- a/services/docstore/README.md +++ b/services/docstore/README.md @@ -3,7 +3,10 @@ overleaf/docstore A CRUD API for storing and updating text documents in projects - +## Tests +``` +AWS_BUCKET=**** AWS_ACCESS_KEY_ID=**** AWS_SECRET_ACCESS_KEY=**** make test +``` License ------- From 6b92c5d21dd2e4ed5cca2a313fda2fe18691c4ad Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 09:37:48 +0100 Subject: [PATCH 253/349] Move acceptance test cred config to docker-compose-config.yml --- services/docstore/Jenkinsfile | 4 +--- services/docstore/Makefile | 3 --- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose-config.yml | 14 ++++++++++++++ services/docstore/docker-compose.ci.yml | 6 +++--- services/docstore/docker-compose.yml | 6 +++--- 6 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 services/docstore/docker-compose-config.yml diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 95132d21db..15471816e2 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -52,9 +52,7 @@ pipeline { stage('Acceptance Tests') { steps { - withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { - sh 'AWS_BUCKET="sl-acceptance-tests" AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' - } + sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' } } diff --git a/services/docstore/Makefile b/services/docstore/Makefile index f4eab58929..7bd0895b81 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -12,9 +12,6 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ BRANCH_NAME=$(BRANCH_NAME) \ PROJECT_NAME=$(PROJECT_NAME) \ MOCHA_GREP=${MOCHA_GREP} \ - AWS_BUCKET=${AWS_BUCKET} \ - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ docker-compose ${DOCKER_COMPOSE_FLAGS} DOCKER_COMPOSE_TEST_ACCEPTANCE = \ diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 180a47502d..48c7852d74 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,5 +1,5 @@ docstore ---acceptance-creds=aws +--acceptance-creds=None --dependencies=mongo --docker-repos=gcr.io/overleaf-ops --env-add= diff --git a/services/docstore/docker-compose-config.yml b/services/docstore/docker-compose-config.yml new file mode 100644 index 0000000000..b19d02d48e --- /dev/null +++ b/services/docstore/docker-compose-config.yml @@ -0,0 +1,14 @@ +version: "2.3" + +services: + dev: + environment: + - AWS_BUCKET + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY + + ci: + environment: + - AWS_BUCKET + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index bc11cc116a..53da6509c7 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -16,14 +16,14 @@ services: test_acceptance: build: . image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + extends: + file: docker-compose-config.yml + service: ci environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres - AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} - AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test depends_on: diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 8dd824af5d..87ea601dd0 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -21,14 +21,14 @@ services: volumes: - .:/app working_dir: /app + extends: + file: docker-compose-config.yml + service: dev environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres - AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} - AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} LOG_LEVEL: ERROR NODE_ENV: test From e6a2a1922a9cfee2b4a6d1bfdbcf762f5c954332 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 09:58:44 +0100 Subject: [PATCH 254/349] Revert "Move acceptance test cred config to docker-compose-config.yml" This reverts commit e59452567f79540c303b6451638bfe83b294fb79. --- services/docstore/Jenkinsfile | 4 +++- services/docstore/Makefile | 3 +++ services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose-config.yml | 14 -------------- services/docstore/docker-compose.ci.yml | 6 +++--- services/docstore/docker-compose.yml | 6 +++--- 6 files changed, 13 insertions(+), 22 deletions(-) delete mode 100644 services/docstore/docker-compose-config.yml diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 15471816e2..95132d21db 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -52,7 +52,9 @@ pipeline { stage('Acceptance Tests') { steps { - sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' + withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { + sh 'AWS_BUCKET="sl-acceptance-tests" AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' + } } } diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 7bd0895b81..f4eab58929 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -12,6 +12,9 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ BRANCH_NAME=$(BRANCH_NAME) \ PROJECT_NAME=$(PROJECT_NAME) \ MOCHA_GREP=${MOCHA_GREP} \ + AWS_BUCKET=${AWS_BUCKET} \ + AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ + AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ docker-compose ${DOCKER_COMPOSE_FLAGS} DOCKER_COMPOSE_TEST_ACCEPTANCE = \ diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 48c7852d74..180a47502d 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,5 +1,5 @@ docstore ---acceptance-creds=None +--acceptance-creds=aws --dependencies=mongo --docker-repos=gcr.io/overleaf-ops --env-add= diff --git a/services/docstore/docker-compose-config.yml b/services/docstore/docker-compose-config.yml deleted file mode 100644 index b19d02d48e..0000000000 --- a/services/docstore/docker-compose-config.yml +++ /dev/null @@ -1,14 +0,0 @@ -version: "2.3" - -services: - dev: - environment: - - AWS_BUCKET - - AWS_ACCESS_KEY_ID - - AWS_SECRET_ACCESS_KEY - - ci: - environment: - - AWS_BUCKET - - AWS_ACCESS_KEY_ID - - AWS_SECRET_ACCESS_KEY diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 53da6509c7..bc11cc116a 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -16,14 +16,14 @@ services: test_acceptance: build: . image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER - extends: - file: docker-compose-config.yml - service: ci environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} + AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test depends_on: diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 87ea601dd0..8dd824af5d 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -21,14 +21,14 @@ services: volumes: - .:/app working_dir: /app - extends: - file: docker-compose-config.yml - service: dev environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} + AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} LOG_LEVEL: ERROR NODE_ENV: test From 942c4b6fbeb1fff9e2ed40b9a748ced710cb966e Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 09:59:07 +0100 Subject: [PATCH 255/349] Revert "Add note on running tests" This reverts commit 735084fef85f9721849184958b64a50eed65cea0. --- services/docstore/README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/services/docstore/README.md b/services/docstore/README.md index dacfd2873b..4fccec8d9c 100644 --- a/services/docstore/README.md +++ b/services/docstore/README.md @@ -3,10 +3,7 @@ overleaf/docstore A CRUD API for storing and updating text documents in projects -## Tests -``` -AWS_BUCKET=**** AWS_ACCESS_KEY_ID=**** AWS_SECRET_ACCESS_KEY=**** make test -``` + License ------- From d5fba45a2e7363aa8bf125293a2dfb6302f80d83 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 09:59:19 +0100 Subject: [PATCH 256/349] Revert "Bump buildscript to 2.3.0" This reverts commit 57b9d3ef79f0b8bf466cb3a66c27eda92d21c05f. --- services/docstore/.eslintrc | 2 +- services/docstore/buildscript.txt | 2 +- services/docstore/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc index 76dad1561d..2e945d6ffb 100644 --- a/services/docstore/.eslintrc +++ b/services/docstore/.eslintrc @@ -8,7 +8,7 @@ "prettier/standard" ], "parserOptions": { - "ecmaVersion": 2018 + "ecmaVersion": 2017 }, "plugins": [ "mocha", diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 180a47502d..268fff6941 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -7,4 +7,4 @@ docstore --language=es --node-version=10.21.0 --public-repo=True ---script-version=2.3.0 +--script-version=2.2.0 diff --git a/services/docstore/package.json b/services/docstore/package.json index 455dc14ed7..1ae7da0d9e 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -48,7 +48,7 @@ "eslint-plugin-react": "^7.19.0", "eslint-plugin-standard": "^4.0.1", "mocha": "^7.1.1", - "prettier": "^2.0.0", + "prettier": "^2.0.1", "prettier-eslint-cli": "^5.0.0", "request": "~2.88.2", "sandboxed-module": "~2.0.3", From ab6300739166376b74cf31658c843dd7db1b72e7 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 10:02:43 +0100 Subject: [PATCH 257/349] Revert "Revert "Bump buildscript to 2.3.0"" This reverts commit 8f631e450cb17beac28fa6e62303bcb413562c46. --- services/docstore/.eslintrc | 2 +- services/docstore/buildscript.txt | 2 +- services/docstore/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc index 2e945d6ffb..76dad1561d 100644 --- a/services/docstore/.eslintrc +++ b/services/docstore/.eslintrc @@ -8,7 +8,7 @@ "prettier/standard" ], "parserOptions": { - "ecmaVersion": 2017 + "ecmaVersion": 2018 }, "plugins": [ "mocha", diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 268fff6941..180a47502d 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -7,4 +7,4 @@ docstore --language=es --node-version=10.21.0 --public-repo=True ---script-version=2.2.0 +--script-version=2.3.0 diff --git a/services/docstore/package.json b/services/docstore/package.json index 1ae7da0d9e..455dc14ed7 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -48,7 +48,7 @@ "eslint-plugin-react": "^7.19.0", "eslint-plugin-standard": "^4.0.1", "mocha": "^7.1.1", - "prettier": "^2.0.1", + "prettier": "^2.0.0", "prettier-eslint-cli": "^5.0.0", "request": "~2.88.2", "sandboxed-module": "~2.0.3", From 19c871c5f896a95059d66e8902462742f05a375b Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 10:03:14 +0100 Subject: [PATCH 258/349] Revert "Revert "Add note on running tests"" This reverts commit 81fdd6a5d1068cbb9f44adecc399e8871ce99dad. --- services/docstore/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/services/docstore/README.md b/services/docstore/README.md index 4fccec8d9c..dacfd2873b 100644 --- a/services/docstore/README.md +++ b/services/docstore/README.md @@ -3,7 +3,10 @@ overleaf/docstore A CRUD API for storing and updating text documents in projects - +## Tests +``` +AWS_BUCKET=**** AWS_ACCESS_KEY_ID=**** AWS_SECRET_ACCESS_KEY=**** make test +``` License ------- From 4cfeccf5931013a4adc63d61e48126de5906b16e Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Tue, 21 Jul 2020 10:03:34 +0100 Subject: [PATCH 259/349] Revert "Revert "Move acceptance test cred config to docker-compose-config.yml"" This reverts commit 703447d33883b45d119ddccee1df4b9ad098b0c2. --- services/docstore/Jenkinsfile | 4 +--- services/docstore/Makefile | 3 --- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose-config.yml | 14 ++++++++++++++ services/docstore/docker-compose.ci.yml | 6 +++--- services/docstore/docker-compose.yml | 6 +++--- 6 files changed, 22 insertions(+), 13 deletions(-) create mode 100644 services/docstore/docker-compose-config.yml diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile index 95132d21db..15471816e2 100644 --- a/services/docstore/Jenkinsfile +++ b/services/docstore/Jenkinsfile @@ -52,9 +52,7 @@ pipeline { stage('Acceptance Tests') { steps { - withCredentials([usernamePassword(credentialsId: 'S3_DOCSTORE_TEST_AWS_KEYS', passwordVariable: 'AWS_SECRET_ACCESS_KEY', usernameVariable: 'AWS_ACCESS_KEY_ID')]) { - sh 'AWS_BUCKET="sl-acceptance-tests" AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' - } + sh 'DOCKER_COMPOSE_FLAGS="-f docker-compose.ci.yml" make test_acceptance' } } diff --git a/services/docstore/Makefile b/services/docstore/Makefile index f4eab58929..7bd0895b81 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -12,9 +12,6 @@ DOCKER_COMPOSE := BUILD_NUMBER=$(BUILD_NUMBER) \ BRANCH_NAME=$(BRANCH_NAME) \ PROJECT_NAME=$(PROJECT_NAME) \ MOCHA_GREP=${MOCHA_GREP} \ - AWS_BUCKET=${AWS_BUCKET} \ - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} \ - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} \ docker-compose ${DOCKER_COMPOSE_FLAGS} DOCKER_COMPOSE_TEST_ACCEPTANCE = \ diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 180a47502d..48c7852d74 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,5 +1,5 @@ docstore ---acceptance-creds=aws +--acceptance-creds=None --dependencies=mongo --docker-repos=gcr.io/overleaf-ops --env-add= diff --git a/services/docstore/docker-compose-config.yml b/services/docstore/docker-compose-config.yml new file mode 100644 index 0000000000..b19d02d48e --- /dev/null +++ b/services/docstore/docker-compose-config.yml @@ -0,0 +1,14 @@ +version: "2.3" + +services: + dev: + environment: + - AWS_BUCKET + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY + + ci: + environment: + - AWS_BUCKET + - AWS_ACCESS_KEY_ID + - AWS_SECRET_ACCESS_KEY diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index bc11cc116a..53da6509c7 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -16,14 +16,14 @@ services: test_acceptance: build: . image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + extends: + file: docker-compose-config.yml + service: ci environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres - AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} - AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test depends_on: diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 8dd824af5d..87ea601dd0 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -21,14 +21,14 @@ services: volumes: - .:/app working_dir: /app + extends: + file: docker-compose-config.yml + service: dev environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres - AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} - AWS_BUCKET: ${AWS_BUCKET} MOCHA_GREP: ${MOCHA_GREP} LOG_LEVEL: ERROR NODE_ENV: test From 99a3266105f2e21c18bcefd0706837315798a6cc Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 23 Jul 2020 19:29:25 +0100 Subject: [PATCH 260/349] Add object-persistor module and upgrade deps to latest minor release --- services/docstore/package-lock.json | 1492 +++++++++++++++++++++------ services/docstore/package.json | 40 +- 2 files changed, 1173 insertions(+), 359 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index b69cba7ca3..636c1cf390 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -77,30 +77,22 @@ "integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==" }, "@babel/runtime": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.4.tgz", - "integrity": "sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.5.tgz", + "integrity": "sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.2" + "regenerator-runtime": "^0.13.4" } }, "@babel/runtime-corejs3": { - "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.9.2.tgz", - "integrity": "sha512-HHxmgxbIzOfFlZ+tdeRKtaxWOMUoCG5Mu3wKeUmOxjYrwb3AAHgnmtCUbPPK11/raIWLIBK250t8E2BPO0p7jA==", + "version": "7.10.5", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.5.tgz", + "integrity": "sha512-RMafpmrNB5E/bwdSphLr8a8++9TosnyJp98RZzI6VOx2R2CCMpsXXXRvmI700O9oEKpXdZat6oEK68/F0zjd4A==", "dev": true, "requires": { "core-js-pure": "^3.0.0", "regenerator-runtime": "^0.13.4" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", - "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", - "dev": true - } } }, "@babel/template": { @@ -168,6 +160,24 @@ "google-auth-library": "^5.5.0", "retry-request": "^4.0.0", "teeny-request": "^6.0.0" + }, + "dependencies": { + "google-auth-library": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.10.1.tgz", + "integrity": "sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^2.1.0", + "gcp-metadata": "^3.4.0", + "gtoken": "^4.1.0", + "jws": "^4.0.0", + "lru-cache": "^5.0.0" + } + } } }, "@google-cloud/debug-agent": { @@ -385,6 +395,22 @@ "type-fest": "^0.12.0" }, "dependencies": { + "google-auth-library": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.10.1.tgz", + "integrity": "sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^2.1.0", + "gcp-metadata": "^3.4.0", + "gtoken": "^4.1.0", + "jws": "^4.0.0", + "lru-cache": "^5.0.0" + } + }, "type-fest": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.12.0.tgz", @@ -393,12 +419,12 @@ } }, "@google-cloud/logging-bunyan": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/logging-bunyan/-/logging-bunyan-2.0.3.tgz", - "integrity": "sha512-8n9MwsCRd4v8WZg17+d3m7qInud7lYTm5rpwXHY0/lzWEJYjeiztT09BiCYh56EEhHr+ynymJnzUDZKazkywlg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@google-cloud/logging-bunyan/-/logging-bunyan-3.0.0.tgz", + "integrity": "sha512-ZLVXEejNQ27ktGcA3S/sd7GPefp7kywbn+/KoBajdb1Syqcmtc98jhXpYQBXVtNP2065iyu77s4SBaiYFbTC5A==", "requires": { "@google-cloud/logging": "^7.0.0", - "google-auth-library": "^5.0.0" + "google-auth-library": "^6.0.0" } }, "@google-cloud/paginator": { @@ -461,6 +487,11 @@ "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz", "integrity": "sha512-QzB0/IMvB0eFxFK7Eqh+bfC8NLv3E9ScjWQrPOk6GgfNroxcVITdTlT8NRsRrcp5+QQJVPLkRqKG0PUdaWXmHw==" }, + "@types/node": { + "version": "10.17.26", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.26.tgz", + "integrity": "sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw==" + }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -587,6 +618,26 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" }, + "protobufjs": { + "version": "6.8.9", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.9.tgz", + "integrity": "sha512-j2JlRdUeL/f4Z6x4aU4gj9I2LECglC+5qR2TrWb193Tla1qfdaNQTZ8I27Pt7K0Ajmvjjpft7O3KWTGciz4gpw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + } + }, "teeny-request": { "version": "3.11.3", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", @@ -609,6 +660,152 @@ "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-1.0.4.tgz", "integrity": "sha512-VccZDcOql77obTnFh0TbNED/6ZbbmHDf8UMNnzO1d5g9V0Htfm4k5cllY8P1tJsRKC3zWYGRLaViiupcgVjBoQ==" }, + "@google-cloud/storage": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.1.2.tgz", + "integrity": "sha512-j2blsBVv6Tt5Z7ff6kOSIg5zVQPdlcTQh/4zMb9h7xMj4ekwndQA60le8c1KEa+Y6SR3EM6ER2AvKYK53P7vdQ==", + "dev": true, + "requires": { + "@google-cloud/common": "^3.0.0", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.0", + "compressible": "^2.0.12", + "concat-stream": "^2.0.0", + "date-and-time": "^0.13.0", + "duplexify": "^3.5.0", + "extend": "^3.0.2", + "gaxios": "^3.0.0", + "gcs-resumable-upload": "^3.0.0", + "hash-stream-validation": "^0.2.2", + "mime": "^2.2.0", + "mime-types": "^2.0.8", + "onetime": "^5.1.0", + "p-limit": "^3.0.1", + "pumpify": "^2.0.0", + "readable-stream": "^3.4.0", + "snakeize": "^0.1.0", + "stream-events": "^1.0.1", + "through2": "^4.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "@google-cloud/common": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.3.2.tgz", + "integrity": "sha512-W7JRLBEJWYtZQQuGQX06U6GBOSLrSrlvZxv6kGNwJtFrusu6AVgZltQ9Pajuz9Dh9aSXy9aTnBcyxn2/O0EGUw==", + "dev": true, + "requires": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^6.0.0", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "dev": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + } + } + }, + "@google-cloud/paginator": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.2.tgz", + "integrity": "sha512-kXK+Dbz4pNvv8bKU80Aw5HsIdgOe0WuMTd8/fI6tkANUxzvJOVJQQRsWVqcHSWK2RXHPTA9WBniUCwY6gAJDXw==", + "dev": true, + "requires": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + } + }, + "@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", + "dev": true + }, + "@google-cloud/promisify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.2.tgz", + "integrity": "sha512-EvuabjzzZ9E2+OaYf+7P9OAiiwbTxKYL0oGLnREQd+Su2NTQBpomkdlkBowFvyWsaV0d1sSGxrKpSNcrhPqbxg==", + "dev": true + }, + "gaxios": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.4.tgz", + "integrity": "sha512-97NmFuMETFQh6gqPUxkqjxRMjmY8aRKRMphIkgO/b90AbCt5wAVuXsp8oWjIXlLN2pIK/fsXD8edcM7ULkFMLg==", + "dev": true, + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "teeny-request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.0.tgz", + "integrity": "sha512-kWD3sdGmIix6w7c8ZdVKxWq+3YwVPGWz+Mq0wRZXayEKY/YHb63b8uphfBzcFDmyq8frD9+UTc3wLyOhltRbtg==", + "dev": true, + "requires": { + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.2.0", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + }, + "uuid": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", + "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==", + "dev": true + } + } + }, "@google-cloud/trace-agent": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.6.1.tgz", @@ -850,6 +1047,175 @@ "resolved": "https://registry.npmjs.org/@overleaf/o-error/-/o-error-3.0.0.tgz", "integrity": "sha512-LsM2s6Iy9G97ktPo0ys4VxtI/m3ahc1ZHwjo5XnhXtjeIkkkVAehsrcRRoV/yWepPjymB0oZonhcfojpjYR/tg==" }, + "@overleaf/object-persistor": { + "version": "git+https://github.com/overleaf/object-persistor.git#8b8bc4b8d1e8b8aa3ca9245691d6ddd69d663d06", + "from": "git+https://github.com/overleaf/object-persistor.git", + "requires": { + "@google-cloud/storage": "^5.1.2", + "@overleaf/o-error": "^3.0.0", + "aws-sdk": "^2.718.0", + "fast-crc32c": "^2.0.0", + "glob": "^7.1.6", + "logger-sharelatex": "^2.1.1", + "node-uuid": "^1.4.8", + "range-parser": "^1.2.1", + "tiny-async-pool": "^1.1.0" + }, + "dependencies": { + "@google-cloud/common": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.3.2.tgz", + "integrity": "sha512-W7JRLBEJWYtZQQuGQX06U6GBOSLrSrlvZxv6kGNwJtFrusu6AVgZltQ9Pajuz9Dh9aSXy9aTnBcyxn2/O0EGUw==", + "requires": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^6.0.0", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + } + } + }, + "@google-cloud/paginator": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.2.tgz", + "integrity": "sha512-kXK+Dbz4pNvv8bKU80Aw5HsIdgOe0WuMTd8/fI6tkANUxzvJOVJQQRsWVqcHSWK2RXHPTA9WBniUCwY6gAJDXw==", + "requires": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + } + }, + "@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" + }, + "@google-cloud/promisify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.2.tgz", + "integrity": "sha512-EvuabjzzZ9E2+OaYf+7P9OAiiwbTxKYL0oGLnREQd+Su2NTQBpomkdlkBowFvyWsaV0d1sSGxrKpSNcrhPqbxg==" + }, + "@google-cloud/storage": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.1.2.tgz", + "integrity": "sha512-j2blsBVv6Tt5Z7ff6kOSIg5zVQPdlcTQh/4zMb9h7xMj4ekwndQA60le8c1KEa+Y6SR3EM6ER2AvKYK53P7vdQ==", + "requires": { + "@google-cloud/common": "^3.0.0", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.0", + "compressible": "^2.0.12", + "concat-stream": "^2.0.0", + "date-and-time": "^0.13.0", + "duplexify": "^3.5.0", + "extend": "^3.0.2", + "gaxios": "^3.0.0", + "gcs-resumable-upload": "^3.0.0", + "hash-stream-validation": "^0.2.2", + "mime": "^2.2.0", + "mime-types": "^2.0.8", + "onetime": "^5.1.0", + "p-limit": "^3.0.1", + "pumpify": "^2.0.0", + "readable-stream": "^3.4.0", + "snakeize": "^0.1.0", + "stream-events": "^1.0.1", + "through2": "^4.0.0", + "xdg-basedir": "^4.0.0" + } + }, + "gaxios": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.4.tgz", + "integrity": "sha512-97NmFuMETFQh6gqPUxkqjxRMjmY8aRKRMphIkgO/b90AbCt5wAVuXsp8oWjIXlLN2pIK/fsXD8edcM7ULkFMLg==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==" + }, + "p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "requires": { + "p-try": "^2.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "teeny-request": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.0.tgz", + "integrity": "sha512-kWD3sdGmIix6w7c8ZdVKxWq+3YwVPGWz+Mq0wRZXayEKY/YHb63b8uphfBzcFDmyq8frD9+UTc3wLyOhltRbtg==", + "requires": { + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.2.0", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" + }, + "dependencies": { + "uuid": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", + "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" + } + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "requires": { + "readable-stream": "3" + } + } + } + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -910,18 +1276,18 @@ "integrity": "sha512-lu8BpxjAtRCAo5ifytTpCPCj99LF7o/2Myn+NXyNCBqvPYn7Pjd76AMmUB5l7XF1U6t0hcWrlEM5ESufW7wAeA==" }, "@sinonjs/commons": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", - "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/fake-timers": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.0.tgz", - "integrity": "sha512-atR1J/jRXvQAb47gfzSK8zavXy7BcpnYq21ALon0U99etu99vsir0trzIO3wpeLtW+LLVY6X7EkfVTbjGSH8Ww==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" @@ -1003,20 +1369,26 @@ "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "@types/long": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" }, "@types/node": { - "version": "10.17.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.17.tgz", - "integrity": "sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q==" + "version": "13.13.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.13.tgz", + "integrity": "sha512-UfvBE9oRCAJVzfR+3eWm/sdLFe/qroAPEXP3GPJ1SehQiEVgZT6NQZWYbPMiJ3UdcKM06v4j+S1lTcdWCmw+3g==" }, "@types/request": { - "version": "2.48.4", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz", - "integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==", + "version": "2.48.5", + "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz", + "integrity": "sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==", "requires": { "@types/caseless": "*", "@types/node": "*", @@ -1042,9 +1414,9 @@ "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" }, "@types/tough-cookie": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz", - "integrity": "sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==" }, "@typescript-eslint/experimental-utils": { "version": "1.13.0", @@ -1223,13 +1595,13 @@ } }, "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha512-majUxHgLehQTeSA+hClx+DY09OVUqG3GtezWkF1krgLGNdlDu9l9V8DaqNMWbq4Eddc8wsyDA0hpDUtnYxQEXw==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", "dev": true, "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" } }, "array-flatten": { @@ -1258,6 +1630,17 @@ "es-abstract": "^1.17.0-next.1" } }, + "array.prototype.flatmap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", + "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1" + } + }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", @@ -1278,7 +1661,7 @@ "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", "dev": true }, "astral-regex": { @@ -1309,6 +1692,29 @@ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, + "aws-sdk": { + "version": "2.718.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.718.0.tgz", + "integrity": "sha512-YMWR1RJ3VuSbUOGeOfDw2QqRzwX51oa9TCm2G6SW+JywJUy0FTxi/Nj0VjVEQvKC0GqGu5QCgUTaarF7S0nQdw==", + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + } + } + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -1321,6 +1727,12 @@ "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, + "axe-core": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz", + "integrity": "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==", + "dev": true + }, "axios": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", @@ -1331,9 +1743,9 @@ } }, "axobject-query": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.1.2.tgz", - "integrity": "sha512-ICt34ZmrVt8UQnvPl6TVyDTkmhXmAyAT4Jh5ugfGUX4MOrZ+U/ZY6/sdylRw3qGNr9Ub5AJsaHeDMzNLehRdOQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", "dev": true }, "babel-eslint": { @@ -1386,9 +1798,9 @@ "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" }, "binary-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", - "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", "dev": true }, "bindings": { @@ -1465,23 +1877,39 @@ "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, "builtin-modules": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" }, "bunyan": { - "version": "1.8.12", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz", - "integrity": "sha512-dmDUbGHeGcvCDLRFOscZkwx1ZO/aFz3bJOCi5nCgzdhFGPxwK+y5AcDBnqagNGlJZ7lje/l6JUEz9mQcutttdg==", + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.14.tgz", + "integrity": "sha512-LlahJUxXzZLuw/hetUQJmRgZ1LF6+cr5TPpRj6jf327AsiIq2jhYEH4oqUUkVKTor+9w2BT3oxVwhzE5lw9tcg==", + "dev": true, "requires": { "dtrace-provider": "~0.8", - "moment": "^2.10.6", + "moment": "^2.19.3", "mv": "~2", "safe-json-stringify": "~1" } @@ -1544,6 +1972,15 @@ "type-detect": "^4.0.5" } }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1575,6 +2012,11 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -1670,12 +2112,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, "common-tags": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", @@ -1687,11 +2123,88 @@ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "requires": { + "mime-db": ">= 1.43.0 < 2" + }, + "dependencies": { + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + } + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "configstore": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", + "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", + "requires": { + "dot-prop": "^5.2.0", + "graceful-fs": "^4.1.2", + "make-dir": "^3.0.0", + "unique-string": "^2.0.0", + "write-file-atomic": "^3.0.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } + } + }, "console-log-level": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", @@ -1700,7 +2213,7 @@ "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, "content-disposition": { @@ -1750,9 +2263,9 @@ "dev": true }, "core-js-pure": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.4.tgz", - "integrity": "sha512-epIhRLkXdgv32xIUFaaAry2wdxZYBi6bgM7cB136dzzXXa+dFyRLTZeLUJxnd8ShrmyVXBub63n2NHo2JAt8Cw==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", "dev": true }, "core-util-is": { @@ -1785,10 +2298,20 @@ "which": "^1.2.9" } }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" + }, + "crypto-random-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==" + }, "d64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", - "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" + "integrity": "sha512-5eNy3WZziVYnrogqgXhcdEmqcDB2IHurTqLcrgssJsfkMVCUoUaZpK6cJjxxvLV2dUm5SuJMNcYfVGoin9UIRw==" }, "damerau-levenshtein": { "version": "1.0.6", @@ -1813,6 +2336,11 @@ } } }, + "date-and-time": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-0.13.1.tgz", + "integrity": "sha512-/Uge9DJAT+s+oAcDxtBhyR8+sKjUnZbYmyhbmWjTHNtX7B7oWD8YyYdeXcBRbwSj6hVvj+IQegJam7m7czhbFw==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -2001,22 +2529,22 @@ } }, "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" } }, "es-to-primitive": { @@ -2136,9 +2664,9 @@ } }, "eslint-config-prettier": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz", - "integrity": "sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", "dev": true, "requires": { "get-stdin": "^6.0.0" @@ -2166,28 +2694,19 @@ } }, "eslint-import-resolver-node": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", - "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", "dev": true, "requires": { "debug": "^2.6.9", "resolve": "^1.13.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -2196,42 +2715,31 @@ } }, "eslint-module-utils": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", - "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", "dev": true, "requires": { "debug": "^2.6.9", "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } } }, "eslint-plugin-chai-expect": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.1.0.tgz", - "integrity": "sha512-rd0/4mjMV6c3i0o4DKkWI4uaFN9DK707kW+/fDphaDI6HVgxXnhML9Xgt5vHnTXmSSnDhupuCFBgsEAEpchXmQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-chai-expect/-/eslint-plugin-chai-expect-2.2.0.tgz", + "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", "dev": true }, "eslint-plugin-chai-friendly": { - "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==", + "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==", "dev": true }, "eslint-plugin-es": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz", - "integrity": "sha512-6/Jb/J/ZvSebydwbBJO1R9E5ky7YeElfK56Veh7e4QGFHCXoIXGH9HhVz+ibJLM3XJ1XjP+T7rKBLUa/Y7eIng==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", "dev": true, "requires": { "eslint-utils": "^2.0.0", @@ -2239,55 +2747,47 @@ }, "dependencies": { "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "regexpp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", - "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true } } }, "eslint-plugin-import": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", - "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "version": "2.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz", + "integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==", "dev": true, "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", "contains-path": "^0.1.0", "debug": "^2.6.9", "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", + "eslint-import-resolver-node": "^0.3.3", + "eslint-module-utils": "^2.6.0", "has": "^1.0.3", "minimatch": "^3.0.4", - "object.values": "^1.1.0", + "object.values": "^1.1.1", "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { "esutils": "^2.0.2", @@ -2295,9 +2795,9 @@ } }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -2306,26 +2806,28 @@ } }, "eslint-plugin-jsx-a11y": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", - "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz", + "integrity": "sha512-i1S+P+c3HOlBJzMFORRbC58tHa65Kbo8b52/TwCwSKLohwvpfT5rm2GjGWzOHTEuq4xxf2aRlHHTtmExDQOP+g==", "dev": true, "requires": { - "@babel/runtime": "^7.4.5", - "aria-query": "^3.0.0", - "array-includes": "^3.0.3", + "@babel/runtime": "^7.10.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", "ast-types-flow": "^0.0.7", - "axobject-query": "^2.0.2", - "damerau-levenshtein": "^1.0.4", - "emoji-regex": "^7.0.2", + "axe-core": "^3.5.4", + "axobject-query": "^2.1.2", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.2.1" + "jsx-ast-utils": "^2.4.1", + "language-tags": "^1.0.5" }, "dependencies": { "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.0.0.tgz", + "integrity": "sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==", "dev": true } } @@ -2352,9 +2854,9 @@ } }, "eslint-plugin-node": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.0.0.tgz", - "integrity": "sha512-chUs/NVID+sknFiJzxoN9lM7uKSOEta8GC8365hw1nDfwIPIjjpRSwwPvQanWv8dt/pDe9EV4anmVSwdiSndNg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", "dev": true, "requires": { "eslint-plugin-es": "^3.0.0", @@ -2366,18 +2868,18 @@ }, "dependencies": { "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, "semver": { @@ -2389,9 +2891,9 @@ } }, "eslint-plugin-prettier": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz", - "integrity": "sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", "dev": true, "requires": { "prettier-linter-helpers": "^1.0.0" @@ -2404,23 +2906,22 @@ "dev": true }, "eslint-plugin-react": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.19.0.tgz", - "integrity": "sha512-SPT8j72CGuAP+JFbT0sJHOB80TX/pu44gQ4vXH/cq+hQTiY2PuZ6IHkqXJV6x1b28GDdo1lbInjKUrrdUf0LOQ==", + "version": "7.20.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz", + "integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==", "dev": true, "requires": { "array-includes": "^3.1.1", + "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.2.3", - "object.entries": "^1.1.1", + "jsx-ast-utils": "^2.4.1", + "object.entries": "^1.1.2", "object.fromentries": "^2.0.2", "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.15.1", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.2", - "xregexp": "^4.3.0" + "resolve": "^1.17.0", + "string.prototype.matchall": "^4.0.2" }, "dependencies": { "doctrine": { @@ -2433,19 +2934,13 @@ } }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true } } }, @@ -2558,6 +3053,11 @@ "uuid": "^3.0.1" } }, + "events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==" + }, "express": { "version": "4.17.1", "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", @@ -2617,6 +3117,14 @@ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true }, + "fast-crc32c": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-crc32c/-/fast-crc32c-2.0.0.tgz", + "integrity": "sha512-LIREwygxtxzHF11oLJ4xIVKu/ZWNgrj/QaGvaSD8ZggIsgCyCtSYevlrpWVqNau57ZwezV8K1HFBSjQ7FcRbTQ==", + "requires": { + "sse4_crc32": "^6.0.1" + } + }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", @@ -2740,7 +3248,7 @@ "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -2887,9 +3395,9 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, "optional": true }, @@ -2926,6 +3434,34 @@ "json-bigint": "^0.3.0" } }, + "gcs-resumable-upload": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.1.0.tgz", + "integrity": "sha512-gB8xH6EjYCv9lfBEL4FK5+AMgTY0feYoNHAYOV5nCuOrDPhy5MOiyJE8WosgxhbKBPS361H7fkwv6CTufEh9bg==", + "requires": { + "abort-controller": "^3.0.0", + "configstore": "^5.0.0", + "extend": "^3.0.2", + "gaxios": "^3.0.0", + "google-auth-library": "^6.0.0", + "pumpify": "^2.0.0", + "stream-events": "^1.0.4" + }, + "dependencies": { + "gaxios": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.3.tgz", + "integrity": "sha512-PkzQludeIFhd535/yucALT/Wxyj/y2zLyrMwPcJmnLHDugmV49NvAi/vb+VUq/eWztATZCNcb8ue+ywPG+oLuw==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + } + } + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2988,19 +3524,61 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, "google-auth-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.10.1.tgz", - "integrity": "sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.0.3.tgz", + "integrity": "sha512-2Np6ojPmaJGXHSMsBhtTQEKfSMdLc8hefoihv7N2cwEr8E5bq39fhoat6TcXHwa0XoGO5Guh9sp3nxHFPmibMw==", "requires": { "arrify": "^2.0.0", "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "fast-text-encoding": "^1.0.0", - "gaxios": "^2.1.0", - "gcp-metadata": "^3.4.0", - "gtoken": "^4.1.0", + "gaxios": "^3.0.0", + "gcp-metadata": "^4.1.0", + "gtoken": "^5.0.0", "jws": "^4.0.0", "lru-cache": "^5.0.0" + }, + "dependencies": { + "gaxios": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.3.tgz", + "integrity": "sha512-PkzQludeIFhd535/yucALT/Wxyj/y2zLyrMwPcJmnLHDugmV49NvAi/vb+VUq/eWztATZCNcb8ue+ywPG+oLuw==", + "requires": { + "abort-controller": "^3.0.0", + "extend": "^3.0.2", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", + "node-fetch": "^2.3.0" + } + }, + "gcp-metadata": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.1.0.tgz", + "integrity": "sha512-r57SV28+olVsflPlKyVig3Muo/VDlcsObMtvDGOEtEJXj+DDE8bEl0coIkXh//hbkSDTvo+f5lbihZOndYXQQQ==", + "requires": { + "gaxios": "^3.0.0", + "json-bigint": "^0.3.0" + } + }, + "google-p12-pem": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.1.tgz", + "integrity": "sha512-VlQgtozgNVVVcYTXS36eQz4PXPt9gIPqLOhHN0QiV6W6h4qSCNVKPtKC5INtJsaHHF2r7+nOIa26MJeJMTaZEQ==", + "requires": { + "node-forge": "^0.9.0" + } + }, + "gtoken": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.1.tgz", + "integrity": "sha512-33w4FNDkUcyIOq/TqyC+drnKdI4PdXmWp9lZzssyEQKuvu9ZFN3KttaSnDKo52U3E51oujVGop93mKxmqO8HHg==", + "requires": { + "gaxios": "^3.0.0", + "google-p12-pem": "^3.0.0", + "jws": "^4.0.0", + "mime": "^2.2.0" + } + } } }, "google-gax": { @@ -3025,6 +3603,22 @@ "walkdir": "^0.4.0" }, "dependencies": { + "google-auth-library": { + "version": "5.10.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.10.1.tgz", + "integrity": "sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^2.1.0", + "gcp-metadata": "^3.4.0", + "gtoken": "^4.1.0", + "jws": "^4.0.0", + "lru-cache": "^5.0.0" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -3115,6 +3709,25 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, + "hash-stream-validation": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.3.tgz", + "integrity": "sha512-OEohGLoUOh+bwsIpHpdvhIXFyRGjeLqJbT8Yc5QTZPbRM7LKywagTQxnX/6mghLDOrD9YGz88hy5mLN2eKflYQ==", + "requires": { + "through2": "^2.0.0" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", @@ -3231,6 +3844,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -3412,9 +4030,9 @@ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, "is-date-object": { @@ -3462,12 +4080,12 @@ "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", "dev": true, "requires": { - "has": "^1.0.3" + "has-symbols": "^1.0.1" } }, "is-stream": { @@ -3498,8 +4116,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "isarray": { "version": "1.0.0", @@ -3627,6 +4244,11 @@ "html-escaper": "^2.0.0" } }, + "jmespath": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", + "integrity": "sha512-+kHj8HXArPfpPEKGLZ+kB5ONRTCiGQXo8RQYL0hH8t6pWXUBBK5KkkQmTNOwKK4LEsd0yTsgtjJVm4UBSZea4w==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3686,7 +4308,17 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } }, "jsprim": { "version": "1.4.1", @@ -3709,12 +4341,12 @@ } }, "jsx-ast-utils": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz", - "integrity": "sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", + "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", "dev": true, "requires": { - "array-includes": "^3.0.3", + "array-includes": "^3.1.1", "object.assign": "^4.1.0" } }, @@ -3743,6 +4375,21 @@ "safe-buffer": "^5.0.1" } }, + "language-subtag-registry": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz", + "integrity": "sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -3756,7 +4403,7 @@ "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -3768,7 +4415,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } @@ -3776,7 +4423,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -3784,19 +4431,19 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash.at": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=" + "integrity": "sha512-GOTh0SEp+Yosnlpjic+8cl2WM9MykorogkGA9xyIFkkObQ3H3kNZqZ+ohuq4K3FrSVo7hMcZBMataJemrxC3BA==" }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, "lodash.flattendeep": { "version": "4.4.0", @@ -3806,13 +4453,13 @@ "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", "dev": true }, "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" + "integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==" }, "lodash.memoize": { "version": "4.1.2", @@ -3852,15 +4499,28 @@ } }, "logger-sharelatex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-2.1.0.tgz", - "integrity": "sha512-WgAABqnBMOv0VAwQJyw+fY4rpqKX+nPJNRydGEYZTo+6lKtJI2TttmZ+Coryg1LEzAjNagxoU78XOHKQvhg7qg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-2.1.1.tgz", + "integrity": "sha512-qqSrBqUgHWnStxtTZ/fSsqPxj9Ju9onok7Vfm3bv5MS702jH+hRsCSA9oXOMvOLcWJrZFnhCZaLGeOvXToUaxw==", "requires": { - "@google-cloud/logging-bunyan": "^2.0.0", + "@google-cloud/logging-bunyan": "^3.0.0", "@overleaf/o-error": "^3.0.0", - "bunyan": "1.8.12", - "raven": "1.1.3", - "yn": "^3.1.1" + "bunyan": "^1.8.14", + "raven": "^2.6.4", + "yn": "^4.0.0" + }, + "dependencies": { + "bunyan": { + "version": "1.8.14", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.14.tgz", + "integrity": "sha512-LlahJUxXzZLuw/hetUQJmRgZ1LF6+cr5TPpRj6jf327AsiIq2jhYEH4oqUUkVKTor+9w2BT3oxVwhzE5lw9tcg==", + "requires": { + "dtrace-provider": "~0.8", + "moment": "^2.19.3", + "mv": "~2", + "safe-json-stringify": "~1" + } + } } }, "loglevel": { @@ -3943,11 +4603,6 @@ "yallist": "^3.0.2" } }, - "lsmod": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lsmod/-/lsmod-1.0.0.tgz", - "integrity": "sha1-mgD3bco26yP6BTUK/htYXUKZ5ks=" - }, "lynx": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", @@ -3996,6 +4651,23 @@ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==" }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ==", + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + }, + "dependencies": { + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + } + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -4054,9 +4726,9 @@ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, "metrics-sharelatex": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.6.2.tgz", - "integrity": "sha512-bOLfkSCexiPgB96hdXhoOWyvvrwscgjeZPEqdcJ7BTGxY59anzvymNf5hTGJ1RtS4sblDKxITw3L5a+gYKhRYQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.7.0.tgz", + "integrity": "sha512-fv7TsM2pVhY/VuHqP5p9Ip2BhHfGPrP0e2TuZGCMK9/J83ZuGCrxkpaU3OOz31CWcmcQ5am4Du70EZAaIdA/2A==", "requires": { "@google-cloud/debug-agent": "^3.0.0", "@google-cloud/profiler": "^0.2.3", @@ -4072,6 +4744,11 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", "integrity": "sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" } } }, @@ -4096,8 +4773,7 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "minimatch": { "version": "3.0.4", @@ -4107,6 +4783,12 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, "mkdirp": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz", @@ -4123,9 +4805,9 @@ } }, "mocha": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.1.tgz", - "integrity": "sha512-3qQsu3ijNS3GkWcccT5Zw0hf/rWvu1fTN9sPvEd81hlwsr30GX2GcDSSoBxo24IR8FelmrAydGC6/1J5QQP4WA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", + "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", "dev": true, "requires": { "ansi-colors": "3.2.3", @@ -4141,7 +4823,7 @@ "js-yaml": "3.13.1", "log-symbols": "3.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.3", + "mkdirp": "0.5.5", "ms": "2.1.1", "node-environment-flags": "1.0.6", "object.assign": "4.1.0", @@ -4195,7 +4877,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "locate-path": { @@ -4208,6 +4890,15 @@ "path-exists": "^3.0.0" } }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", @@ -4237,7 +4928,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "yargs": { @@ -4257,16 +4948,6 @@ "y18n": "^4.0.0", "yargs-parser": "^13.1.2" } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } } } }, @@ -4377,9 +5058,9 @@ "dev": true }, "nise": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.3.tgz", - "integrity": "sha512-EGlhjm7/4KvmmE6B/UFsKh7eHykRl9VH+au8dduHLCyWUO/hr7+N+WtTvDUwc9zHuM1IaIJs/0lQ6Ag1jDkQSg==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", + "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", @@ -4392,7 +5073,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, "path-to-regexp": { @@ -4406,6 +5087,12 @@ } } }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "optional": true + }, "node-environment-flags": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", @@ -4545,13 +5232,13 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", + "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", "dev": true }, "object-keys": { @@ -4573,14 +5260,13 @@ } }, "object.entries": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", - "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", "dev": true, "requires": { "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", + "es-abstract": "^1.17.5", "has": "^1.0.3" } }, @@ -4638,7 +5324,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -4679,7 +5364,7 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -4697,7 +5382,7 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true } } @@ -4728,14 +5413,14 @@ } }, "parse-duration": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.2.tgz", - "integrity": "sha512-0qfMZyjOUFBeEIvJ5EayfXJqaEXxQ+Oj2b7tWJM3hvEXvXsYCk05EDVI23oYnEw2NaFYUWdABEVPBvBMh8L/pA==" + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.3.tgz", + "integrity": "sha512-hMOZHfUmjxO5hMKn7Eft+ckP2M4nV4yzauLXiw3PndpkASnx5r8pDAMcOAiqxoemqWjMWmz4fOHQM6n6WwETXw==" }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -4791,7 +5476,7 @@ "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { "pify": "^2.0.0" @@ -4800,7 +5485,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } @@ -4831,7 +5516,7 @@ "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { "find-up": "^2.1.0" @@ -4844,9 +5529,9 @@ "dev": true }, "prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-piXGBcY1zoFOG0MvHpNE5reAGseLmaCRifQ/fmfF49BcYkInEs/naD/unxGNAeOKFA5+JxVrPyMvMlpzcd20UA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "dev": true }, "prettier-eslint": { @@ -5480,9 +6165,9 @@ } }, "protobufjs": { - "version": "6.8.9", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.9.tgz", - "integrity": "sha512-j2JlRdUeL/f4Z6x4aU4gj9I2LECglC+5qR2TrWb193Tla1qfdaNQTZ8I27Pt7K0Ajmvjjpft7O3KWTGciz4gpw==", + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.9.0.tgz", + "integrity": "sha512-LlGVfEWDXoI/STstRDdZZKb/qusoAWUnmLg9R8OLSO473mBLWHowx8clbX5/+mKDEI+v7GzjoK9tRPZMMcoTrg==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -5494,8 +6179,8 @@ "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", + "@types/long": "^4.0.1", + "@types/node": "^13.7.0", "long": "^4.0.0" } }, @@ -5561,11 +6246,21 @@ } } }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" + }, "quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -5584,26 +6279,31 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raven": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/raven/-/raven-1.1.3.tgz", - "integrity": "sha1-QnPBrm005CMPUbLAEEGjK5Iygio=", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/raven/-/raven-2.6.4.tgz", + "integrity": "sha512-6PQdfC4+DQSFncowthLf+B6Hr0JpPsFBgTVYTAOq7tCmx/kR4SXbeawtPch20+3QfUcQDoJBLjWW1ybvZ4kXTw==", "requires": { "cookie": "0.3.1", - "json-stringify-safe": "5.0.1", - "lsmod": "1.0.0", - "stack-trace": "0.0.9", - "uuid": "3.0.0" + "md5": "^2.2.1", + "stack-trace": "0.0.10", + "timed-out": "4.0.1", + "uuid": "3.3.2" }, "dependencies": { "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" }, "uuid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.0.0.tgz", - "integrity": "sha1-Zyj8BFnEUNeWqZwxg3VpvfZy1yg=" + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" } } }, @@ -5627,7 +6327,7 @@ "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { "load-json-file": "^2.0.0", @@ -5638,7 +6338,7 @@ "read-pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { "find-up": "^2.0.0", @@ -5684,9 +6384,9 @@ } }, "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "version": "0.13.7", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", "dev": true }, "regexp.prototype.flags": { @@ -5778,9 +6478,9 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "requires": { "path-parse": "^1.0.6" } @@ -5790,7 +6490,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", "dev": true }, "require-main-filename": { @@ -5909,9 +6609,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sandboxed-module": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-2.0.3.tgz", - "integrity": "sha512-wXiA6ULoGjCDwjn6evQF/Qi+oe77P+aCxizUktLBBKdqNbTxwec4GySJcS+O7iZFhme2ex04m+14KgknKKqFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/sandboxed-module/-/sandboxed-module-2.0.4.tgz", + "integrity": "sha512-AwEPOdO8mg/wJjr876yCHP2DHqVN0MaggEXhp6IIf3bcI5cYoQl9QrrCHSrvToHjvdEiS5x4TVZRgjD2bEmNTA==", "dev": true, "requires": { "require-like": "0.1.2", @@ -5927,6 +6627,11 @@ "sparse-bitfield": "^3.0.3" } }, + "sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -6036,13 +6741,13 @@ "integrity": "sha512-meQNNykwecVxdu1RlYMKpQx4+wefIYpmxi6gexo/KAbwquJrBUrBmKYJrE8KFkVQAAVWEnwNdu21PgrD77J3xA==" }, "sinon": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.1.tgz", - "integrity": "sha512-iTTyiQo5T94jrOx7X7QLBZyucUJ2WvL9J13+96HMfm2CGoJYbIPqRfl6wgNcqmzk0DI28jeGx5bUTXizkrqBmg==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.2.tgz", + "integrity": "sha512-0uF8Q/QHkizNUmbK3LRFqx5cpTttEVXudywY9Uwzy8bTfZUhljZ7ARzSxnRHWYWtVTeh4Cw+tTb3iU21FQVO9A==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.0", - "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/commons": "^1.7.2", + "@sinonjs/fake-timers": "^6.0.1", "@sinonjs/formatio": "^5.0.1", "@sinonjs/samsam": "^5.0.3", "diff": "^4.0.2", @@ -6073,6 +6778,12 @@ } } }, + "sinon-chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", + "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", + "dev": true + }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", @@ -6101,6 +6812,11 @@ "to-snake-case": "^1.0.0" } }, + "snakeize": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", + "integrity": "sha512-ot3bb6pQt6IVq5G/JQ640ceSYTPtriVrwNyfoUw1LmQQGzPMAGxE5F+ded2UwSUCyf2PW1fFAYUnVEX21PWbpQ==" + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -6192,6 +6908,16 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, + "sse4_crc32": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/sse4_crc32/-/sse4_crc32-6.0.1.tgz", + "integrity": "sha512-FUTYXpLroqytNKWIfHzlDWoy9E4tmBB/RklNMy6w3VJs+/XEYAHgbiylg4SS43iOk/9bM0BlJ2EDpFAGT66IoQ==", + "optional": true, + "requires": { + "bindings": "^1.3.0", + "node-addon-api": "^1.3.0" + } + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -6229,7 +6955,8 @@ "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==" + "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=", + "dev": true }, "statsd-parser": { "version": "0.0.4", @@ -6254,6 +6981,11 @@ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, + "streamifier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz", + "integrity": "sha512-zDgl+muIlWzXNsXeyUfOk9dChMjlpkq0DRsxujtYPgyJ676yQ8jEm6zzaaWHFDg5BNcLuif0eD2MTyJdZqXpdg==" + }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -6290,24 +7022,24 @@ "side-channel": "^1.0.2" } }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5" } }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5" } }, "string_decoder": { @@ -6354,7 +7086,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" }, "supports-color": { "version": "6.0.0", @@ -6574,6 +7306,20 @@ "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==" + }, + "tiny-async-pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-1.1.0.tgz", + "integrity": "sha512-jIglyHF/9QdCC3662m/UMVADE6SlocBDpXdFLMZyiAfrw8MSG1pml7lwRtBMT6L/z4dddAxfzw2lpW2Vm42fyQ==", + "requires": { + "semver": "^5.5.0", + "yaassertion": "^1.0.0" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -6596,7 +7342,7 @@ "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" }, "to-regex-range": { "version": "5.0.1", @@ -6610,7 +7356,7 @@ "to-snake-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", + "integrity": "sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==", "requires": { "to-space-case": "^1.0.0" } @@ -6618,7 +7364,7 @@ "to-space-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", "requires": { "to-no-case": "^1.0.0" } @@ -6646,6 +7392,18 @@ } } }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", @@ -6697,6 +7455,19 @@ "mime-types": "~2.1.24" } }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "requires": { + "is-typedarray": "^1.0.0" + } + }, "typescript": { "version": "3.7.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", @@ -6704,9 +7475,17 @@ "dev": true }, "underscore": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", - "integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==" + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", + "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==" + }, + "unique-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", + "requires": { + "crypto-random-string": "^2.0.0" + } }, "unpipe": { "version": "1.0.0", @@ -6730,6 +7509,15 @@ } } }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6799,9 +7587,9 @@ }, "dependencies": { "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, "acorn-jsx": { @@ -6888,13 +7676,13 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { @@ -6910,7 +7698,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -6980,20 +7768,40 @@ "signal-exit": "^3.0.2" } }, - "xregexp": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", - "integrity": "sha512-7jXDIFXh5yJ/orPn4SXjuVrWWoi4Cr8jfV1eHv9CixKSbU+jY4mxfrBwAuDvupPNKpMUY+FeIqsVw/JLT9+B8g==", - "dev": true, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" + }, + "xml2js": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", + "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", "requires": { - "@babel/runtime-corejs3": "^7.8.3" + "sax": ">=0.6.0", + "xmlbuilder": "~9.0.1" } }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, + "yaassertion": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/yaassertion/-/yaassertion-1.0.2.tgz", + "integrity": "sha512-sBoJBg5vTr3lOpRX0yFD+tz7wv/l2UPMFthag4HGTMPrypBRKerjjS8jiEnNMjcAEtPXjbHiKE0UwRR1W1GXBg==" + }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -7064,9 +7872,9 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -7084,9 +7892,9 @@ } }, "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-4.0.0.tgz", + "integrity": "sha512-huWiiCS4TxKc4SfgmTwW1K7JmXPPAmuXWYy4j9qjQo4+27Kni8mGhAAi1cloRWmBe2EqcLgt3IGqQoRL/MtPgg==" } } } diff --git a/services/docstore/package.json b/services/docstore/package.json index 455dc14ed7..e53077de30 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -19,40 +19,46 @@ "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write" }, "dependencies": { + "@overleaf/object-persistor": "git+https://github.com/overleaf/object-persistor.git", "async": "^2.6.3", "body-parser": "^1.19.0", "express": "^4.17.1", - "logger-sharelatex": "^2.1.0", - "metrics-sharelatex": "^2.6.2", + "logger-sharelatex": "^2.1.1", + "metrics-sharelatex": "^2.7.0", "mongojs": "3.1.0", "settings-sharelatex": "^1.1.0", - "underscore": "~1.9.2" + "streamifier": "^0.1.1", + "tiny-async-pool": "^1.1.0", + "underscore": "~1.10.2" }, "devDependencies": { + "@google-cloud/storage": "^5.1.2", "babel-eslint": "^10.1.0", - "bunyan": "~1.8.12", + "bunyan": "~1.8.14", "chai": "~4.2.0", + "chai-as-promised": "^7.1.1", "eslint": "^6.8.0", - "eslint-config-prettier": "^6.10.0", - "eslint-config-standard": "^14.1.0", + "eslint-config-prettier": "^6.11.0", + "eslint-config-standard": "^14.1.1", "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.5.0", - "eslint-plugin-import": "^2.20.1", - "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-chai-expect": "^2.2.0", + "eslint-plugin-chai-friendly": "^0.6.0", + "eslint-plugin-import": "^2.22.0", + "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-mocha": "^6.3.0", - "eslint-plugin-node": "^11.0.0", - "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-react": "^7.19.0", + "eslint-plugin-react": "^7.20.3", "eslint-plugin-standard": "^4.0.1", - "mocha": "^7.1.1", - "prettier": "^2.0.0", + "mocha": "^7.2.0", + "prettier": "^2.0.5", "prettier-eslint-cli": "^5.0.0", "request": "~2.88.2", - "sandboxed-module": "~2.0.3", - "sinon": "~9.0.1" + "sandboxed-module": "~2.0.4", + "sinon": "~9.0.2", + "sinon-chai": "^3.5.0" }, "engines": { "node": "~6.14.1" From 287d70567160069eeae36fc34a4bb7407fd58cab Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 23 Jul 2020 19:30:13 +0100 Subject: [PATCH 261/349] Update buildscripts to use fake-gcs instead of S3 credentials --- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose.ci.yml | 13 ++++++++++--- services/docstore/docker-compose.yml | 15 +++++++++++---- .../test/acceptance/deps/Dockerfile.fake-gcs | 5 +++++ .../docstore/test/acceptance/deps/healthcheck.sh | 9 +++++++++ 5 files changed, 36 insertions(+), 8 deletions(-) create mode 100644 services/docstore/test/acceptance/deps/Dockerfile.fake-gcs create mode 100644 services/docstore/test/acceptance/deps/healthcheck.sh diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 48c7852d74..a8929bd59f 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,6 +1,6 @@ docstore --acceptance-creds=None ---dependencies=mongo +--dependencies=mongo,gcs --docker-repos=gcr.io/overleaf-ops --env-add= --env-pass-through= diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 53da6509c7..3510433789 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -16,19 +16,22 @@ services: test_acceptance: build: . image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER - extends: - file: docker-compose-config.yml - service: ci environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres + GCS_API_ENDPOINT: gcs:9090 + GCS_API_SCHEME: http + GCS_PROJECT_ID: fake + STORAGE_EMULATOR_HOST: http://gcs:9090/storage/v1 MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test depends_on: mongo: condition: service_healthy + gcs: + condition: service_healthy user: node command: npm run test:acceptance:_run @@ -42,3 +45,7 @@ services: user: root mongo: image: mongo:3.6 + gcs: + build: + context: test/acceptance/deps + dockerfile: Dockerfile.fake-gcs diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 87ea601dd0..02bf2410af 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -17,18 +17,19 @@ services: user: node test_acceptance: - image: node:10.21.0 + image: node:10 volumes: - .:/app working_dir: /app - extends: - file: docker-compose-config.yml - service: dev environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres + GCS_API_ENDPOINT: gcs:9090 + GCS_API_SCHEME: http + GCS_PROJECT_ID: fake + STORAGE_EMULATOR_HOST: http://gcs:9090/storage/v1 MOCHA_GREP: ${MOCHA_GREP} LOG_LEVEL: ERROR NODE_ENV: test @@ -36,8 +37,14 @@ services: depends_on: mongo: condition: service_healthy + gcs: + condition: service_healthy command: npm run test:acceptance mongo: image: mongo:3.6 + gcs: + build: + context: test/acceptance/deps + dockerfile: Dockerfile.fake-gcs diff --git a/services/docstore/test/acceptance/deps/Dockerfile.fake-gcs b/services/docstore/test/acceptance/deps/Dockerfile.fake-gcs new file mode 100644 index 0000000000..0e6de7e735 --- /dev/null +++ b/services/docstore/test/acceptance/deps/Dockerfile.fake-gcs @@ -0,0 +1,5 @@ +FROM fsouza/fake-gcs-server:latest +RUN apk add --update --no-cache curl +COPY healthcheck.sh /healthcheck.sh +HEALTHCHECK --interval=1s --timeout=1s --retries=30 CMD /healthcheck.sh http://localhost:9090 +CMD ["--port=9090", "--scheme=http"] diff --git a/services/docstore/test/acceptance/deps/healthcheck.sh b/services/docstore/test/acceptance/deps/healthcheck.sh new file mode 100644 index 0000000000..cd19cea637 --- /dev/null +++ b/services/docstore/test/acceptance/deps/healthcheck.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +# health check to allow 404 status code as valid +STATUSCODE=$(curl --silent --output /dev/null --write-out "%{http_code}" $1) +# will be 000 on non-http error (e.g. connection failure) +if test $STATUSCODE -ge 500 || test $STATUSCODE -lt 200; then + exit 1 +fi +exit 0 From 812c996c47197657252ca12f519bda4b7e4c83a3 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 23 Jul 2020 19:42:20 +0100 Subject: [PATCH 262/349] Add required settings for object-persistor --- services/docstore/config/settings.defaults.js | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index d22ff8fee1..0483ecbc3e 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -17,8 +17,15 @@ const Settings = { mongo: {}, docstore: { + backend: process.env.BACKEND || 's3', healthCheck: { project_id: process.env.HEALTH_CHECK_PROJECT_ID + }, + bucket: process.env.BUCKET_NAME || 'bucket', + gcs: { + unlockBeforeDelete: process.env.GCS_UNLOCK_BEFORE_DELETE === 'true', + deletedBucketSuffix: process.env.GCS_DELETED_BUCKET_SUFFIX, + deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50 } }, @@ -41,7 +48,28 @@ if ( Settings.docstore.s3 = { key: process.env.AWS_ACCESS_KEY_ID, secret: process.env.AWS_SECRET_ACCESS_KEY, - bucket: process.env.AWS_BUCKET + bucket: process.env.AWS_BUCKET, + endpoint: process.env.AWS_S3_ENDPOINT, + pathStyle: process.env.AWS_S3_PATH_STYLE, + partSize: parseInt(process.env.AWS_S3_PARTSIZE) || 100 * 1024 * 1024 + } +} + +if (process.env.GCS_API_ENDPOINT) { + Settings.docstore.gcs.endpoint = { + apiEndpoint: process.env.GCS_API_ENDPOINT, + apiScheme: process.env.GCS_API_SCHEME, + projectId: process.env.GCS_PROJECT_ID + } +} + +if (process.env.FALLBACK_BACKEND) { + Settings.docstore.fallback = { + backend: process.env.FALLBACK_BACKEND, + // mapping of bucket names on the fallback, to bucket names on the primary. + // e.g. { myS3UserFilesBucketName: 'myGoogleUserFilesBucketName' } + buckets: JSON.parse(process.env.FALLBACK_BUCKET_MAPPING || '{}'), + copyOnMiss: process.env.COPY_ON_MISS === 'true' } } From 6e04db552aa354c0bf214a62d1bd90f2827c2e3e Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 23 Jul 2020 19:42:49 +0100 Subject: [PATCH 263/349] Implement object-persistor support --- services/docstore/app/js/DocArchiveManager.js | 454 +++++++----------- services/docstore/app/js/Errors.js | 24 +- services/docstore/app/js/PersistorManager.js | 9 + 3 files changed, 187 insertions(+), 300 deletions(-) create mode 100644 services/docstore/app/js/PersistorManager.js diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index f763d081ee..8b9c44bbce 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -1,295 +1,179 @@ -/* eslint-disable - camelcase, - handle-callback-err, - no-useless-escape, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -let DocArchive +const { promisify, callbackify } = require('util') const MongoManager = require('./MongoManager') const Errors = require('./Errors') const logger = require('logger-sharelatex') -const _ = require('underscore') -const async = require('async') const settings = require('settings-sharelatex') -const request = require('request') const crypto = require('crypto') +const Streamifier = require('streamifier') const RangeManager = require('./RangeManager') -const thirtySeconds = 30 * 1000 +const PersistorManager = require('./PersistorManager') +const AsyncPool = require('tiny-async-pool') -module.exports = DocArchive = { - archiveAllDocs(project_id, callback) { - if (callback == null) { - callback = function (err, docs) {} - } - return MongoManager.getProjectsDocs( - project_id, - { include_deleted: true }, - { lines: true, ranges: true, rev: true, inS3: true }, - function (err, docs) { - if (err != null) { - return callback(err) - } else if (docs == null) { - return callback( - new Errors.NotFoundError(`No docs for project ${project_id}`) - ) - } - docs = _.filter(docs, (doc) => doc.inS3 !== true) - const jobs = _.map(docs, (doc) => (cb) => - DocArchive.archiveDoc(project_id, doc, cb) - ) - return async.parallelLimit(jobs, 5, callback) - } - ) - }, +const PARALLEL_JOBS = 5 - archiveDoc(project_id, doc, callback) { - let options - logger.log({ project_id, doc_id: doc._id }, 'sending doc to s3') - try { - options = DocArchive.buildS3Options(project_id + '/' + doc._id) - } catch (e) { - return callback(e) - } - return DocArchive._mongoDocToS3Doc(doc, function (error, json_doc) { - if (error != null) { - return callback(error) - } - options.body = json_doc - options.headers = { 'Content-Type': 'application/json' } - return request.put(options, function (err, res) { - if (err != null || res.statusCode !== 200) { - logger.err( - { - err, - res, - project_id, - doc_id: doc._id, - statusCode: res != null ? res.statusCode : undefined - }, - 'something went wrong archiving doc in aws' - ) - return callback(new Error('Error in S3 request')) - } - const md5lines = crypto - .createHash('md5') - .update(json_doc, 'utf8') - .digest('hex') - const md5response = res.headers.etag.toString().replace(/\"/g, '') - if (md5lines !== md5response) { - logger.err( - { - responseMD5: md5response, - linesMD5: md5lines, - project_id, - doc_id: doc != null ? doc._id : undefined - }, - 'err in response md5 from s3' - ) - return callback(new Error('Error in S3 md5 response')) - } - return MongoManager.markDocAsArchived(doc._id, doc.rev, function (err) { - if (err != null) { - return callback(err) - } - return callback() - }) - }) - }) - }, - - unArchiveAllDocs(project_id, callback) { - if (callback == null) { - callback = function (err) {} - } - return MongoManager.getArchivedProjectDocs(project_id, function ( - err, - docs - ) { - if (err != null) { - logger.err({ err, project_id }, 'error unarchiving all docs') - return callback(err) - } else if (docs == null) { - return callback( - new Errors.NotFoundError(`No docs for project ${project_id}`) - ) - } - const jobs = _.map( - docs, - (doc) => - function (cb) { - if (doc.inS3 == null) { - return cb() - } else { - return DocArchive.unarchiveDoc(project_id, doc._id, cb) - } - } - ) - return async.parallelLimit(jobs, 5, callback) - }) - }, - - unarchiveDoc(project_id, doc_id, callback) { - let options - logger.log({ project_id, doc_id }, 'getting doc from s3') - try { - options = DocArchive.buildS3Options(project_id + '/' + doc_id) - } catch (e) { - return callback(e) - } - options.json = true - return request.get(options, function (err, res, doc) { - if (err != null || res.statusCode !== 200) { - logger.err( - { err, res, project_id, doc_id }, - 'something went wrong unarchiving doc from aws' - ) - return callback(new Errors.NotFoundError('Error in S3 request')) - } - return DocArchive._s3DocToMongoDoc(doc, function (error, mongo_doc) { - if (error != null) { - return callback(error) - } - return MongoManager.upsertIntoDocCollection( - project_id, - doc_id.toString(), - mongo_doc, - function (err) { - if (err != null) { - return callback(err) - } - logger.log({ project_id, doc_id }, 'deleting doc from s3') - return DocArchive._deleteDocFromS3(project_id, doc_id, callback) - } - ) - }) - }) - }, - - destroyAllDocs(project_id, callback) { - if (callback == null) { - callback = function (err) {} - } - return MongoManager.getProjectsDocs( - project_id, - { include_deleted: true }, - { _id: 1 }, - function (err, docs) { - if (err != null) { - logger.err({ err, project_id }, "error getting project's docs") - return callback(err) - } else if (docs == null) { - return callback() - } - const jobs = _.map(docs, (doc) => (cb) => - DocArchive.destroyDoc(project_id, doc._id, cb) - ) - return async.parallelLimit(jobs, 5, callback) - } - ) - }, - - destroyDoc(project_id, doc_id, callback) { - logger.log({ project_id, doc_id }, 'removing doc from mongo and s3') - return MongoManager.findDoc(project_id, doc_id, { inS3: 1 }, function ( - error, - doc - ) { - if (error != null) { - return callback(error) - } - if (doc == null) { - return callback(new Errors.NotFoundError('Doc not found in Mongo')) - } - if (doc.inS3 === true) { - return DocArchive._deleteDocFromS3(project_id, doc_id, function (err) { - if (err != null) { - return err - } - return MongoManager.destroyDoc(doc_id, callback) - }) - } else { - return MongoManager.destroyDoc(doc_id, callback) - } - }) - }, - - _deleteDocFromS3(project_id, doc_id, callback) { - let options - try { - options = DocArchive.buildS3Options(project_id + '/' + doc_id) - } catch (e) { - return callback(e) - } - options.json = true - return request.del(options, function (err, res, body) { - if (err != null || res.statusCode !== 204) { - logger.err( - { err, res, project_id, doc_id }, - 'something went wrong deleting doc from aws' - ) - return callback(new Error('Error in S3 request')) - } - return callback() - }) - }, - - _s3DocToMongoDoc(doc, callback) { - if (callback == null) { - callback = function (error, mongo_doc) {} - } - const mongo_doc = {} - if (doc.schema_v === 1 && doc.lines != null) { - mongo_doc.lines = doc.lines - if (doc.ranges != null) { - mongo_doc.ranges = RangeManager.jsonRangesToMongo(doc.ranges) - } - } else if (doc instanceof Array) { - mongo_doc.lines = doc - } else { - return callback(new Error("I don't understand the doc format in s3")) - } - return callback(null, mongo_doc) - }, - - _mongoDocToS3Doc(doc, callback) { - if (callback == null) { - callback = function (error, s3_doc) {} - } - if (doc.lines == null) { - return callback(new Error('doc has no lines')) - } - const json = JSON.stringify({ - lines: doc.lines, - ranges: doc.ranges, - schema_v: 1 - }) - if (json.indexOf('\u0000') !== -1) { - const error = new Error('null bytes detected') - logger.err({ err: error, doc, json }, error.message) - return callback(error) - } - return callback(null, json) - }, - - buildS3Options(key) { - if (settings.docstore.s3 == null) { - throw new Error('S3 settings are not configured') - } - return { - aws: { - key: settings.docstore.s3.key, - secret: settings.docstore.s3.secret, - bucket: settings.docstore.s3.bucket - }, - timeout: thirtySeconds, - uri: `https://${settings.docstore.s3.bucket}.s3.amazonaws.com/${key}` - } +module.exports = { + archiveAllDocs: callbackify(archiveAllDocs), + archiveDoc: callbackify(archiveDoc), + unArchiveAllDocs: callbackify(unArchiveAllDocs), + unarchiveDoc: callbackify(unarchiveDoc), + destroyAllDocs: callbackify(destroyAllDocs), + destroyDoc: callbackify(destroyDoc), + promises: { + archiveAllDocs, + archiveDoc, + unArchiveAllDocs, + unarchiveDoc, + destroyAllDocs, + destroyDoc } } + +async function archiveAllDocs(projectId) { + const docs = await promisify(MongoManager.getProjectsDocs)( + projectId, + { include_deleted: true }, + { lines: true, ranges: true, rev: true, inS3: true } + ) + + if (!docs) { + throw new Errors.NotFoundError(`No docs for project ${projectId}`) + } + + await AsyncPool( + PARALLEL_JOBS, + docs.filter((doc) => !doc.inS3), + (doc) => archiveDoc(projectId, doc) + ) +} + +async function archiveDoc(projectId, doc) { + logger.log( + { project_id: projectId, doc_id: doc._id }, + 'sending doc to persistor' + ) + const key = `${projectId}/${doc._id}` + + if (doc.lines == null) { + throw new Error('doc has no lines') + } + + const json = JSON.stringify({ + lines: doc.lines, + ranges: doc.ranges, + schema_v: 1 + }) + + // this should never happen, but protects against memory-corruption errors that + // have happened in the past + if (json.indexOf('\u0000') > -1) { + const error = new Error('null bytes detected') + logger.err({ err: error, doc }, error.message) + throw error + } + + const md5 = crypto.createHash('md5').update(json).digest('hex') + const stream = Streamifier.createReadStream(json) + await PersistorManager.sendStream(settings.docstore.bucket, key, stream, { + sourceMd5: md5 + }) + await promisify(MongoManager.markDocAsArchived)(doc._id, doc.rev) +} + +async function unArchiveAllDocs(projectId) { + const docs = await promisify(MongoManager.getArchivedProjectDocs)(projectId) + if (!docs) { + throw new Errors.NotFoundError(`No docs for project ${projectId}`) + } + await AsyncPool(PARALLEL_JOBS, docs, (doc) => + unarchiveDoc(projectId, doc._id) + ) +} + +async function unarchiveDoc(projectId, docId) { + logger.log( + { project_id: projectId, doc_id: docId }, + 'getting doc from persistor' + ) + const key = `${projectId}/${docId}` + const sourceMd5 = await PersistorManager.getObjectMd5Hash( + settings.docstore.bucket, + key + ) + const stream = await PersistorManager.getObjectStream( + settings.docstore.bucket, + key + ) + stream.resume() + const json = await _streamToString(stream) + const md5 = crypto.createHash('md5').update(json).digest('hex') + if (sourceMd5 !== md5) { + throw new Errors.Md5MismatchError('md5 mismatch when downloading doc', { + key, + sourceMd5, + md5 + }) + } + + const doc = JSON.parse(json) + + const mongoDoc = {} + if (doc.schema_v === 1 && doc.lines != null) { + mongoDoc.lines = doc.lines + if (doc.ranges != null) { + mongoDoc.ranges = RangeManager.jsonRangesToMongo(doc.ranges) + } + } else if (Array.isArray(doc)) { + mongoDoc.lines = doc + } else { + throw new Error("I don't understand the doc format in s3") + } + await promisify(MongoManager.upsertIntoDocCollection)( + projectId, + docId, + mongoDoc + ) + await PersistorManager.deleteObject(settings.docstore.bucket, key) +} + +async function destroyAllDocs(projectId) { + const docs = await promisify(MongoManager.getProjectsDocs)( + projectId, + { include_deleted: true }, + { _id: 1 } + ) + if (docs) { + await AsyncPool(PARALLEL_JOBS, docs, (doc) => + destroyDoc(projectId, doc._id) + ) + } +} + +async function destroyDoc(projectId, docId) { + logger.log( + { project_id: projectId, doc_id: docId }, + 'removing doc from mongo and persistor' + ) + const doc = await promisify(MongoManager.findDoc)(projectId, docId, { + inS3: 1 + }) + if (!doc) { + throw new Errors.NotFoundError('Doc not found in Mongo') + } + + if (doc.inS3) { + await PersistorManager.deleteObject( + settings.docstore.bucket, + `${projectId}/${docId}` + ) + } + await promisify(MongoManager.destroyDoc)(docId) +} + +async function _streamToString(stream) { + const chunks = [] + return new Promise((resolve, reject) => { + stream.on('data', (chunk) => chunks.push(chunk)) + stream.on('error', reject) + stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))) + }) +} diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index a950b6de20..6a74485494 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -1,16 +1,10 @@ -/* eslint-disable - no-proto, - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -let Errors -var NotFoundError = function (message) { - const error = new Error(message) - error.name = 'NotFoundError' - error.__proto__ = NotFoundError.prototype - return error -} -NotFoundError.prototype.__proto__ = Error.prototype +// import Errors from object-persistor to pass instanceof checks +const OError = require('@overleaf/o-error') +const { Errors } = require('@overleaf/object-persistor') -module.exports = Errors = { NotFoundError } +class Md5MismatchError extends OError {} + +module.exports = { + Md5MismatchError, + ...Errors +} diff --git a/services/docstore/app/js/PersistorManager.js b/services/docstore/app/js/PersistorManager.js new file mode 100644 index 0000000000..b3d194a210 --- /dev/null +++ b/services/docstore/app/js/PersistorManager.js @@ -0,0 +1,9 @@ +const settings = require('settings-sharelatex') + +const persistorSettings = settings.docstore +persistorSettings.Metrics = require('metrics-sharelatex') + +const ObjectPersistor = require('@overleaf/object-persistor') +const persistor = ObjectPersistor(persistorSettings) + +module.exports = persistor From e302c1d844333cf9322dd420de1f8626019584f9 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 23 Jul 2020 19:43:33 +0100 Subject: [PATCH 264/349] Update acceptance tests for object-persistor and gcs --- .../test/acceptance/js/ArchiveDocsTests.js | 104 ++++++++++-------- .../test/acceptance/js/DeletingDocsTests.js | 17 +-- .../test/acceptance/js/helpers/DocstoreApp.js | 7 ++ .../acceptance/js/helpers/DocstoreClient.js | 37 +++++-- 4 files changed, 98 insertions(+), 67 deletions(-) diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 3f559f566e..959af6715b 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -12,22 +12,37 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require('sinon') -const chai = require('chai') -const should = chai.should() -const { db, ObjectId, ISODate } = require('../../../app/js/mongojs') -const async = require('async') +process.env.BACKEND = 'gcs' const Settings = require('settings-sharelatex') -const DocArchiveManager = require('../../../app/js/DocArchiveManager.js') -const request = require('request') +const chai = require('chai') +const { expect } = chai +const should = chai.should() +const { db, ObjectId } = require('../../../app/js/mongojs') +const async = require('async') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') +const { Storage } = require('@google-cloud/storage') +const Persistor = require('../../../app/js/PersistorManager') +const Streamifier = require('streamifier') + +function uploadContent(path, json, callback) { + const stream = Streamifier.createReadStream(JSON.stringify(json)) + Persistor.sendStream(Settings.docstore.bucket, path, stream) + .then(() => callback()) + .catch(callback) +} describe('Archiving', function () { before(function (done) { return DocstoreApp.ensureRunning(done) }) + before(async function () { + const storage = new Storage(Settings.docstore.gcs.endpoint) + await storage.createBucket(Settings.docstore.bucket) + await storage.createBucket(`${Settings.docstore.bucket}-deleted`) + }) + describe('multiple docs in a project', function () { before(function (done) { this.project_id = ObjectId() @@ -99,10 +114,10 @@ describe('Archiving', function () { return DocstoreClient.getS3Doc( this.project_id, doc._id, - (error, res, s3_doc) => { + (error, s3_doc) => { s3_doc.lines.should.deep.equal(doc.lines) s3_doc.ranges.should.deep.equal(doc.ranges) - return callback() + callback() } ) } @@ -215,7 +230,7 @@ describe('Archiving', function () { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, - (error, res, s3_doc) => { + (error, s3_doc) => { if (error != null) { throw error } @@ -316,7 +331,7 @@ describe('Archiving', function () { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, - (error, res, s3_doc) => { + (error, s3_doc) => { if (error != null) { throw error } @@ -790,7 +805,7 @@ describe('Archiving', function () { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, - (error, res, s3_doc) => { + (error, s3_doc) => { if (error != null) { throw error } @@ -909,7 +924,7 @@ describe('Archiving', function () { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, - (error, res, s3_doc) => { + (error, s3_doc) => { if (error != null) { throw error } @@ -1006,7 +1021,7 @@ describe('Archiving', function () { return DocstoreClient.getS3Doc( this.project_id, this.doc._id, - (error, res, s3_doc) => { + (error, s3_doc) => { if (error != null) { throw error } @@ -1054,39 +1069,36 @@ describe('Archiving', function () { ranges: {}, version: 2 } - const options = DocArchiveManager.buildS3Options( - `${this.project_id}/${this.doc._id}` - ) - options.json = this.doc.lines - return request.put(options, (error, res, body) => { - if (error != null) { - throw error - } - res.statusCode.should.equal(200) - return db.docs.insert( - { - project_id: this.project_id, - _id: this.doc._id, - rev: this.doc.version, - inS3: true - }, - (error) => { - if (error != null) { - throw error - } - return DocstoreClient.getAllDocs( - this.project_id, - (error, res, fetched_docs) => { - this.fetched_docs = fetched_docs - if (error != null) { - throw error - } - return done() + uploadContent( + `${this.project_id}/${this.doc._id}`, + this.doc.lines, + (error) => { + expect(error).not.to.exist + db.docs.insert( + { + project_id: this.project_id, + _id: this.doc._id, + rev: this.doc.version, + inS3: true + }, + (error) => { + if (error != null) { + throw error } - ) - } - ) - }) + DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error != null) { + throw error + } + return done() + } + ) + } + ) + } + ) }) it('should restore the doc to mongo', function (done) { diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index fd534da010..41a62fbebb 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -11,12 +11,12 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const sinon = require('sinon') const chai = require('chai') chai.should() const { db, ObjectId } = require('../../../app/js/mongojs') const { expect } = chai const DocstoreApp = require('./helpers/DocstoreApp') +const Errors = require('../../../app/js/Errors') const DocstoreClient = require('./helpers/DocstoreClient') @@ -143,17 +143,10 @@ describe("Destroying a project's documents", function () { }) return it('should remove the doc contents from s3', function (done) { - return DocstoreClient.getS3Doc( - this.project_id, - this.doc_id, - (error, res, s3_doc) => { - if (error != null) { - throw error - } - expect(res.statusCode).to.equal(404) - return done() - } - ) + return DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error) => { + expect(error).to.be.instanceOf(Errors.NotFoundError) + done() + }) }) }) }) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 67dc1760e4..38162da8f2 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -15,6 +15,13 @@ const app = require('../../../../app') require('logger-sharelatex').logger.level('error') const settings = require('settings-sharelatex') +// treat unhandled promise rejections as failures +process.on('unhandledRejection', (e) => { + // eslint-disable-next-line no-console + console.log('** Unhandled Promise Rejection **\n', e) + throw e +}) + module.exports = { running: false, initing: false, diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index bec63a261a..237ef42134 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -13,9 +13,23 @@ */ let DocstoreClient const request = require('request').defaults({ jar: false }) -const { db, ObjectId } = require('../../../../app/js/mongojs') const settings = require('settings-sharelatex') -const DocArchiveManager = require('../../../../app/js/DocArchiveManager.js') +const Persistor = require('../../../../app/js/PersistorManager') + +async function streamToString(stream) { + const chunks = [] + return new Promise((resolve, reject) => { + stream.on('data', (chunk) => chunks.push(chunk)) + stream.on('error', reject) + stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))) + }) +} + +async function getStringFromPersistor(persistor, bucket, key) { + const stream = await persistor.getObjectStream(bucket, key, {}) + stream.resume() + return streamToString(stream) +} module.exports = DocstoreClient = { createDoc(project_id, doc_id, lines, version, ranges, callback) { @@ -55,7 +69,9 @@ module.exports = DocstoreClient = { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, json: true }, - callback + (req, res, body) => { + callback(req, res, body) + } ) }, @@ -126,11 +142,14 @@ module.exports = DocstoreClient = { }, getS3Doc(project_id, doc_id, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - const options = DocArchiveManager.buildS3Options(project_id + '/' + doc_id) - options.json = true - return request.get(options, callback) + getStringFromPersistor( + Persistor, + settings.docstore.bucket, + `${project_id}/${doc_id}` + ) + .then((data) => { + callback(null, JSON.parse(data)) + }) + .catch(callback) } } From 04ae868fe27453337477e0e234275011dd977027 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 23 Jul 2020 19:43:51 +0100 Subject: [PATCH 265/349] Update unit tests for object-persistor --- .../test/unit/js/DocArchiveManagerTests.js | 860 +++++++++--------- .../docstore/test/unit/js/DocManagerTests.js | 3 +- 2 files changed, 408 insertions(+), 455 deletions(-) diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index f950fe4dc8..9fa689d1dc 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -1,47 +1,59 @@ -/* eslint-disable - camelcase, - handle-callback-err, - no-return-assign, - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -const { assert } = require('chai') const sinon = require('sinon') const chai = require('chai') -const should = chai.should() const { expect } = chai const modulePath = '../../../app/js/DocArchiveManager.js' const SandboxedModule = require('sandboxed-module') const { ObjectId } = require('mongojs') const Errors = require('../../../app/js/Errors') -const crypto = require('crypto') + +chai.use(require('chai-as-promised')) +chai.use(require('sinon-chai')) describe('DocArchiveManager', function () { + let DocArchiveManager, + PersistorManager, + MongoManager, + RangeManager, + Settings, + Logger, + Crypto, + Streamifier, + HashDigest, + HashUpdate, + archivedDocs, + mongoDocs, + docJson, + md5Sum, + projectId, + readStream, + stream + beforeEach(function () { - this.settings = { + md5Sum = 'decafbad' + + RangeManager = { + jsonRangesToMongo: sinon.stub().returns({ mongo: 'ranges' }) + } + Settings = { docstore: { - s3: { - secret: 'secret', - key: 'this_key', - bucket: 'doc-archive-unit-test' - } + bucket: 'wombat' } } - - this.request = { - put: {}, - get: {}, - del: {} + Logger = { + log: sinon.stub(), + err: sinon.stub() + } + HashDigest = sinon.stub().returns(md5Sum) + HashUpdate = sinon.stub().returns({ digest: HashDigest }) + Crypto = { + createHash: sinon.stub().returns({ update: HashUpdate }) + } + Streamifier = { + createReadStream: sinon.stub().returns({ stream: 'readStream' }) } - this.archivedDocs = [ + projectId = ObjectId() + archivedDocs = [ { _id: ObjectId(), inS3: true, @@ -58,8 +70,7 @@ describe('DocArchiveManager', function () { rev: 6 } ] - - this.mongoDocs = [ + mongoDocs = [ { _id: ObjectId(), lines: ['one', 'two', 'three'], @@ -87,488 +98,429 @@ describe('DocArchiveManager', function () { } ] - this.unarchivedDocs = [ - { - _id: ObjectId(), - lines: ['wombat', 'potato', 'banana'], - rev: 2 - }, - { - _id: ObjectId(), - lines: ['llama', 'turnip', 'apple'], - rev: 4 - }, - { - _id: ObjectId(), - lines: ['elephant', 'swede', 'nectarine'], - rev: 6 - } - ] + docJson = JSON.stringify({ + lines: mongoDocs[0].lines, + ranges: mongoDocs[0].ranges, + schema_v: 1 + }) - this.mixedDocs = this.archivedDocs.concat(this.unarchivedDocs) + stream = { + on: sinon.stub(), + resume: sinon.stub() + } + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + stream.on.withArgs('end').yields() - this.MongoManager = { - markDocAsArchived: sinon.stub().callsArgWith(2, null), - upsertIntoDocCollection: sinon.stub().callsArgWith(3, null), - getProjectsDocs: sinon.stub().callsArgWith(3, null, this.mongoDocs), - getArchivedProjectDocs: sinon.stub().callsArgWith(2, null, this.mongoDocs) + readStream = { + stream: 'readStream' } - this.requires = { - 'settings-sharelatex': this.settings, - './MongoManager': this.MongoManager, - request: this.request, - './RangeManager': (this.RangeManager = {}), - 'logger-sharelatex': { - log() {}, - err() {} - } + PersistorManager = { + getObjectStream: sinon.stub().resolves(stream), + sendStream: sinon.stub().resolves(), + getObjectMd5Hash: sinon.stub().resolves(md5Sum), + deleteObject: sinon.stub().resolves() } - this.globals = { JSON } - this.error = 'my errror' - this.project_id = ObjectId().toString() - this.stubbedError = new Errors.NotFoundError('Error in S3 request') - return (this.DocArchiveManager = SandboxedModule.require(modulePath, { - requires: this.requires, - globals: this.globals - })) + MongoManager = { + markDocAsArchived: sinon.stub().yields(), + upsertIntoDocCollection: sinon.stub().yields(), + getProjectsDocs: sinon.stub().yields(null, mongoDocs), + getArchivedProjectDocs: sinon.stub().yields(null, archivedDocs), + findDoc: sinon.stub().yields(), + destroyDoc: sinon.stub().yields() + } + for (const mongoDoc of mongoDocs) { + MongoManager.findDoc + .withArgs(projectId, mongoDoc._id, sinon.match.any) + .yields(null, mongoDoc) + } + + DocArchiveManager = SandboxedModule.require(modulePath, { + requires: { + 'settings-sharelatex': Settings, + 'logger-sharelatex': Logger, + crypto: Crypto, + streamifier: Streamifier, + './MongoManager': MongoManager, + './RangeManager': RangeManager, + './PersistorManager': PersistorManager, + './Errors': Errors + }, + globals: { + console, + JSON + } + }) }) describe('archiveDoc', function () { - it('should use correct options', function (done) { - this.request.put = sinon - .stub() - .callsArgWith(1, null, { statusCode: 200, headers: { etag: '' } }) - return this.DocArchiveManager.archiveDoc( - this.project_id, - this.mongoDocs[0], - (err) => { - const opts = this.request.put.args[0][0] - assert.deepEqual(opts.aws, { - key: this.settings.docstore.s3.key, - secret: this.settings.docstore.s3.secret, - bucket: this.settings.docstore.s3.bucket - }) - opts.body.should.equal( - JSON.stringify({ - lines: this.mongoDocs[0].lines, - ranges: this.mongoDocs[0].ranges, - schema_v: 1 - }) - ) - opts.timeout.should.equal(30 * 1000) - opts.uri.should.equal( - `https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}` - ) - return done() - } + it('should resolve when passed a valid document', async function () { + await expect( + DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) + ).to.eventually.be.fulfilled + }) + + it('should throw an error if the doc has no lines', async function () { + const doc = mongoDocs[0] + doc.lines = null + + await expect( + DocArchiveManager.promises.archiveDoc(projectId, doc) + ).to.eventually.be.rejectedWith('doc has no lines') + }) + + it('should add the schema version', async function () { + await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[1]) + expect(Streamifier.createReadStream).to.have.been.calledWith( + sinon.match(/"schema_v":1/) ) }) - it('should return no md5 error', function (done) { - const data = JSON.stringify({ - lines: this.mongoDocs[0].lines, - ranges: this.mongoDocs[0].ranges, + it('should calculate the hex md5 sum of the content', async function () { + const json = JSON.stringify({ + lines: mongoDocs[0].lines, + ranges: mongoDocs[0].ranges, schema_v: 1 }) - this.md5 = crypto.createHash('md5').update(data).digest('hex') - this.request.put = sinon - .stub() - .callsArgWith(1, null, { statusCode: 200, headers: { etag: this.md5 } }) - return this.DocArchiveManager.archiveDoc( - this.project_id, - this.mongoDocs[0], - (err) => { - should.not.exist(err) - return done() - } + + await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) + + expect(Crypto.createHash).to.have.been.calledWith('md5') + expect(HashUpdate).to.have.been.calledWith(json) + expect(HashDigest).to.have.been.calledWith('hex') + }) + + it('should pass the md5 hash to the object persistor for verification', async function () { + await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) + + expect(PersistorManager.sendStream).to.have.been.calledWith( + sinon.match.any, + sinon.match.any, + sinon.match.any, + { sourceMd5: md5Sum } ) }) - return it('should return the error', function (done) { - this.request.put = sinon.stub().callsArgWith(1, this.stubbedError, { - statusCode: 400, - headers: { etag: '' } - }) - return this.DocArchiveManager.archiveDoc( - this.project_id, - this.mongoDocs[0], - (err) => { - should.exist(err) - return done() - } + it('should pass the correct bucket and key to the persistor', async function () { + await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) + + expect(PersistorManager.sendStream).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${mongoDocs[0]._id}` ) }) + + it('should create a stream from the encoded json and send it', async function () { + await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) + expect(Streamifier.createReadStream).to.have.been.calledWith(docJson) + expect(PersistorManager.sendStream).to.have.been.calledWith( + sinon.match.any, + sinon.match.any, + readStream + ) + }) + + it('should mark the doc as archived', async function () { + await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) + expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + mongoDocs[0]._id, + mongoDocs[0].rev + ) + }) + + describe('with null bytes in the result', function () { + const _stringify = JSON.stringify + + beforeEach(function () { + JSON.stringify = sinon.stub().returns('{"bad": "\u0000"}') + }) + + afterEach(function () { + JSON.stringify = _stringify + }) + + it('should return an error', async function () { + await expect( + DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) + ).to.eventually.be.rejectedWith('null bytes detected') + }) + }) }) describe('unarchiveDoc', function () { - it('should use correct options', function (done) { - this.request.get = sinon - .stub() - .callsArgWith(1, null, { statusCode: 200 }, this.mongoDocs[0].lines) - this.request.del = sinon - .stub() - .callsArgWith(1, null, { statusCode: 204 }, {}) - return this.DocArchiveManager.unarchiveDoc( - this.project_id, - this.mongoDocs[0]._id, - (err) => { - const opts = this.request.get.args[0][0] - assert.deepEqual(opts.aws, { - key: this.settings.docstore.s3.key, - secret: this.settings.docstore.s3.secret, - bucket: this.settings.docstore.s3.bucket - }) - opts.json.should.equal(true) - opts.timeout.should.equal(30 * 1000) - opts.uri.should.equal( - `https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${this.mongoDocs[0]._id}` + let docId + + beforeEach(function () { + docId = mongoDocs[0]._id + }) + + it('should resolve when passed a valid document', async function () { + await expect(DocArchiveManager.promises.unarchiveDoc(projectId, docId)).to + .eventually.be.fulfilled + }) + + it('should throw an error if the md5 does not match', async function () { + PersistorManager.getObjectMd5Hash.resolves('badf00d') + await expect( + DocArchiveManager.promises.unarchiveDoc(projectId, docId) + ).to.eventually.be.rejected.and.be.instanceof(Errors.Md5MismatchError) + }) + + it('should update the doc lines in mongo', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect( + MongoManager.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, { lines: mongoDocs[0].lines }) + }) + + it('should delete the doc in s3', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect(PersistorManager.deleteObject).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${docId}` + ) + }) + + describe('doc contents', function () { + let mongoDoc, s3Doc + + describe('when the doc has the old schema', function () { + beforeEach(function () { + mongoDoc = { + lines: ['doc', 'lines'] + } + s3Doc = ['doc', 'lines'] + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should return the docs lines', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect(MongoManager.upsertIntoDocCollection).to.have.been.calledWith( + projectId, + docId, + mongoDoc ) - return done() - } - ) + }) + }) + + describe('with the new schema and ranges', function () { + beforeEach(function () { + s3Doc = { + lines: ['doc', 'lines'], + ranges: { json: 'ranges' }, + schema_v: 1 + } + mongoDoc = { + lines: ['doc', 'lines'], + ranges: { mongo: 'ranges' } + } + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should return the doc lines and ranges', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect(MongoManager.upsertIntoDocCollection).to.have.been.calledWith( + projectId, + docId, + mongoDoc + ) + }) + }) + + describe('with the new schema and no ranges', function () { + beforeEach(function () { + s3Doc = { + lines: ['doc', 'lines'], + schema_v: 1 + } + mongoDoc = { + lines: ['doc', 'lines'] + } + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should return only the doc lines', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect(MongoManager.upsertIntoDocCollection).to.have.been.calledWith( + projectId, + docId, + mongoDoc + ) + }) + }) + + describe('with an unrecognised schema', function () { + beforeEach(function () { + s3Doc = { + lines: ['doc', 'lines'], + schema_v: 2 + } + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should throw an error', async function () { + await expect( + DocArchiveManager.promises.unarchiveDoc(projectId, docId) + ).to.eventually.be.rejectedWith( + "I don't understand the doc format in s3" + ) + }) + }) + }) + }) + + describe('destroyDoc', function () { + let docId + + beforeEach(function () { + docId = mongoDocs[0]._id }) - it('should return the error', function (done) { - this.request.get = sinon.stub().callsArgWith(1, this.stubbedError, {}, {}) - return this.DocArchiveManager.unarchiveDoc( - this.project_id, - this.mongoDocs[0], - (err) => { - should.exist(err) - return done() - } - ) + it('should resolve when passed a valid document', async function () { + await expect(DocArchiveManager.promises.destroyDoc(projectId, docId)).to + .eventually.be.fulfilled }) - return it('should error if the doc lines are a string not an array', function (done) { - this.request.get = sinon - .stub() - .callsArgWith(1, null, { statusCode: 200 }, 'this is a string') - this.request.del = sinon.stub() - return this.DocArchiveManager.unarchiveDoc( - this.project_id, - this.mongoDocs[0], - (err) => { - should.exist(err) - this.request.del.called.should.equal(false) - return done() - } - ) + it('should throw a not found error when there is no document', async function () { + await expect( + DocArchiveManager.promises.destroyDoc(projectId, 'wombat') + ).to.eventually.be.rejected.and.be.instanceof(Errors.NotFoundError) + }) + + describe('when the doc is in s3', function () { + beforeEach(function () { + mongoDocs[0].inS3 = true + }) + + it('should delete the document from s3, if it is in s3', async function () { + await DocArchiveManager.promises.destroyDoc(projectId, docId) + expect(PersistorManager.deleteObject).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${docId}` + ) + }) + + it('should delete the doc in mongo', async function () { + await DocArchiveManager.promises.destroyDoc(projectId, docId) + }) + }) + + describe('when the doc is not in s3', function () { + beforeEach(function () { + mongoDocs[0].inS3 = false + }) + + it('should not delete the document from s3, if it is not in s3', async function () { + await DocArchiveManager.promises.destroyDoc(projectId, docId) + expect(PersistorManager.deleteObject).not.to.have.been.called + }) + + it('should delete the doc in mongo', async function () { + await DocArchiveManager.promises.destroyDoc(projectId, docId) + }) }) }) describe('archiveAllDocs', function () { - it('should archive all project docs which are not in s3', function (done) { - this.MongoManager.getProjectsDocs = sinon - .stub() - .callsArgWith(3, null, this.mongoDocs) - this.DocArchiveManager.archiveDoc = sinon.stub().callsArgWith(2, null) - - return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { - this.DocArchiveManager.archiveDoc - .calledWith(this.project_id, this.mongoDocs[0]) - .should.equal(true) - this.DocArchiveManager.archiveDoc - .calledWith(this.project_id, this.mongoDocs[1]) - .should.equal(true) - this.DocArchiveManager.archiveDoc - .calledWith(this.project_id, this.mongoDocs[4]) - .should.equal(true) - - this.DocArchiveManager.archiveDoc - .calledWith(this.project_id, this.mongoDocs[2]) - .should.equal(false) - this.DocArchiveManager.archiveDoc - .calledWith(this.project_id, this.mongoDocs[3]) - .should.equal(false) - - should.not.exist(err) - return done() - }) + it('should resolve with valid arguments', async function () { + await expect(DocArchiveManager.promises.archiveAllDocs(projectId)).to + .eventually.be.fulfilled }) - it('should return error if have no docs', function (done) { - this.MongoManager.getProjectsDocs = sinon - .stub() - .callsArgWith(3, null, null) + it('should archive all project docs which are not in s3', async function () { + await DocArchiveManager.promises.archiveAllDocs(projectId) + // not inS3 + expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + mongoDocs[0]._id + ) + expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + mongoDocs[1]._id + ) + expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + mongoDocs[4]._id + ) - return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { - should.exist(err) - return done() - }) + // inS3 + expect(MongoManager.markDocAsArchived).not.to.have.been.calledWith( + mongoDocs[2]._id + ) + expect(MongoManager.markDocAsArchived).not.to.have.been.calledWith( + mongoDocs[3]._id + ) }) - it('should return the error', function (done) { - this.MongoManager.getProjectsDocs = sinon - .stub() - .callsArgWith(3, this.error, null) + it('should return error if the project has no docs', async function () { + MongoManager.getProjectsDocs.yields(null, null) - return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { - err.should.equal(this.error) - return done() - }) - }) - - return describe('when most have been already put in s3', function () { - beforeEach(function () { - let numberOfDocs = 10 * 1000 - this.mongoDocs = [] - while (--numberOfDocs !== 0) { - this.mongoDocs.push({ inS3: true, _id: ObjectId() }) - } - - this.MongoManager.getProjectsDocs = sinon - .stub() - .callsArgWith(3, null, this.mongoDocs) - return (this.DocArchiveManager.archiveDoc = sinon - .stub() - .callsArgWith(2, null)) - }) - - return it('should not throw and error', function (done) { - return this.DocArchiveManager.archiveAllDocs(this.project_id, (err) => { - should.not.exist(err) - return done() - }) - }) + await expect( + DocArchiveManager.promises.archiveAllDocs(projectId) + ).to.eventually.be.rejected.and.be.instanceof(Errors.NotFoundError) }) }) describe('unArchiveAllDocs', function () { - it('should unarchive all inS3 docs', function (done) { - this.MongoManager.getArchivedProjectDocs = sinon - .stub() - .callsArgWith(1, null, this.archivedDocs) - this.DocArchiveManager.unarchiveDoc = sinon.stub().callsArgWith(2, null) - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, (err) => { - for (const doc of Array.from(this.archivedDocs)) { - this.DocArchiveManager.unarchiveDoc - .calledWith(this.project_id, doc._id) - .should.equal(true) - } - should.not.exist(err) - return done() - }) + it('should resolve with valid arguments', async function () { + await expect(DocArchiveManager.promises.unArchiveAllDocs(projectId)).to + .eventually.be.fulfilled }) - it('should return error if have no docs', function (done) { - this.MongoManager.getArchivedProjectDocs = sinon - .stub() - .callsArgWith(1, null, null) - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, (err) => { - should.exist(err) - return done() - }) + it('should unarchive all inS3 docs', async function () { + await DocArchiveManager.promises.unArchiveAllDocs(projectId) + + for (const doc of archivedDocs) { + expect(PersistorManager.getObjectStream).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${doc._id}` + ) + } }) - return it('should return the error', function (done) { - this.MongoManager.getArchivedProjectDocs = sinon - .stub() - .callsArgWith(1, this.error, null) - return this.DocArchiveManager.unArchiveAllDocs(this.project_id, (err) => { - err.should.equal(this.error) - return done() - }) + it('should return error if the project has no docs', async function () { + MongoManager.getArchivedProjectDocs.yields(null, null) + + await expect( + DocArchiveManager.promises.unArchiveAllDocs(projectId) + ).to.eventually.be.rejected.and.be.instanceof(Errors.NotFoundError) }) }) describe('destroyAllDocs', function () { - beforeEach(function () { - this.request.del = sinon - .stub() - .callsArgWith(1, null, { statusCode: 204 }, {}) - this.MongoManager.getProjectsDocs = sinon - .stub() - .callsArgWith(3, null, this.mixedDocs) - this.MongoManager.findDoc = sinon.stub().callsArgWith(3, null, null) - this.MongoManager.destroyDoc = sinon.stub().yields() - return Array.from(this.mixedDocs).map((doc) => - this.MongoManager.findDoc - .withArgs(this.project_id, doc._id) - .callsArgWith(3, null, doc) - ) + it('should resolve with valid arguments', async function () { + await expect(DocArchiveManager.promises.destroyAllDocs(projectId)).to + .eventually.be.fulfilled }) - it('should destroy all the docs', function (done) { - this.DocArchiveManager.destroyDoc = sinon.stub().callsArgWith(2, null) - return this.DocArchiveManager.destroyAllDocs(this.project_id, (err) => { - for (const doc of Array.from(this.mixedDocs)) { - this.DocArchiveManager.destroyDoc - .calledWith(this.project_id, doc._id) - .should.equal(true) - } - should.not.exist(err) - return done() - }) - }) + it('should delete all docs that are in s3 from s3', async function () { + await DocArchiveManager.promises.destroyAllDocs(projectId) - it('should only the s3 docs from s3', function (done) { - const docOpts = (doc) => { - return JSON.parse( - JSON.stringify({ - aws: { - key: this.settings.docstore.s3.key, - secret: this.settings.docstore.s3.secret, - bucket: this.settings.docstore.s3.bucket - }, - json: true, - timeout: 30 * 1000, - uri: `https://${this.settings.docstore.s3.bucket}.s3.amazonaws.com/${this.project_id}/${doc._id}` - }) + // not inS3 + for (const index of [0, 1, 4]) { + expect(PersistorManager.deleteObject).not.to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${mongoDocs[index]._id}` ) } - return this.DocArchiveManager.destroyAllDocs(this.project_id, (err) => { - let doc - expect(err).not.to.exist - - for (doc of Array.from(this.archivedDocs)) { - sinon.assert.calledWith(this.request.del, docOpts(doc)) - } - for (doc of Array.from(this.unarchivedDocs)) { - expect(this.request.del.calledWith(docOpts(doc))).to.equal(false) - } // no notCalledWith - - return done() - }) - }) - - return it('should remove the docs from mongo', function (done) { - this.DocArchiveManager.destroyAllDocs(this.project_id, (err) => { - return expect(err).not.to.exist - }) - - for (const doc of Array.from(this.mixedDocs)) { - sinon.assert.calledWith(this.MongoManager.destroyDoc, doc._id) + // inS3 + for (const index of [2, 3]) { + expect(PersistorManager.deleteObject).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${mongoDocs[index]._id}` + ) } - - return done() - }) - }) - - describe('_s3DocToMongoDoc', function () { - describe('with the old schema', function () { - return it('should return the docs lines', function (done) { - return this.DocArchiveManager._s3DocToMongoDoc( - ['doc', 'lines'], - (error, doc) => { - expect(doc).to.deep.equal({ - lines: ['doc', 'lines'] - }) - return done() - } - ) - }) }) - describe('with the new schema', function () { - it('should return the doc lines and ranges', function (done) { - this.RangeManager.jsonRangesToMongo = sinon - .stub() - .returns({ mongo: 'ranges' }) - return this.DocArchiveManager._s3DocToMongoDoc( - { - lines: ['doc', 'lines'], - ranges: { json: 'ranges' }, - schema_v: 1 - }, - (error, doc) => { - expect(doc).to.deep.equal({ - lines: ['doc', 'lines'], - ranges: { mongo: 'ranges' } - }) - return done() - } - ) - }) + it('should destroy all docs in mongo', async function () { + await DocArchiveManager.promises.destroyAllDocs(projectId) - return it('should return just the doc lines when there are no ranges', function (done) { - return this.DocArchiveManager._s3DocToMongoDoc( - { - lines: ['doc', 'lines'], - schema_v: 1 - }, - (error, doc) => { - expect(doc).to.deep.equal({ - lines: ['doc', 'lines'] - }) - return done() - } - ) - }) - }) - - return describe('with an unrecognised schema', function () { - return it('should return an error', function (done) { - return this.DocArchiveManager._s3DocToMongoDoc( - { - schema_v: 2 - }, - (error, doc) => { - expect(error).to.exist - return done() - } - ) - }) - }) - }) - - return describe('_mongoDocToS3Doc', function () { - describe('with a valid doc', function () { - return it('should return the json version', function (done) { - let doc - return this.DocArchiveManager._mongoDocToS3Doc( - (doc = { - lines: ['doc', 'lines'], - ranges: { mock: 'ranges' } - }), - (err, s3_doc) => { - expect(s3_doc).to.equal( - JSON.stringify({ - lines: ['doc', 'lines'], - ranges: { mock: 'ranges' }, - schema_v: 1 - }) - ) - return done() - } - ) - }) - }) - - describe('with null bytes in the result', function () { - beforeEach(function () { - this._stringify = JSON.stringify - return (JSON.stringify = sinon.stub().returns('{"bad": "\u0000"}')) - }) - - afterEach(function () { - return (JSON.stringify = this._stringify) - }) - - return it('should return an error', function (done) { - return this.DocArchiveManager._mongoDocToS3Doc( - { - lines: ['doc', 'lines'], - ranges: { mock: 'ranges' } - }, - (err, s3_doc) => { - expect(err).to.exist - return done() - } - ) - }) - }) - - return describe('without doc lines', function () { - return it('should return an error', function (done) { - return this.DocArchiveManager._mongoDocToS3Doc({}, (err, s3_doc) => { - expect(err).to.exist - return done() - }) - }) + for (const mongoDoc of mongoDocs) { + expect(MongoManager.destroyDoc).to.have.been.calledWith(mongoDoc._id) + } }) }) }) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 63b70493a5..e7f5baa567 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -38,7 +38,8 @@ describe('DocManager', function () { log: sinon.stub(), warn() {}, err() {} - }) + }), + './Errors': Errors } }) this.doc_id = ObjectId().toString() From fdefb311ab85dce43836a66a534332a7e7d8f099 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 24 Jul 2020 11:50:53 +0100 Subject: [PATCH 266/349] Fix sha1 package hashes --- services/docstore/package-lock.json | 54 ++++++++++++++--------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 636c1cf390..e7b6f6aa60 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1372,7 +1372,7 @@ "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "@types/long": { @@ -1661,7 +1661,7 @@ "ast-types-flow": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", "dev": true }, "astral-regex": { @@ -2213,7 +2213,7 @@ "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==", "dev": true }, "content-disposition": { @@ -2787,7 +2787,7 @@ "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -3248,7 +3248,7 @@ "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -4384,7 +4384,7 @@ "language-tags": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", "dev": true, "requires": { "language-subtag-registry": "~0.3.2" @@ -4403,7 +4403,7 @@ "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", "dev": true, "requires": { "graceful-fs": "^4.1.2", @@ -4415,7 +4415,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -4423,7 +4423,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -4453,7 +4453,7 @@ "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "lodash.has": { @@ -4877,7 +4877,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "locate-path": { @@ -4928,7 +4928,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true }, "yargs": { @@ -5073,7 +5073,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "path-to-regexp": { @@ -5232,7 +5232,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true }, "object-inspect": { @@ -5364,7 +5364,7 @@ "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -5382,7 +5382,7 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", "dev": true } } @@ -5420,7 +5420,7 @@ "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", "dev": true, "requires": { "error-ex": "^1.2.0" @@ -5476,7 +5476,7 @@ "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", "dev": true, "requires": { "pify": "^2.0.0" @@ -5485,7 +5485,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", "dev": true } } @@ -5516,7 +5516,7 @@ "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "integrity": "sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==", "dev": true, "requires": { "find-up": "^2.1.0" @@ -6327,7 +6327,7 @@ "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", "dev": true, "requires": { "load-json-file": "^2.0.0", @@ -6338,7 +6338,7 @@ "read-pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", "dev": true, "requires": { "find-up": "^2.0.0", @@ -6490,7 +6490,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "dev": true }, "require-main-filename": { @@ -6955,7 +6955,7 @@ "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=", + "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==", "dev": true }, "statsd-parser": { @@ -7676,13 +7676,13 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "string-width": { @@ -7698,7 +7698,7 @@ "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { "ansi-regex": "^3.0.0" From 268f436461931d59914f9bbd215606e0ae62d9b5 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 24 Jul 2020 11:51:18 +0100 Subject: [PATCH 267/349] Don't call AsyncPool with an empty array --- services/docstore/app/js/DocArchiveManager.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 8b9c44bbce..612b0da060 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -84,6 +84,10 @@ async function unArchiveAllDocs(projectId) { if (!docs) { throw new Errors.NotFoundError(`No docs for project ${projectId}`) } + if (!docs.length) { + // AsyncPool will throw an error with an empty array + return + } await AsyncPool(PARALLEL_JOBS, docs, (doc) => unarchiveDoc(projectId, doc._id) ) From 9724407e314ef5509deb1491ac23890db8d73af9 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 31 Jul 2020 16:20:07 +0100 Subject: [PATCH 268/349] Export .promises from MongoManager --- services/docstore/app/js/DocArchiveManager.js | 22 +++--- services/docstore/app/js/MongoManager.js | 18 ++--- .../test/unit/js/DocArchiveManagerTests.js | 74 +++++++++---------- .../test/unit/js/MongoManagerTests.js | 3 + 4 files changed, 56 insertions(+), 61 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 612b0da060..d369bbf645 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -1,5 +1,5 @@ -const { promisify, callbackify } = require('util') -const MongoManager = require('./MongoManager') +const { callbackify } = require('util') +const MongoManager = require('./MongoManager').promises const Errors = require('./Errors') const logger = require('logger-sharelatex') const settings = require('settings-sharelatex') @@ -29,7 +29,7 @@ module.exports = { } async function archiveAllDocs(projectId) { - const docs = await promisify(MongoManager.getProjectsDocs)( + const docs = await MongoManager.getProjectsDocs( projectId, { include_deleted: true }, { lines: true, ranges: true, rev: true, inS3: true } @@ -76,11 +76,11 @@ async function archiveDoc(projectId, doc) { await PersistorManager.sendStream(settings.docstore.bucket, key, stream, { sourceMd5: md5 }) - await promisify(MongoManager.markDocAsArchived)(doc._id, doc.rev) + await MongoManager.markDocAsArchived(doc._id, doc.rev) } async function unArchiveAllDocs(projectId) { - const docs = await promisify(MongoManager.getArchivedProjectDocs)(projectId) + const docs = await MongoManager.getArchivedProjectDocs(projectId) if (!docs) { throw new Errors.NotFoundError(`No docs for project ${projectId}`) } @@ -131,16 +131,12 @@ async function unarchiveDoc(projectId, docId) { } else { throw new Error("I don't understand the doc format in s3") } - await promisify(MongoManager.upsertIntoDocCollection)( - projectId, - docId, - mongoDoc - ) + await MongoManager.upsertIntoDocCollection(projectId, docId, mongoDoc) await PersistorManager.deleteObject(settings.docstore.bucket, key) } async function destroyAllDocs(projectId) { - const docs = await promisify(MongoManager.getProjectsDocs)( + const docs = await MongoManager.getProjectsDocs( projectId, { include_deleted: true }, { _id: 1 } @@ -157,7 +153,7 @@ async function destroyDoc(projectId, docId) { { project_id: projectId, doc_id: docId }, 'removing doc from mongo and persistor' ) - const doc = await promisify(MongoManager.findDoc)(projectId, docId, { + const doc = await MongoManager.findDoc(projectId, docId, { inS3: 1 }) if (!doc) { @@ -170,7 +166,7 @@ async function destroyDoc(projectId, docId) { `${projectId}/${docId}` ) } - await promisify(MongoManager.destroyDoc)(docId) + await MongoManager.destroyDoc(docId) } async function _streamToString(stream) { diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index b3e90c63c9..b6e90a7ad3 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -14,6 +14,7 @@ let MongoManager const { db, ObjectId } = require('./mongojs') const logger = require('logger-sharelatex') const metrics = require('metrics-sharelatex') +const { promisify } = require('util') module.exports = MongoManager = { findDoc(project_id, doc_id, filter, callback) { @@ -162,14 +163,11 @@ module.exports = MongoManager = { ) } } -;[ - 'findDoc', - 'getProjectsDocs', - 'getArchivedProjectDocs', - 'upsertIntoDocCollection', - 'markDocAsArchived', - 'getDocVersion', - 'setDocVersion' -].map((method) => + +const methods = Object.getOwnPropertyNames(MongoManager) + +module.exports.promises = {} +for (const method of methods) { metrics.timeAsyncMethod(MongoManager, method, 'mongo.MongoManager', logger) -) + module.exports.promises[method] = promisify(module.exports[method]) +} diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 9fa689d1dc..026c7654b4 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -123,17 +123,19 @@ describe('DocArchiveManager', function () { } MongoManager = { - markDocAsArchived: sinon.stub().yields(), - upsertIntoDocCollection: sinon.stub().yields(), - getProjectsDocs: sinon.stub().yields(null, mongoDocs), - getArchivedProjectDocs: sinon.stub().yields(null, archivedDocs), - findDoc: sinon.stub().yields(), - destroyDoc: sinon.stub().yields() + promises: { + markDocAsArchived: sinon.stub().resolves(), + upsertIntoDocCollection: sinon.stub().resolves(), + getProjectsDocs: sinon.stub().resolves(mongoDocs), + getArchivedProjectDocs: sinon.stub().resolves(archivedDocs), + findDoc: sinon.stub().resolves(), + destroyDoc: sinon.stub().resolves() + } } for (const mongoDoc of mongoDocs) { - MongoManager.findDoc - .withArgs(projectId, mongoDoc._id, sinon.match.any) - .yields(null, mongoDoc) + MongoManager.promises.findDoc + .withArgs(projectId, mongoDoc._id) + .resolves(mongoDoc) } DocArchiveManager = SandboxedModule.require(modulePath, { @@ -223,7 +225,7 @@ describe('DocArchiveManager', function () { it('should mark the doc as archived', async function () { await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) - expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + expect(MongoManager.promises.markDocAsArchived).to.have.been.calledWith( mongoDocs[0]._id, mongoDocs[0].rev ) @@ -270,7 +272,7 @@ describe('DocArchiveManager', function () { it('should update the doc lines in mongo', async function () { await DocArchiveManager.promises.unarchiveDoc(projectId, docId) expect( - MongoManager.upsertIntoDocCollection + MongoManager.promises.upsertIntoDocCollection ).to.have.been.calledWith(projectId, docId, { lines: mongoDocs[0].lines }) }) @@ -297,11 +299,9 @@ describe('DocArchiveManager', function () { it('should return the docs lines', async function () { await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect(MongoManager.upsertIntoDocCollection).to.have.been.calledWith( - projectId, - docId, - mongoDoc - ) + expect( + MongoManager.promises.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, mongoDoc) }) }) @@ -322,11 +322,9 @@ describe('DocArchiveManager', function () { it('should return the doc lines and ranges', async function () { await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect(MongoManager.upsertIntoDocCollection).to.have.been.calledWith( - projectId, - docId, - mongoDoc - ) + expect( + MongoManager.promises.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, mongoDoc) }) }) @@ -345,11 +343,9 @@ describe('DocArchiveManager', function () { it('should return only the doc lines', async function () { await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect(MongoManager.upsertIntoDocCollection).to.have.been.calledWith( - projectId, - docId, - mongoDoc - ) + expect( + MongoManager.promises.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, mongoDoc) }) }) @@ -435,27 +431,27 @@ describe('DocArchiveManager', function () { it('should archive all project docs which are not in s3', async function () { await DocArchiveManager.promises.archiveAllDocs(projectId) // not inS3 - expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + expect(MongoManager.promises.markDocAsArchived).to.have.been.calledWith( mongoDocs[0]._id ) - expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + expect(MongoManager.promises.markDocAsArchived).to.have.been.calledWith( mongoDocs[1]._id ) - expect(MongoManager.markDocAsArchived).to.have.been.calledWith( + expect(MongoManager.promises.markDocAsArchived).to.have.been.calledWith( mongoDocs[4]._id ) // inS3 - expect(MongoManager.markDocAsArchived).not.to.have.been.calledWith( - mongoDocs[2]._id - ) - expect(MongoManager.markDocAsArchived).not.to.have.been.calledWith( - mongoDocs[3]._id - ) + expect( + MongoManager.promises.markDocAsArchived + ).not.to.have.been.calledWith(mongoDocs[2]._id) + expect( + MongoManager.promises.markDocAsArchived + ).not.to.have.been.calledWith(mongoDocs[3]._id) }) it('should return error if the project has no docs', async function () { - MongoManager.getProjectsDocs.yields(null, null) + MongoManager.promises.getProjectsDocs.resolves(null) await expect( DocArchiveManager.promises.archiveAllDocs(projectId) @@ -481,7 +477,7 @@ describe('DocArchiveManager', function () { }) it('should return error if the project has no docs', async function () { - MongoManager.getArchivedProjectDocs.yields(null, null) + MongoManager.promises.getArchivedProjectDocs.resolves(null) await expect( DocArchiveManager.promises.unArchiveAllDocs(projectId) @@ -519,7 +515,9 @@ describe('DocArchiveManager', function () { await DocArchiveManager.promises.destroyAllDocs(projectId) for (const mongoDoc of mongoDocs) { - expect(MongoManager.destroyDoc).to.have.been.calledWith(mongoDoc._id) + expect(MongoManager.promises.destroyDoc).to.have.been.calledWith( + mongoDoc._id + ) } }) }) diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index f26e6539f1..fec3ec0682 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -29,6 +29,9 @@ describe('MongoManager', function () { }, 'metrics-sharelatex': { timeAsyncMethod: sinon.stub() }, 'logger-sharelatex': { log() {} } + }, + globals: { + console } }) this.project_id = ObjectId().toString() From cb8c2bf4b5ccc1cd02160fa0e447c16b54fd1fb0 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 31 Jul 2020 16:21:59 +0100 Subject: [PATCH 269/349] AsyncPool -> asyncPool --- services/docstore/app/js/DocArchiveManager.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index d369bbf645..e7fc4ee848 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -7,7 +7,7 @@ const crypto = require('crypto') const Streamifier = require('streamifier') const RangeManager = require('./RangeManager') const PersistorManager = require('./PersistorManager') -const AsyncPool = require('tiny-async-pool') +const asyncPool = require('tiny-async-pool') const PARALLEL_JOBS = 5 @@ -39,7 +39,7 @@ async function archiveAllDocs(projectId) { throw new Errors.NotFoundError(`No docs for project ${projectId}`) } - await AsyncPool( + await asyncPool( PARALLEL_JOBS, docs.filter((doc) => !doc.inS3), (doc) => archiveDoc(projectId, doc) @@ -85,10 +85,10 @@ async function unArchiveAllDocs(projectId) { throw new Errors.NotFoundError(`No docs for project ${projectId}`) } if (!docs.length) { - // AsyncPool will throw an error with an empty array + // asyncPool will throw an error with an empty array return } - await AsyncPool(PARALLEL_JOBS, docs, (doc) => + await asyncPool(PARALLEL_JOBS, docs, (doc) => unarchiveDoc(projectId, doc._id) ) } @@ -141,8 +141,8 @@ async function destroyAllDocs(projectId) { { include_deleted: true }, { _id: 1 } ) - if (docs) { - await AsyncPool(PARALLEL_JOBS, docs, (doc) => + if (docs && docs.length) { + await asyncPool(PARALLEL_JOBS, docs, (doc) => destroyDoc(projectId, doc._id) ) } From a4d0813acbc6b20799ee73c780d9504c5f27b3a4 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 31 Jul 2020 16:24:41 +0100 Subject: [PATCH 270/349] Update build scripts --- services/docstore/.github/dependabot.yml | 17 +++ services/docstore/Dockerfile | 2 - services/docstore/Jenkinsfile | 131 ----------------------- services/docstore/Makefile | 6 +- services/docstore/buildscript.txt | 4 +- services/docstore/docker-compose.ci.yml | 5 + services/docstore/docker-compose.yml | 11 +- services/docstore/nodemon.json | 1 - services/docstore/package.json | 2 +- 9 files changed, 35 insertions(+), 144 deletions(-) create mode 100644 services/docstore/.github/dependabot.yml delete mode 100644 services/docstore/Jenkinsfile diff --git a/services/docstore/.github/dependabot.yml b/services/docstore/.github/dependabot.yml new file mode 100644 index 0000000000..c6f98d843d --- /dev/null +++ b/services/docstore/.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/docstore/Dockerfile b/services/docstore/Dockerfile index b07f7117bc..78a715757d 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -15,8 +15,6 @@ RUN npm ci --quiet COPY . /app - - FROM base COPY --from=app /app /app diff --git a/services/docstore/Jenkinsfile b/services/docstore/Jenkinsfile deleted file mode 100644 index 15471816e2..0000000000 --- a/services/docstore/Jenkinsfile +++ /dev/null @@ -1,131 +0,0 @@ -String cron_string = BRANCH_NAME == "master" ? "@daily" : "" - -pipeline { - agent any - - environment { - GIT_PROJECT = "docstore" - JENKINS_WORKFLOW = "docstore-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/docstore/Makefile b/services/docstore/Makefile index 7bd0895b81..77f11edeea 100644 --- a/services/docstore/Makefile +++ b/services/docstore/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/docstore/buildscript.txt b/services/docstore/buildscript.txt index a8929bd59f..d4e653d97b 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -1,10 +1,8 @@ docstore ---acceptance-creds=None --dependencies=mongo,gcs --docker-repos=gcr.io/overleaf-ops --env-add= --env-pass-through= ---language=es --node-version=10.21.0 --public-repo=True ---script-version=2.3.0 +--script-version=3.2.0 diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 3510433789..d2ad377bcd 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -11,11 +11,15 @@ services: command: npm run test:unit:_run environment: NODE_ENV: test + NODE_OPTIONS: "--unhandled-rejections=strict" test_acceptance: build: . image: ci/$PROJECT_NAME:$BRANCH_NAME-$BUILD_NUMBER + extends: + file: docker-compose-config.yml + service: ci environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis @@ -27,6 +31,7 @@ services: STORAGE_EMULATOR_HOST: http://gcs:9090/storage/v1 MOCHA_GREP: ${MOCHA_GREP} NODE_ENV: test + NODE_OPTIONS: "--unhandled-rejections=strict" depends_on: mongo: condition: service_healthy diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 02bf2410af..40e0d9af62 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -13,14 +13,18 @@ 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: - image: node:10 + image: node:10.21.0 volumes: - .:/app working_dir: /app + extends: + file: docker-compose-config.yml + service: dev environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis @@ -33,13 +37,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 gcs: condition: service_healthy - command: npm run test:acceptance + command: npm run --silent test:acceptance mongo: image: mongo:3.6 diff --git a/services/docstore/nodemon.json b/services/docstore/nodemon.json index 5826281b84..e3e8817d90 100644 --- a/services/docstore/nodemon.json +++ b/services/docstore/nodemon.json @@ -8,7 +8,6 @@ "execMap": { "js": "npm run start" }, - "watch": [ "app/js/", "app.js", diff --git a/services/docstore/package.json b/services/docstore/package.json index e53077de30..5dc0415d9b 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -14,7 +14,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" }, From a18146612a2fe81d9c40697dfd8a46501374c02d Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 31 Jul 2020 16:25:33 +0100 Subject: [PATCH 271/349] Remove unhandled-promise-rejection handler --- .../docstore/test/acceptance/js/helpers/DocstoreApp.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 38162da8f2..67dc1760e4 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -15,13 +15,6 @@ const app = require('../../../../app') require('logger-sharelatex').logger.level('error') const settings = require('settings-sharelatex') -// treat unhandled promise rejections as failures -process.on('unhandledRejection', (e) => { - // eslint-disable-next-line no-console - console.log('** Unhandled Promise Rejection **\n', e) - throw e -}) - module.exports = { running: false, initing: false, From e4d7c253c055acba68777c099303f54b4893b37d Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Mon, 10 Aug 2020 11:55:39 +0100 Subject: [PATCH 272/349] Fallback to AWS_BUCKET env var in settings for backwards compatiblity --- services/docstore/config/settings.defaults.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 0483ecbc3e..c538b79045 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -21,7 +21,7 @@ const Settings = { healthCheck: { project_id: process.env.HEALTH_CHECK_PROJECT_ID }, - bucket: process.env.BUCKET_NAME || 'bucket', + bucket: process.env.BUCKET_NAME || process.env.AWS_BUCKET || 'bucket', gcs: { unlockBeforeDelete: process.env.GCS_UNLOCK_BEFORE_DELETE === 'true', deletedBucketSuffix: process.env.GCS_DELETED_BUCKET_SUFFIX, From 1575cd41ebf8ac5deccf199ec8121e6020f23011 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Mon, 10 Aug 2020 15:44:41 +0100 Subject: [PATCH 273/349] Don't pass empty array to asyncPool when archiving --- services/docstore/app/js/DocArchiveManager.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index e7fc4ee848..d564113c9b 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -39,11 +39,12 @@ async function archiveAllDocs(projectId) { throw new Errors.NotFoundError(`No docs for project ${projectId}`) } - await asyncPool( - PARALLEL_JOBS, - docs.filter((doc) => !doc.inS3), - (doc) => archiveDoc(projectId, doc) - ) + const docsToArchive = docs.filter((doc) => !doc.inS3) + if (docsToArchive.length) { + await asyncPool(PARALLEL_JOBS, docsToArchive, (doc) => + archiveDoc(projectId, doc) + ) + } } async function archiveDoc(projectId, doc) { From d5214d4351c7b3af7aab2948d98984aa9e546c73 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Mon, 10 Aug 2020 16:53:18 +0100 Subject: [PATCH 274/349] Update object-persistor module --- services/docstore/package-lock.json | 176 +++------------------------- 1 file changed, 15 insertions(+), 161 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index e7b6f6aa60..9afa158ecb 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -664,7 +664,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.1.2.tgz", "integrity": "sha512-j2blsBVv6Tt5Z7ff6kOSIg5zVQPdlcTQh/4zMb9h7xMj4ekwndQA60le8c1KEa+Y6SR3EM6ER2AvKYK53P7vdQ==", - "dev": true, "requires": { "@google-cloud/common": "^3.0.0", "@google-cloud/paginator": "^3.0.0", @@ -694,7 +693,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.3.2.tgz", "integrity": "sha512-W7JRLBEJWYtZQQuGQX06U6GBOSLrSrlvZxv6kGNwJtFrusu6AVgZltQ9Pajuz9Dh9aSXy9aTnBcyxn2/O0EGUw==", - "dev": true, "requires": { "@google-cloud/projectify": "^2.0.0", "@google-cloud/promisify": "^2.0.0", @@ -711,7 +709,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "dev": true, "requires": { "end-of-stream": "^1.4.1", "inherits": "^2.0.3", @@ -725,7 +722,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.2.tgz", "integrity": "sha512-kXK+Dbz4pNvv8bKU80Aw5HsIdgOe0WuMTd8/fI6tkANUxzvJOVJQQRsWVqcHSWK2RXHPTA9WBniUCwY6gAJDXw==", - "dev": true, "requires": { "arrify": "^2.0.0", "extend": "^3.0.2" @@ -734,20 +730,17 @@ "@google-cloud/projectify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", - "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", - "dev": true + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" }, "@google-cloud/promisify": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.2.tgz", - "integrity": "sha512-EvuabjzzZ9E2+OaYf+7P9OAiiwbTxKYL0oGLnREQd+Su2NTQBpomkdlkBowFvyWsaV0d1sSGxrKpSNcrhPqbxg==", - "dev": true + "integrity": "sha512-EvuabjzzZ9E2+OaYf+7P9OAiiwbTxKYL0oGLnREQd+Su2NTQBpomkdlkBowFvyWsaV0d1sSGxrKpSNcrhPqbxg==" }, "gaxios": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.4.tgz", "integrity": "sha512-97NmFuMETFQh6gqPUxkqjxRMjmY8aRKRMphIkgO/b90AbCt5wAVuXsp8oWjIXlLN2pIK/fsXD8edcM7ULkFMLg==", - "dev": true, "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", @@ -760,7 +753,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -769,7 +761,6 @@ "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -780,7 +771,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.0.tgz", "integrity": "sha512-kWD3sdGmIix6w7c8ZdVKxWq+3YwVPGWz+Mq0wRZXayEKY/YHb63b8uphfBzcFDmyq8frD9+UTc3wLyOhltRbtg==", - "dev": true, "requires": { "http-proxy-agent": "^4.0.0", "https-proxy-agent": "^5.0.0", @@ -793,7 +783,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, "requires": { "readable-stream": "3" } @@ -801,8 +790,7 @@ "uuid": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", - "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==", - "dev": true + "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" } } }, @@ -1048,7 +1036,7 @@ "integrity": "sha512-LsM2s6Iy9G97ktPo0ys4VxtI/m3ahc1ZHwjo5XnhXtjeIkkkVAehsrcRRoV/yWepPjymB0oZonhcfojpjYR/tg==" }, "@overleaf/object-persistor": { - "version": "git+https://github.com/overleaf/object-persistor.git#8b8bc4b8d1e8b8aa3ca9245691d6ddd69d663d06", + "version": "git+https://github.com/overleaf/object-persistor.git#4ca62157a2beb747e9a56da3ce1569124b90378a", "from": "git+https://github.com/overleaf/object-persistor.git", "requires": { "@google-cloud/storage": "^5.1.2", @@ -1062,95 +1050,6 @@ "tiny-async-pool": "^1.1.0" }, "dependencies": { - "@google-cloud/common": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.3.2.tgz", - "integrity": "sha512-W7JRLBEJWYtZQQuGQX06U6GBOSLrSrlvZxv6kGNwJtFrusu6AVgZltQ9Pajuz9Dh9aSXy9aTnBcyxn2/O0EGUw==", - "requires": { - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^6.0.0", - "retry-request": "^4.1.1", - "teeny-request": "^7.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - } - } - }, - "@google-cloud/paginator": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.2.tgz", - "integrity": "sha512-kXK+Dbz4pNvv8bKU80Aw5HsIdgOe0WuMTd8/fI6tkANUxzvJOVJQQRsWVqcHSWK2RXHPTA9WBniUCwY6gAJDXw==", - "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - } - }, - "@google-cloud/projectify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", - "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" - }, - "@google-cloud/promisify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.2.tgz", - "integrity": "sha512-EvuabjzzZ9E2+OaYf+7P9OAiiwbTxKYL0oGLnREQd+Su2NTQBpomkdlkBowFvyWsaV0d1sSGxrKpSNcrhPqbxg==" - }, - "@google-cloud/storage": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.1.2.tgz", - "integrity": "sha512-j2blsBVv6Tt5Z7ff6kOSIg5zVQPdlcTQh/4zMb9h7xMj4ekwndQA60le8c1KEa+Y6SR3EM6ER2AvKYK53P7vdQ==", - "requires": { - "@google-cloud/common": "^3.0.0", - "@google-cloud/paginator": "^3.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.0", - "compressible": "^2.0.12", - "concat-stream": "^2.0.0", - "date-and-time": "^0.13.0", - "duplexify": "^3.5.0", - "extend": "^3.0.2", - "gaxios": "^3.0.0", - "gcs-resumable-upload": "^3.0.0", - "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", - "mime-types": "^2.0.8", - "onetime": "^5.1.0", - "p-limit": "^3.0.1", - "pumpify": "^2.0.0", - "readable-stream": "^3.4.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "through2": "^4.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "gaxios": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.0.4.tgz", - "integrity": "sha512-97NmFuMETFQh6gqPUxkqjxRMjmY8aRKRMphIkgO/b90AbCt5wAVuXsp8oWjIXlLN2pIK/fsXD8edcM7ULkFMLg==", - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.3.0" - } - }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -1167,52 +1066,7 @@ "node-uuid": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==" - }, - "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", - "requires": { - "p-try": "^2.0.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "teeny-request": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.0.tgz", - "integrity": "sha512-kWD3sdGmIix6w7c8ZdVKxWq+3YwVPGWz+Mq0wRZXayEKY/YHb63b8uphfBzcFDmyq8frD9+UTc3wLyOhltRbtg==", - "requires": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.2.0", - "stream-events": "^1.0.5", - "uuid": "^8.0.0" - }, - "dependencies": { - "uuid": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.2.0.tgz", - "integrity": "sha512-CYpGiFTUrmI6OBMkAdjSDM0k5h8SkkiTP4WAjQgDgNB1S3Ou9VBEvr6q0Kv2H1mMk7IWfxYGpMH5sd5AvcIV2Q==" - } - } - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "requires": { - "readable-stream": "3" - } + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" } } }, @@ -1693,9 +1547,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sdk": { - "version": "2.718.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.718.0.tgz", - "integrity": "sha512-YMWR1RJ3VuSbUOGeOfDw2QqRzwX51oa9TCm2G6SW+JywJUy0FTxi/Nj0VjVEQvKC0GqGu5QCgUTaarF7S0nQdw==", + "version": "2.729.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.729.0.tgz", + "integrity": "sha512-x5q/+9wM37tBYCmYNGMj+aU9qeXqhbUH0Dz3wlSpAW55+N4NwlBbpqhyCV3oF9bePEJtEnxLGWNXpb9BNWNhew==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -3056,7 +2910,7 @@ "events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==" + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" }, "express": { "version": "4.17.1", @@ -4247,7 +4101,7 @@ "jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", - "integrity": "sha512-+kHj8HXArPfpPEKGLZ+kB5ONRTCiGQXo8RQYL0hH8t6pWXUBBK5KkkQmTNOwKK4LEsd0yTsgtjJVm4UBSZea4w==" + "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" }, "js-tokens": { "version": "4.0.0", @@ -6249,7 +6103,7 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==" + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" }, "qs": { "version": "6.7.0", @@ -6259,7 +6113,7 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==" + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, "quick-lru": { "version": "4.0.1", @@ -6630,7 +6484,7 @@ "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, "semver": { "version": "5.5.0", @@ -7512,7 +7366,7 @@ "url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", - "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", "requires": { "punycode": "1.3.2", "querystring": "0.2.0" @@ -7785,7 +7639,7 @@ "xmlbuilder": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==" + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, "xtend": { "version": "4.0.2", From d1da5e43af1b76bd172b4d94b148f185ea92adc9 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Wed, 12 Aug 2020 15:17:06 +0100 Subject: [PATCH 275/349] [misc] bump logger-sharelatex to version 2.2.0 --- services/docstore/.gitignore | 3 + services/docstore/app/js/DocArchiveManager.js | 12 +-- services/docstore/app/js/DocManager.js | 8 +- services/docstore/app/js/Errors.js | 2 +- services/docstore/app/js/HealthChecker.js | 8 +- services/docstore/app/js/HttpController.js | 4 +- services/docstore/app/js/MongoManager.js | 34 ++++---- services/docstore/app/js/RangeManager.js | 2 +- services/docstore/app/js/mongojs.js | 2 +- services/docstore/buildscript.txt | 2 +- services/docstore/config/settings.defaults.js | 18 ++--- services/docstore/docker-compose.ci.yml | 2 +- services/docstore/docker-compose.yml | 2 +- services/docstore/package-lock.json | 75 +++++++----------- services/docstore/package.json | 18 ++--- .../test/acceptance/js/ArchiveDocsTests.js | 40 +++++----- .../test/acceptance/js/GettingAllDocsTests.js | 10 +-- .../test/acceptance/js/GettingDocsTests.js | 8 +- .../test/acceptance/js/UpdatingDocsTests.js | 16 ++-- .../test/acceptance/js/helpers/DocstoreApp.js | 2 +- .../acceptance/js/helpers/DocstoreClient.js | 18 ++--- .../test/unit/js/DocArchiveManagerTests.js | 64 +++++++-------- .../docstore/test/unit/js/DocManagerTests.js | 44 +++++------ .../test/unit/js/HttpControllerTests.js | 70 ++++++++--------- .../test/unit/js/MongoManagerTests.js | 28 +++---- .../test/unit/js/RangeManagerTests.js | 78 +++++++++---------- 26 files changed, 277 insertions(+), 293 deletions(-) diff --git a/services/docstore/.gitignore b/services/docstore/.gitignore index 50678c09e9..80bac793a7 100644 --- a/services/docstore/.gitignore +++ b/services/docstore/.gitignore @@ -1,2 +1,5 @@ node_modules forever + +# managed by dev-environment$ bin/update_build_scripts +.npmrc diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index d564113c9b..9dd542e0ab 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -24,8 +24,8 @@ module.exports = { unArchiveAllDocs, unarchiveDoc, destroyAllDocs, - destroyDoc - } + destroyDoc, + }, } async function archiveAllDocs(projectId) { @@ -61,7 +61,7 @@ async function archiveDoc(projectId, doc) { const json = JSON.stringify({ lines: doc.lines, ranges: doc.ranges, - schema_v: 1 + schema_v: 1, }) // this should never happen, but protects against memory-corruption errors that @@ -75,7 +75,7 @@ async function archiveDoc(projectId, doc) { const md5 = crypto.createHash('md5').update(json).digest('hex') const stream = Streamifier.createReadStream(json) await PersistorManager.sendStream(settings.docstore.bucket, key, stream, { - sourceMd5: md5 + sourceMd5: md5, }) await MongoManager.markDocAsArchived(doc._id, doc.rev) } @@ -115,7 +115,7 @@ async function unarchiveDoc(projectId, docId) { throw new Errors.Md5MismatchError('md5 mismatch when downloading doc', { key, sourceMd5, - md5 + md5, }) } @@ -155,7 +155,7 @@ async function destroyDoc(projectId, docId) { 'removing doc from mongo and persistor' ) const doc = await MongoManager.findDoc(projectId, docId, { - inS3: 1 + inS3: 1, }) if (!doc) { throw new Errors.NotFoundError('Doc not found in Mongo') diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index edd9c0f1cd..2b8b3106e3 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -103,7 +103,7 @@ module.exports = DocManager = { deleted: true, version: true, ranges: true, - inS3: true + inS3: true, }, function (err, doc) { if (err != null) { @@ -175,7 +175,7 @@ module.exports = DocManager = { lines: true, version: true, ranges: true, - inS3: true + inS3: true, }, function (err, doc) { let updateLines, updateRanges, updateVersion @@ -238,7 +238,7 @@ module.exports = DocManager = { project_id, doc_id, oldVersion: doc != null ? doc.version : undefined, - newVersion: version + newVersion: version, }, 'updating doc version' ) @@ -288,5 +288,5 @@ module.exports = DocManager = { } return MongoManager.markDocAsDeleted(project_id, doc_id, callback) }) - } + }, } diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index 6a74485494..4eaa5481d3 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -6,5 +6,5 @@ class Md5MismatchError extends OError {} module.exports = { Md5MismatchError, - ...Errors + ...Errors, } diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 70ebc85ad9..5328fbf616 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -26,11 +26,11 @@ module.exports = { const url = `http://localhost:${port}/project/${project_id}/doc/${doc_id}` const lines = [ 'smoke test - delete me', - `${crypto.randomBytes(32).toString('hex')}` + `${crypto.randomBytes(32).toString('hex')}`, ] const getOpts = () => ({ url, - timeout: 3000 + timeout: 3000, }) logger.log({ lines, url, doc_id, project_id }, 'running health check') const jobs = [ @@ -61,8 +61,8 @@ module.exports = { }) }, (cb) => db.docs.remove({ _id: doc_id, project_id }, cb), - (cb) => db.docOps.remove({ doc_id }, cb) + (cb) => db.docOps.remove({ doc_id }, cb), ] return async.series(jobs, callback) - } + }, } diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 50c779736c..7503762168 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -157,7 +157,7 @@ module.exports = HttpController = { } return res.json({ modified, - rev + rev, }) } ) @@ -259,5 +259,5 @@ module.exports = HttpController = { return res.sendStatus(200) } }) - } + }, } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index b6e90a7ad3..d419132f0f 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -24,7 +24,7 @@ module.exports = MongoManager = { return db.docs.find( { _id: ObjectId(doc_id.toString()), - project_id: ObjectId(project_id.toString()) + project_id: ObjectId(project_id.toString()), }, filter, function (error, docs) { @@ -50,7 +50,7 @@ module.exports = MongoManager = { getArchivedProjectDocs(project_id, callback) { const query = { project_id: ObjectId(project_id.toString()), - inS3: true + inS3: true, } return db.docs.find(query, {}, callback) }, @@ -59,11 +59,11 @@ module.exports = MongoManager = { const update = { $set: updates, $inc: { - rev: 1 + rev: 1, }, $unset: { - inS3: true - } + inS3: true, + }, } update.$set.project_id = ObjectId(project_id) return db.docs.update( @@ -78,10 +78,10 @@ module.exports = MongoManager = { return db.docs.update( { _id: ObjectId(doc_id), - project_id: ObjectId(project_id) + project_id: ObjectId(project_id), }, { - $set: { deleted: true } + $set: { deleted: true }, }, callback ) @@ -90,14 +90,14 @@ module.exports = MongoManager = { markDocAsArchived(doc_id, rev, callback) { const update = { $set: {}, - $unset: {} + $unset: {}, } update.$set.inS3 = true update.$unset.lines = true update.$unset.ranges = true const query = { _id: doc_id, - rev + rev, } return db.docs.update(query, update, (err) => callback(err)) }, @@ -108,10 +108,10 @@ module.exports = MongoManager = { } return db.docOps.find( { - doc_id: ObjectId(doc_id) + doc_id: ObjectId(doc_id), }, { - version: 1 + version: 1, }, function (error, docs) { if (error != null) { @@ -132,13 +132,13 @@ module.exports = MongoManager = { } return db.docOps.update( { - doc_id: ObjectId(doc_id) + doc_id: ObjectId(doc_id), }, { - $set: { version } + $set: { version }, }, { - upsert: true + upsert: true, }, callback ) @@ -147,7 +147,7 @@ module.exports = MongoManager = { destroyDoc(doc_id, callback) { return db.docs.remove( { - _id: ObjectId(doc_id) + _id: ObjectId(doc_id), }, function (err) { if (err != null) { @@ -155,13 +155,13 @@ module.exports = MongoManager = { } return db.docOps.remove( { - doc_id: ObjectId(doc_id) + doc_id: ObjectId(doc_id), }, callback ) } ) - } + }, } const methods = Object.getOwnPropertyNames(MongoManager) diff --git a/services/docstore/app/js/RangeManager.js b/services/docstore/app/js/RangeManager.js index b11019657f..083cdf0486 100644 --- a/services/docstore/app/js/RangeManager.js +++ b/services/docstore/app/js/RangeManager.js @@ -65,5 +65,5 @@ module.exports = RangeManager = { } catch (error) { return data } - } + }, } diff --git a/services/docstore/app/js/mongojs.js b/services/docstore/app/js/mongojs.js index 41f3bec470..44b9d64bf0 100644 --- a/services/docstore/app/js/mongojs.js +++ b/services/docstore/app/js/mongojs.js @@ -5,5 +5,5 @@ const mongojs = require('mongojs') const db = mongojs(Settings.mongo.url, ['docs', 'docOps']) module.exports = { db, - ObjectId: mongojs.ObjectId + ObjectId: mongojs.ObjectId, } diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index d4e653d97b..53561414dc 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -5,4 +5,4 @@ docstore --env-pass-through= --node-version=10.21.0 --public-repo=True ---script-version=3.2.0 +--script-version=3.3.2 diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index c538b79045..f9193f1eb0 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -10,8 +10,8 @@ const Settings = { internal: { docstore: { port: 3016, - host: process.env.LISTEN_ADDRESS || 'localhost' - } + host: process.env.LISTEN_ADDRESS || 'localhost', + }, }, mongo: {}, @@ -19,17 +19,17 @@ const Settings = { docstore: { backend: process.env.BACKEND || 's3', healthCheck: { - project_id: process.env.HEALTH_CHECK_PROJECT_ID + project_id: process.env.HEALTH_CHECK_PROJECT_ID, }, bucket: process.env.BUCKET_NAME || process.env.AWS_BUCKET || 'bucket', gcs: { unlockBeforeDelete: process.env.GCS_UNLOCK_BEFORE_DELETE === 'true', deletedBucketSuffix: process.env.GCS_DELETED_BUCKET_SUFFIX, - deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50 - } + deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50, + }, }, - max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024 // 2mb + max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024, // 2mb } if (process.env.MONGO_CONNECTION_STRING != null) { @@ -51,7 +51,7 @@ if ( bucket: process.env.AWS_BUCKET, endpoint: process.env.AWS_S3_ENDPOINT, pathStyle: process.env.AWS_S3_PATH_STYLE, - partSize: parseInt(process.env.AWS_S3_PARTSIZE) || 100 * 1024 * 1024 + partSize: parseInt(process.env.AWS_S3_PARTSIZE) || 100 * 1024 * 1024, } } @@ -59,7 +59,7 @@ if (process.env.GCS_API_ENDPOINT) { Settings.docstore.gcs.endpoint = { apiEndpoint: process.env.GCS_API_ENDPOINT, apiScheme: process.env.GCS_API_SCHEME, - projectId: process.env.GCS_PROJECT_ID + projectId: process.env.GCS_PROJECT_ID, } } @@ -69,7 +69,7 @@ if (process.env.FALLBACK_BACKEND) { // mapping of bucket names on the fallback, to bucket names on the primary. // e.g. { myS3UserFilesBucketName: 'myGoogleUserFilesBucketName' } buckets: JSON.parse(process.env.FALLBACK_BUCKET_MAPPING || '{}'), - copyOnMiss: process.env.COPY_ON_MISS === 'true' + copyOnMiss: process.env.COPY_ON_MISS === 'true', } } diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index d2ad377bcd..b08834d1e6 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -49,7 +49,7 @@ services: command: tar -czf /tmp/build/build.tar.gz --exclude=build.tar.gz --exclude-vcs . user: root mongo: - image: mongo:3.6 + image: mongo:4.0 gcs: build: context: test/acceptance/deps diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 40e0d9af62..4ea846b682 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -47,7 +47,7 @@ services: command: npm run --silent test:acceptance mongo: - image: mongo:3.6 + image: mongo:4.0 gcs: build: diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 9afa158ecb..6b6807c967 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -993,9 +993,9 @@ } }, "@grpc/proto-loader": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.4.tgz", - "integrity": "sha512-HTM4QpI9B2XFkPz7pjwMyMgZchJ93TVkL3kWPW8GDMDKYxsMnmf4w2TNMJK7+KNiYHS5cJrCEAFlF+AwtXWVPA==", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.5.tgz", + "integrity": "sha512-WwN9jVNdHRQoOBo9FDH7qU+mgfjPc8GygPYms3M+y3fbQLfnCe/Kv/E01t7JRgnrsOHH8euvSbed3mIalXhwqQ==", "requires": { "lodash.camelcase": "^4.3.0", "protobufjs": "^6.8.6" @@ -1760,7 +1760,6 @@ "version": "1.8.14", "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.14.tgz", "integrity": "sha512-LlahJUxXzZLuw/hetUQJmRgZ1LF6+cr5TPpRj6jf327AsiIq2jhYEH4oqUUkVKTor+9w2BT3oxVwhzE5lw9tcg==", - "dev": true, "requires": { "dtrace-provider": "~0.8", "moment": "^2.19.3", @@ -1869,7 +1868,7 @@ "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" }, "check-error": { "version": "1.0.2", @@ -2155,7 +2154,7 @@ "crypt": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" }, "crypto-random-string": { "version": "2.0.0", @@ -2165,7 +2164,7 @@ "d64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", - "integrity": "sha512-5eNy3WZziVYnrogqgXhcdEmqcDB2IHurTqLcrgssJsfkMVCUoUaZpK6cJjxxvLV2dUm5SuJMNcYfVGoin9UIRw==" + "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" }, "damerau-levenshtein": { "version": "1.0.6", @@ -2584,12 +2583,6 @@ "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", "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==", - "dev": true - }, "eslint-plugin-es": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", @@ -4292,12 +4285,12 @@ "lodash.at": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha512-GOTh0SEp+Yosnlpjic+8cl2WM9MykorogkGA9xyIFkkObQ3H3kNZqZ+ohuq4K3FrSVo7hMcZBMataJemrxC3BA==" + "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=" }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, "lodash.flattendeep": { "version": "4.4.0", @@ -4313,7 +4306,7 @@ "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==" + "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" }, "lodash.memoize": { "version": "4.1.2", @@ -4353,28 +4346,16 @@ } }, "logger-sharelatex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-2.1.1.tgz", - "integrity": "sha512-qqSrBqUgHWnStxtTZ/fSsqPxj9Ju9onok7Vfm3bv5MS702jH+hRsCSA9oXOMvOLcWJrZFnhCZaLGeOvXToUaxw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/logger-sharelatex/-/logger-sharelatex-2.2.0.tgz", + "integrity": "sha512-ko+OmE25XHJJCiz1R9EgwlfM7J/5olpunUfR3WcfuqOQrcUqsdBrDA2sOytngT0ViwjCR0Fh4qZVPwEWfmrvwA==", "requires": { "@google-cloud/logging-bunyan": "^3.0.0", "@overleaf/o-error": "^3.0.0", "bunyan": "^1.8.14", + "node-fetch": "^2.6.0", "raven": "^2.6.4", "yn": "^4.0.0" - }, - "dependencies": { - "bunyan": { - "version": "1.8.14", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.14.tgz", - "integrity": "sha512-LlahJUxXzZLuw/hetUQJmRgZ1LF6+cr5TPpRj6jf327AsiIq2jhYEH4oqUUkVKTor+9w2BT3oxVwhzE5lw9tcg==", - "requires": { - "dtrace-provider": "~0.8", - "moment": "^2.19.3", - "mv": "~2", - "safe-json-stringify": "~1" - } - } } }, "loglevel": { @@ -4506,13 +4487,13 @@ "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==" }, "md5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", - "integrity": "sha512-PlGG4z5mBANDGCKsYQe0CaUYHdZYZt8ZPZLmEt+Urf0W4GlpTX4HescwHU+dc9+Z/G/vZKYZYFrwgm9VxK6QOQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", + "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", "requires": { - "charenc": "~0.0.1", - "crypt": "~0.0.1", - "is-buffer": "~1.1.1" + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" }, "dependencies": { "is-buffer": { @@ -6019,9 +6000,9 @@ } }, "protobufjs": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.9.0.tgz", - "integrity": "sha512-LlGVfEWDXoI/STstRDdZZKb/qusoAWUnmLg9R8OLSO473mBLWHowx8clbX5/+mKDEI+v7GzjoK9tRPZMMcoTrg==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.1.tgz", + "integrity": "sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -6147,12 +6128,12 @@ "cookie": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==" + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" }, "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==" + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, "uuid": { "version": "3.3.2", @@ -7163,7 +7144,7 @@ "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==" + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, "tiny-async-pool": { "version": "1.1.0", @@ -7196,7 +7177,7 @@ "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" }, "to-regex-range": { "version": "5.0.1", @@ -7210,7 +7191,7 @@ "to-snake-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==", + "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", "requires": { "to-space-case": "^1.0.0" } @@ -7218,7 +7199,7 @@ "to-space-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", "requires": { "to-no-case": "^1.0.0" } diff --git a/services/docstore/package.json b/services/docstore/package.json index 5dc0415d9b..8ecba94090 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -23,7 +23,7 @@ "async": "^2.6.3", "body-parser": "^1.19.0", "express": "^4.17.1", - "logger-sharelatex": "^2.1.1", + "logger-sharelatex": "^2.2.0", "metrics-sharelatex": "^2.7.0", "mongojs": "3.1.0", "settings-sharelatex": "^1.1.0", @@ -38,22 +38,22 @@ "chai": "~4.2.0", "chai-as-promised": "^7.1.1", "eslint": "^6.8.0", - "eslint-config-prettier": "^6.11.0", - "eslint-config-standard": "^14.1.1", + "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.2.0", - "eslint-plugin-chai-friendly": "^0.6.0", - "eslint-plugin-import": "^2.22.0", + "eslint-plugin-chai-expect": "^2.1.0", + "eslint-plugin-chai-friendly": "^0.5.0", + "eslint-plugin-import": "^2.20.1", "eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-mocha": "^6.3.0", - "eslint-plugin-node": "^11.1.0", - "eslint-plugin-prettier": "^3.1.4", + "eslint-plugin-node": "^11.0.0", + "eslint-plugin-prettier": "^3.1.2", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-react": "^7.20.3", "eslint-plugin-standard": "^4.0.1", "mocha": "^7.2.0", - "prettier": "^2.0.5", + "prettier": "^2.0.0", "prettier-eslint-cli": "^5.0.0", "request": "~2.88.2", "sandboxed-module": "~2.0.4", diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 959af6715b..95fe5d58fa 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -51,14 +51,14 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: {}, - version: 2 + version: 2, }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], ranges: {}, - version: 4 - } + version: 4, + }, ] const jobs = Array.from(this.docs).map((doc) => ((doc) => { @@ -173,7 +173,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -287,7 +287,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: [big_line, big_line, big_line, big_line], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -758,10 +758,10 @@ describe('Archiving', function () { 'Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue', 'But now...\u001b[20Cfor my greatest trick...\u001b[8m', 'The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]', - 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗' + 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗', ], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -857,17 +857,17 @@ describe('Archiving', function () { op: { i: 'foo', p: 24 }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-27T16:10:44.194Z') - } + ts: new Date('2017-01-27T16:10:44.194Z'), + }, }, { id: ObjectId(), op: { d: 'bar', p: 50 }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-27T18:10:44.194Z') - } - } + ts: new Date('2017-01-27T18:10:44.194Z'), + }, + }, ], comments: [ { @@ -875,12 +875,12 @@ describe('Archiving', function () { op: { c: 'comment', p: 284, t: ObjectId() }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-26T14:22:04.869Z') - } - } - ] + ts: new Date('2017-01-26T14:22:04.869Z'), + }, + }, + ], }, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -971,7 +971,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['abc', 'def', 'ghi'], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -1067,7 +1067,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['abc', 'def', 'ghi'], ranges: {}, - version: 2 + version: 2, } uploadContent( `${this.project_id}/${this.doc._id}`, @@ -1079,7 +1079,7 @@ describe('Archiving', function () { project_id: this.project_id, _id: this.doc._id, rev: this.doc.version, - inS3: true + inS3: true, }, (error) => { if (error != null) { diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 01d6662424..05a824cb33 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -28,26 +28,26 @@ describe('Getting all docs', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: { mock: 'one' }, - rev: 2 + rev: 2, }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], ranges: { mock: 'two' }, - rev: 4 + rev: 4, }, { _id: ObjectId(), lines: ['111', '222', '333'], ranges: { mock: 'three' }, - rev: 6 - } + rev: 6, + }, ] this.deleted_doc = { _id: ObjectId(), lines: ['deleted'], ranges: { mock: 'four' }, - rev: 8 + rev: 8, } const version = 42 const jobs = Array.from(this.docs).map((doc) => diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index b41af2827d..0ab7f6be58 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -32,10 +32,10 @@ describe('Getting a doc', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } return DocstoreApp.ensureRunning(() => { return DocstoreClient.createDoc( diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index 251378a392..2dff763f69 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -31,10 +31,10 @@ describe('Applying updates to a doc', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.newRanges = { changes: [ @@ -43,10 +43,10 @@ describe('Applying updates to a doc', function () { op: { i: 'bar', p: 6 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.version = 42 return DocstoreApp.ensureRunning(() => { diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 67dc1760e4..a0560a24a0 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -48,5 +48,5 @@ module.exports = { } ) } - } + }, } diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 237ef42134..cd2e8639cb 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -54,7 +54,7 @@ module.exports = DocstoreClient = { { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, json: true, - qs + qs, }, callback ) @@ -67,7 +67,7 @@ module.exports = DocstoreClient = { return request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, - json: true + json: true, }, (req, res, body) => { callback(req, res, body) @@ -82,7 +82,7 @@ module.exports = DocstoreClient = { return request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, - json: true + json: true, }, callback ) @@ -98,8 +98,8 @@ module.exports = DocstoreClient = { json: { lines, version, - ranges - } + ranges, + }, }, callback ) @@ -111,7 +111,7 @@ module.exports = DocstoreClient = { } return request.del( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}` + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, }, callback ) @@ -123,7 +123,7 @@ module.exports = DocstoreClient = { } return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive` + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive`, }, callback ) @@ -135,7 +135,7 @@ module.exports = DocstoreClient = { } return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy` + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy`, }, callback ) @@ -151,5 +151,5 @@ module.exports = DocstoreClient = { callback(null, JSON.parse(data)) }) .catch(callback) - } + }, } diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 026c7654b4..f3179b2963 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -32,24 +32,24 @@ describe('DocArchiveManager', function () { md5Sum = 'decafbad' RangeManager = { - jsonRangesToMongo: sinon.stub().returns({ mongo: 'ranges' }) + jsonRangesToMongo: sinon.stub().returns({ mongo: 'ranges' }), } Settings = { docstore: { - bucket: 'wombat' - } + bucket: 'wombat', + }, } Logger = { log: sinon.stub(), - err: sinon.stub() + err: sinon.stub(), } HashDigest = sinon.stub().returns(md5Sum) HashUpdate = sinon.stub().returns({ digest: HashDigest }) Crypto = { - createHash: sinon.stub().returns({ update: HashUpdate }) + createHash: sinon.stub().returns({ update: HashUpdate }), } Streamifier = { - createReadStream: sinon.stub().returns({ stream: 'readStream' }) + createReadStream: sinon.stub().returns({ stream: 'readStream' }), } projectId = ObjectId() @@ -57,69 +57,69 @@ describe('DocArchiveManager', function () { { _id: ObjectId(), inS3: true, - rev: 2 + rev: 2, }, { _id: ObjectId(), inS3: true, - rev: 4 + rev: 4, }, { _id: ObjectId(), inS3: true, - rev: 6 - } + rev: 6, + }, ] mongoDocs = [ { _id: ObjectId(), lines: ['one', 'two', 'three'], - rev: 2 + rev: 2, }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], - rev: 4 + rev: 4, }, { _id: ObjectId(), inS3: true, - rev: 6 + rev: 6, }, { _id: ObjectId(), inS3: true, - rev: 6 + rev: 6, }, { _id: ObjectId(), lines: ['111', '222', '333'], - rev: 6 - } + rev: 6, + }, ] docJson = JSON.stringify({ lines: mongoDocs[0].lines, ranges: mongoDocs[0].ranges, - schema_v: 1 + schema_v: 1, }) stream = { on: sinon.stub(), - resume: sinon.stub() + resume: sinon.stub(), } stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) stream.on.withArgs('end').yields() readStream = { - stream: 'readStream' + stream: 'readStream', } PersistorManager = { getObjectStream: sinon.stub().resolves(stream), sendStream: sinon.stub().resolves(), getObjectMd5Hash: sinon.stub().resolves(md5Sum), - deleteObject: sinon.stub().resolves() + deleteObject: sinon.stub().resolves(), } MongoManager = { @@ -129,8 +129,8 @@ describe('DocArchiveManager', function () { getProjectsDocs: sinon.stub().resolves(mongoDocs), getArchivedProjectDocs: sinon.stub().resolves(archivedDocs), findDoc: sinon.stub().resolves(), - destroyDoc: sinon.stub().resolves() - } + destroyDoc: sinon.stub().resolves(), + }, } for (const mongoDoc of mongoDocs) { MongoManager.promises.findDoc @@ -147,12 +147,12 @@ describe('DocArchiveManager', function () { './MongoManager': MongoManager, './RangeManager': RangeManager, './PersistorManager': PersistorManager, - './Errors': Errors + './Errors': Errors, }, globals: { console, - JSON - } + JSON, + }, }) }) @@ -183,7 +183,7 @@ describe('DocArchiveManager', function () { const json = JSON.stringify({ lines: mongoDocs[0].lines, ranges: mongoDocs[0].ranges, - schema_v: 1 + schema_v: 1, }) await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) @@ -290,7 +290,7 @@ describe('DocArchiveManager', function () { describe('when the doc has the old schema', function () { beforeEach(function () { mongoDoc = { - lines: ['doc', 'lines'] + lines: ['doc', 'lines'], } s3Doc = ['doc', 'lines'] docJson = JSON.stringify(s3Doc) @@ -310,11 +310,11 @@ describe('DocArchiveManager', function () { s3Doc = { lines: ['doc', 'lines'], ranges: { json: 'ranges' }, - schema_v: 1 + schema_v: 1, } mongoDoc = { lines: ['doc', 'lines'], - ranges: { mongo: 'ranges' } + ranges: { mongo: 'ranges' }, } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) @@ -332,10 +332,10 @@ describe('DocArchiveManager', function () { beforeEach(function () { s3Doc = { lines: ['doc', 'lines'], - schema_v: 1 + schema_v: 1, } mongoDoc = { - lines: ['doc', 'lines'] + lines: ['doc', 'lines'], } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) @@ -353,7 +353,7 @@ describe('DocArchiveManager', function () { beforeEach(function () { s3Doc = { lines: ['doc', 'lines'], - schema_v: 2 + schema_v: 2, } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index e7f5baa567..66d10c5087 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -32,15 +32,15 @@ describe('DocManager', function () { jsonRangesToMongo(r) { return r }, - shouldUpdateRanges: sinon.stub().returns(false) + shouldUpdateRanges: sinon.stub().returns(false), }), 'logger-sharelatex': (this.logger = { log: sinon.stub(), warn() {}, - err() {} + err() {}, }), - './Errors': Errors - } + './Errors': Errors, + }, }) this.doc_id = ObjectId().toString() this.project_id = ObjectId().toString() @@ -99,7 +99,7 @@ describe('DocManager', function () { this.DocManager._getDoc = sinon.stub() return (this.doc = { _id: this.doc_id, - lines: ['2134'] + lines: ['2134'], }) }) @@ -117,7 +117,7 @@ describe('DocManager', function () { deleted: true, version: true, ranges: true, - inS3: true + inS3: true, }) .should.equal(true) return done() @@ -154,7 +154,7 @@ describe('DocManager', function () { this.DocManager._getDoc .calledWith(this.project_id, this.doc_id, { lines: true, - inS3: true + inS3: true, }) .should.equal(true) return done() @@ -181,7 +181,7 @@ describe('DocManager', function () { this.doc = { _id: this.doc_id, project_id: this.project_id, - lines: ['mock-lines'] + lines: ['mock-lines'], } this.version = 42 this.MongoManager.findDoc = sinon.stub() @@ -302,7 +302,7 @@ describe('DocManager', function () { _id: this.doc_id, project_id: this.project_id, lines: ['mock-lines'], - inS3: true + inS3: true, } this.MongoManager.findDoc.yields(null, this.doc) this.DocArchiveManager.unarchiveDoc = ( @@ -368,8 +368,8 @@ describe('DocManager', function () { { _id: this.doc_id, project_id: this.project_id, - lines: ['mock-lines'] - } + lines: ['mock-lines'], + }, ] this.MongoManager.getProjectsDocs = sinon .stub() @@ -490,10 +490,10 @@ describe('DocManager', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.newRanges = { changes: [ @@ -502,10 +502,10 @@ describe('DocManager', function () { op: { i: 'bar', p: 6 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.version = 42 this.doc = { @@ -514,7 +514,7 @@ describe('DocManager', function () { lines: this.oldDocLines, rev: (this.rev = 5), version: this.version, - ranges: this.originalRanges + ranges: this.originalRanges, } this.MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @@ -543,7 +543,7 @@ describe('DocManager', function () { lines: true, version: true, ranges: true, - inS3: true + inS3: true, }) .should.equal(true) }) @@ -789,7 +789,7 @@ describe('DocManager', function () { return this.MongoManager.upsertIntoDocCollection .calledWith(this.project_id, this.doc_id, { lines: this.newDocLines, - ranges: this.originalRanges + ranges: this.originalRanges, }) .should.equal(true) }) diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 46132737f2..b56b334787 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -29,17 +29,17 @@ describe('HttpController', function () { './DocArchiveManager': (this.DocArchiveManager = {}), 'logger-sharelatex': (this.logger = { log: sinon.stub(), - error: sinon.stub() + error: sinon.stub(), }), - './HealthChecker': {} + './HealthChecker': {}, }, - globals: { process } + globals: { process }, }) this.res = { send: sinon.stub(), sendStatus: sinon.stub(), json: sinon.stub(), - setHeader: sinon.stub() + setHeader: sinon.stub(), } this.res.status = sinon.stub().returns(this.res) this.req = { query: {} } @@ -50,14 +50,14 @@ describe('HttpController', function () { _id: this.doc_id, lines: ['mock', 'lines', ' here', '', '', ' spaces '], version: 42, - rev: 5 + rev: 5, } return (this.deletedDoc = { deleted: true, _id: this.doc_id, lines: ['mock', 'lines', ' here', '', '', ' spaces '], version: 42, - rev: 5 + rev: 5, }) }) @@ -66,7 +66,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } this.DocManager.getFullDoc = sinon .stub() @@ -86,7 +86,7 @@ describe('HttpController', function () { _id: this.doc_id, lines: this.doc.lines, rev: this.doc.rev, - version: this.doc.version + version: this.doc.version, }) .should.equal(true) }) @@ -96,7 +96,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } return (this.DocManager.getFullDoc = sinon .stub() @@ -124,7 +124,7 @@ describe('HttpController', function () { lines: this.doc.lines, rev: this.doc.rev, deleted: true, - version: this.doc.version + version: this.doc.version, }) .should.equal(true) }) @@ -135,7 +135,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc) return this.HttpController.getRawDoc(this.req, this.res, this.next) @@ -169,13 +169,13 @@ describe('HttpController', function () { { _id: ObjectId(), lines: ['mock', 'lines', 'one'], - rev: 2 + rev: 2, }, { _id: ObjectId(), lines: ['mock', 'lines', 'two'], - rev: 4 - } + rev: 4, + }, ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -195,13 +195,13 @@ describe('HttpController', function () { { _id: this.docs[0]._id.toString(), lines: this.docs[0].lines, - rev: this.docs[0].rev + rev: this.docs[0].rev, }, { _id: this.docs[1]._id.toString(), lines: this.docs[1].lines, - rev: this.docs[1].rev - } + rev: this.docs[1].rev, + }, ]) .should.equal(true) }) @@ -214,14 +214,14 @@ describe('HttpController', function () { { _id: ObjectId(), lines: ['mock', 'lines', 'one'], - rev: 2 + rev: 2, }, null, { _id: ObjectId(), lines: ['mock', 'lines', 'two'], - rev: 4 - } + rev: 4, + }, ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -235,13 +235,13 @@ describe('HttpController', function () { { _id: this.docs[0]._id.toString(), lines: this.docs[0].lines, - rev: this.docs[0].rev + rev: this.docs[0].rev, }, { _id: this.docs[2]._id.toString(), lines: this.docs[2].lines, - rev: this.docs[2].rev - } + rev: this.docs[2].rev, + }, ]) .should.equal(true) }) @@ -251,7 +251,7 @@ describe('HttpController', function () { .calledWith( { err: sinon.match.has('message', 'null doc'), - project_id: this.project_id + project_id: this.project_id, }, 'encountered null doc' ) @@ -267,12 +267,12 @@ describe('HttpController', function () { this.docs = [ { _id: ObjectId(), - ranges: { mock_ranges: 'one' } + ranges: { mock_ranges: 'one' }, }, { _id: ObjectId(), - ranges: { mock_ranges: 'two' } - } + ranges: { mock_ranges: 'two' }, + }, ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -291,12 +291,12 @@ describe('HttpController', function () { .calledWith([ { _id: this.docs[0]._id.toString(), - ranges: this.docs[0].ranges + ranges: this.docs[0].ranges, }, { _id: this.docs[1]._id.toString(), - ranges: this.docs[1].ranges - } + ranges: this.docs[1].ranges, + }, ]) .should.equal(true) }) @@ -307,7 +307,7 @@ describe('HttpController', function () { beforeEach(function () { return (this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, }) }) @@ -316,7 +316,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), - ranges: (this.ranges = { changes: 'mock' }) + ranges: (this.ranges = { changes: 'mock' }), } this.DocManager.updateDoc = sinon .stub() @@ -348,7 +348,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), - ranges: {} + ranges: {}, } this.DocManager.updateDoc = sinon .stub() @@ -416,7 +416,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = Array(2049).fill('a'.repeat(1024))), version: (this.version = 42), - ranges: (this.ranges = { changes: 'mock' }) + ranges: (this.ranges = { changes: 'mock' }), } return this.HttpController.updateDoc(this.req, this.res, this.next) }) @@ -435,7 +435,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } this.DocManager.deleteDoc = sinon.stub().callsArg(2) return this.HttpController.deleteDoc(this.req, this.res, this.next) diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index fec3ec0682..204a8d96a5 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -25,14 +25,14 @@ describe('MongoManager', function () { requires: { './mongojs': { db: (this.db = { docs: {}, docOps: {} }), - ObjectId + ObjectId, }, 'metrics-sharelatex': { timeAsyncMethod: sinon.stub() }, - 'logger-sharelatex': { log() {} } + 'logger-sharelatex': { log() {} }, }, globals: { - console - } + console, + }, }) this.project_id = ObjectId().toString() this.doc_id = ObjectId().toString() @@ -58,7 +58,7 @@ describe('MongoManager', function () { .calledWith( { _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id) + project_id: ObjectId(this.project_id), }, this.filter ) @@ -97,7 +97,7 @@ describe('MongoManager', function () { .calledWith( { project_id: ObjectId(this.project_id), - deleted: { $ne: true } + deleted: { $ne: true }, }, this.filter ) @@ -125,7 +125,7 @@ describe('MongoManager', function () { return this.db.docs.find .calledWith( { - project_id: ObjectId(this.project_id) + project_id: ObjectId(this.project_id), }, this.filter ) @@ -189,7 +189,7 @@ describe('MongoManager', function () { const args = this.db.docs.update.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id) + project_id: ObjectId(this.project_id), }) assert.equal(args[1].$set.deleted, true) return done() @@ -218,13 +218,13 @@ describe('MongoManager', function () { it('should destroy the doc', function () { return sinon.assert.calledWith(this.db.docs.remove, { - _id: ObjectId('123456789012') + _id: ObjectId('123456789012'), }) }) return it('should destroy the docOps', function () { return sinon.assert.calledWith(this.db.docOps.remove, { - doc_id: ObjectId('123456789012') + doc_id: ObjectId('123456789012'), }) }) }) @@ -275,15 +275,15 @@ describe('MongoManager', function () { return this.db.docOps.update .calledWith( { - doc_id: ObjectId(this.doc_id) + doc_id: ObjectId(this.doc_id), }, { $set: { - version: this.version - } + version: this.version, + }, }, { - upsert: true + upsert: true, } ) .should.equal(true) diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index eafc60110b..575b8a1f54 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -27,9 +27,9 @@ describe('RangeManager', function () { return (this.RangeManager = SandboxedModule.require(modulePath, { requires: { './mongojs': { - ObjectId - } - } + ObjectId, + }, + }, })) }) @@ -47,16 +47,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id, - ts - } - } + ts, + }, + }, ], comments: [ { id: comment_id, - op: { c: 'foo', p: 3, t: thread_id } - } - ] + op: { c: 'foo', p: 3, t: thread_id }, + }, + ], }).should.deep.equal({ changes: [ { @@ -64,16 +64,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id: ObjectId(user_id), - ts: new Date(ts) - } - } + ts: new Date(ts), + }, + }, ], comments: [ { id: ObjectId(comment_id), - op: { c: 'foo', p: 3, t: ObjectId(thread_id) } - } - ] + op: { c: 'foo', p: 3, t: ObjectId(thread_id) }, + }, + ], }) }) @@ -86,29 +86,29 @@ describe('RangeManager', function () { { id: change_id, metadata: { - user_id - } - } + user_id, + }, + }, ], comments: [ { - id: comment_id - } - ] + id: comment_id, + }, + ], }).should.deep.equal({ changes: [ { id: change_id, metadata: { - user_id - } - } + user_id, + }, + }, ], comments: [ { - id: comment_id - } - ] + id: comment_id, + }, + ], }) }) @@ -125,16 +125,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id, - ts - } - } + ts, + }, + }, ], comments: [ { id: comment_id, - op: { c: 'foo', p: 3, t: thread_id } - } - ] + op: { c: 'foo', p: 3, t: thread_id }, + }, + ], } const ranges1_copy = JSON.parse(JSON.stringify(ranges1)) // jsonRangesToMongo modifies in place const ranges2 = JSON.parse( @@ -153,16 +153,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id: ObjectId(), - ts: new Date() - } - } + ts: new Date(), + }, + }, ], comments: [ { id: ObjectId(), - op: { c: 'foo', p: 3, t: ObjectId() } - } - ] + op: { c: 'foo', p: 3, t: ObjectId() }, + }, + ], } return (this.ranges_copy = this.RangeManager.jsonRangesToMongo( JSON.parse(JSON.stringify(this.ranges)) From 2be47a6820182fdf37ef1ba9d4092d6e085359ae Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Wed, 12 Aug 2020 15:24:43 +0100 Subject: [PATCH 276/349] Add missing eslint-plugin-chai-friendly@^0.5.0 --- services/docstore/package-lock.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 6b6807c967..a4c04f4fe1 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -2583,6 +2583,12 @@ "integrity": "sha512-ExTJKhgeYMfY8wDj3UiZmgpMKJOUHGNHmWMlxT49JUDB1vTnw0sSNfXJSxnX+LcebyBD/gudXzjzD136WqPJrQ==", "dev": true }, + "eslint-plugin-chai-friendly": { + "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": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", From 16c9ab38b2f01f096f3c40c02b687b5e4512240e Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Wed, 12 Aug 2020 15:29:19 +0100 Subject: [PATCH 277/349] Fix formating --- services/docstore/app/js/DocArchiveManager.js | 12 +-- services/docstore/app/js/DocManager.js | 8 +- services/docstore/app/js/Errors.js | 2 +- services/docstore/app/js/HealthChecker.js | 8 +- services/docstore/app/js/HttpController.js | 4 +- services/docstore/app/js/MongoManager.js | 34 ++++---- services/docstore/app/js/RangeManager.js | 2 +- services/docstore/app/js/mongojs.js | 2 +- services/docstore/config/settings.defaults.js | 18 ++--- .../test/acceptance/js/ArchiveDocsTests.js | 40 +++++----- .../test/acceptance/js/GettingAllDocsTests.js | 10 +-- .../test/acceptance/js/GettingDocsTests.js | 8 +- .../test/acceptance/js/UpdatingDocsTests.js | 16 ++-- .../test/acceptance/js/helpers/DocstoreApp.js | 2 +- .../acceptance/js/helpers/DocstoreClient.js | 18 ++--- .../test/unit/js/DocArchiveManagerTests.js | 64 +++++++-------- .../docstore/test/unit/js/DocManagerTests.js | 44 +++++------ .../test/unit/js/HttpControllerTests.js | 70 ++++++++--------- .../test/unit/js/MongoManagerTests.js | 28 +++---- .../test/unit/js/RangeManagerTests.js | 78 +++++++++---------- 20 files changed, 234 insertions(+), 234 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 9dd542e0ab..d564113c9b 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -24,8 +24,8 @@ module.exports = { unArchiveAllDocs, unarchiveDoc, destroyAllDocs, - destroyDoc, - }, + destroyDoc + } } async function archiveAllDocs(projectId) { @@ -61,7 +61,7 @@ async function archiveDoc(projectId, doc) { const json = JSON.stringify({ lines: doc.lines, ranges: doc.ranges, - schema_v: 1, + schema_v: 1 }) // this should never happen, but protects against memory-corruption errors that @@ -75,7 +75,7 @@ async function archiveDoc(projectId, doc) { const md5 = crypto.createHash('md5').update(json).digest('hex') const stream = Streamifier.createReadStream(json) await PersistorManager.sendStream(settings.docstore.bucket, key, stream, { - sourceMd5: md5, + sourceMd5: md5 }) await MongoManager.markDocAsArchived(doc._id, doc.rev) } @@ -115,7 +115,7 @@ async function unarchiveDoc(projectId, docId) { throw new Errors.Md5MismatchError('md5 mismatch when downloading doc', { key, sourceMd5, - md5, + md5 }) } @@ -155,7 +155,7 @@ async function destroyDoc(projectId, docId) { 'removing doc from mongo and persistor' ) const doc = await MongoManager.findDoc(projectId, docId, { - inS3: 1, + inS3: 1 }) if (!doc) { throw new Errors.NotFoundError('Doc not found in Mongo') diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 2b8b3106e3..edd9c0f1cd 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -103,7 +103,7 @@ module.exports = DocManager = { deleted: true, version: true, ranges: true, - inS3: true, + inS3: true }, function (err, doc) { if (err != null) { @@ -175,7 +175,7 @@ module.exports = DocManager = { lines: true, version: true, ranges: true, - inS3: true, + inS3: true }, function (err, doc) { let updateLines, updateRanges, updateVersion @@ -238,7 +238,7 @@ module.exports = DocManager = { project_id, doc_id, oldVersion: doc != null ? doc.version : undefined, - newVersion: version, + newVersion: version }, 'updating doc version' ) @@ -288,5 +288,5 @@ module.exports = DocManager = { } return MongoManager.markDocAsDeleted(project_id, doc_id, callback) }) - }, + } } diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index 4eaa5481d3..6a74485494 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -6,5 +6,5 @@ class Md5MismatchError extends OError {} module.exports = { Md5MismatchError, - ...Errors, + ...Errors } diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 5328fbf616..70ebc85ad9 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -26,11 +26,11 @@ module.exports = { const url = `http://localhost:${port}/project/${project_id}/doc/${doc_id}` const lines = [ 'smoke test - delete me', - `${crypto.randomBytes(32).toString('hex')}`, + `${crypto.randomBytes(32).toString('hex')}` ] const getOpts = () => ({ url, - timeout: 3000, + timeout: 3000 }) logger.log({ lines, url, doc_id, project_id }, 'running health check') const jobs = [ @@ -61,8 +61,8 @@ module.exports = { }) }, (cb) => db.docs.remove({ _id: doc_id, project_id }, cb), - (cb) => db.docOps.remove({ doc_id }, cb), + (cb) => db.docOps.remove({ doc_id }, cb) ] return async.series(jobs, callback) - }, + } } diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 7503762168..50c779736c 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -157,7 +157,7 @@ module.exports = HttpController = { } return res.json({ modified, - rev, + rev }) } ) @@ -259,5 +259,5 @@ module.exports = HttpController = { return res.sendStatus(200) } }) - }, + } } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index d419132f0f..b6e90a7ad3 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -24,7 +24,7 @@ module.exports = MongoManager = { return db.docs.find( { _id: ObjectId(doc_id.toString()), - project_id: ObjectId(project_id.toString()), + project_id: ObjectId(project_id.toString()) }, filter, function (error, docs) { @@ -50,7 +50,7 @@ module.exports = MongoManager = { getArchivedProjectDocs(project_id, callback) { const query = { project_id: ObjectId(project_id.toString()), - inS3: true, + inS3: true } return db.docs.find(query, {}, callback) }, @@ -59,11 +59,11 @@ module.exports = MongoManager = { const update = { $set: updates, $inc: { - rev: 1, + rev: 1 }, $unset: { - inS3: true, - }, + inS3: true + } } update.$set.project_id = ObjectId(project_id) return db.docs.update( @@ -78,10 +78,10 @@ module.exports = MongoManager = { return db.docs.update( { _id: ObjectId(doc_id), - project_id: ObjectId(project_id), + project_id: ObjectId(project_id) }, { - $set: { deleted: true }, + $set: { deleted: true } }, callback ) @@ -90,14 +90,14 @@ module.exports = MongoManager = { markDocAsArchived(doc_id, rev, callback) { const update = { $set: {}, - $unset: {}, + $unset: {} } update.$set.inS3 = true update.$unset.lines = true update.$unset.ranges = true const query = { _id: doc_id, - rev, + rev } return db.docs.update(query, update, (err) => callback(err)) }, @@ -108,10 +108,10 @@ module.exports = MongoManager = { } return db.docOps.find( { - doc_id: ObjectId(doc_id), + doc_id: ObjectId(doc_id) }, { - version: 1, + version: 1 }, function (error, docs) { if (error != null) { @@ -132,13 +132,13 @@ module.exports = MongoManager = { } return db.docOps.update( { - doc_id: ObjectId(doc_id), + doc_id: ObjectId(doc_id) }, { - $set: { version }, + $set: { version } }, { - upsert: true, + upsert: true }, callback ) @@ -147,7 +147,7 @@ module.exports = MongoManager = { destroyDoc(doc_id, callback) { return db.docs.remove( { - _id: ObjectId(doc_id), + _id: ObjectId(doc_id) }, function (err) { if (err != null) { @@ -155,13 +155,13 @@ module.exports = MongoManager = { } return db.docOps.remove( { - doc_id: ObjectId(doc_id), + doc_id: ObjectId(doc_id) }, callback ) } ) - }, + } } const methods = Object.getOwnPropertyNames(MongoManager) diff --git a/services/docstore/app/js/RangeManager.js b/services/docstore/app/js/RangeManager.js index 083cdf0486..b11019657f 100644 --- a/services/docstore/app/js/RangeManager.js +++ b/services/docstore/app/js/RangeManager.js @@ -65,5 +65,5 @@ module.exports = RangeManager = { } catch (error) { return data } - }, + } } diff --git a/services/docstore/app/js/mongojs.js b/services/docstore/app/js/mongojs.js index 44b9d64bf0..41f3bec470 100644 --- a/services/docstore/app/js/mongojs.js +++ b/services/docstore/app/js/mongojs.js @@ -5,5 +5,5 @@ const mongojs = require('mongojs') const db = mongojs(Settings.mongo.url, ['docs', 'docOps']) module.exports = { db, - ObjectId: mongojs.ObjectId, + ObjectId: mongojs.ObjectId } diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index f9193f1eb0..c538b79045 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -10,8 +10,8 @@ const Settings = { internal: { docstore: { port: 3016, - host: process.env.LISTEN_ADDRESS || 'localhost', - }, + host: process.env.LISTEN_ADDRESS || 'localhost' + } }, mongo: {}, @@ -19,17 +19,17 @@ const Settings = { docstore: { backend: process.env.BACKEND || 's3', healthCheck: { - project_id: process.env.HEALTH_CHECK_PROJECT_ID, + project_id: process.env.HEALTH_CHECK_PROJECT_ID }, bucket: process.env.BUCKET_NAME || process.env.AWS_BUCKET || 'bucket', gcs: { unlockBeforeDelete: process.env.GCS_UNLOCK_BEFORE_DELETE === 'true', deletedBucketSuffix: process.env.GCS_DELETED_BUCKET_SUFFIX, - deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50, - }, + deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50 + } }, - max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024, // 2mb + max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024 // 2mb } if (process.env.MONGO_CONNECTION_STRING != null) { @@ -51,7 +51,7 @@ if ( bucket: process.env.AWS_BUCKET, endpoint: process.env.AWS_S3_ENDPOINT, pathStyle: process.env.AWS_S3_PATH_STYLE, - partSize: parseInt(process.env.AWS_S3_PARTSIZE) || 100 * 1024 * 1024, + partSize: parseInt(process.env.AWS_S3_PARTSIZE) || 100 * 1024 * 1024 } } @@ -59,7 +59,7 @@ if (process.env.GCS_API_ENDPOINT) { Settings.docstore.gcs.endpoint = { apiEndpoint: process.env.GCS_API_ENDPOINT, apiScheme: process.env.GCS_API_SCHEME, - projectId: process.env.GCS_PROJECT_ID, + projectId: process.env.GCS_PROJECT_ID } } @@ -69,7 +69,7 @@ if (process.env.FALLBACK_BACKEND) { // mapping of bucket names on the fallback, to bucket names on the primary. // e.g. { myS3UserFilesBucketName: 'myGoogleUserFilesBucketName' } buckets: JSON.parse(process.env.FALLBACK_BUCKET_MAPPING || '{}'), - copyOnMiss: process.env.COPY_ON_MISS === 'true', + copyOnMiss: process.env.COPY_ON_MISS === 'true' } } diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 95fe5d58fa..959af6715b 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -51,14 +51,14 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: {}, - version: 2, + version: 2 }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], ranges: {}, - version: 4, - }, + version: 4 + } ] const jobs = Array.from(this.docs).map((doc) => ((doc) => { @@ -173,7 +173,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: {}, - version: 2, + version: 2 } return DocstoreClient.createDoc( this.project_id, @@ -287,7 +287,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: [big_line, big_line, big_line, big_line], ranges: {}, - version: 2, + version: 2 } return DocstoreClient.createDoc( this.project_id, @@ -758,10 +758,10 @@ describe('Archiving', function () { 'Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue', 'But now...\u001b[20Cfor my greatest trick...\u001b[8m', 'The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]', - 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗', + 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗' ], ranges: {}, - version: 2, + version: 2 } return DocstoreClient.createDoc( this.project_id, @@ -857,17 +857,17 @@ describe('Archiving', function () { op: { i: 'foo', p: 24 }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-27T16:10:44.194Z'), - }, + ts: new Date('2017-01-27T16:10:44.194Z') + } }, { id: ObjectId(), op: { d: 'bar', p: 50 }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-27T18:10:44.194Z'), - }, - }, + ts: new Date('2017-01-27T18:10:44.194Z') + } + } ], comments: [ { @@ -875,12 +875,12 @@ describe('Archiving', function () { op: { c: 'comment', p: 284, t: ObjectId() }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-26T14:22:04.869Z'), - }, - }, - ], + ts: new Date('2017-01-26T14:22:04.869Z') + } + } + ] }, - version: 2, + version: 2 } return DocstoreClient.createDoc( this.project_id, @@ -971,7 +971,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['abc', 'def', 'ghi'], ranges: {}, - version: 2, + version: 2 } return DocstoreClient.createDoc( this.project_id, @@ -1067,7 +1067,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['abc', 'def', 'ghi'], ranges: {}, - version: 2, + version: 2 } uploadContent( `${this.project_id}/${this.doc._id}`, @@ -1079,7 +1079,7 @@ describe('Archiving', function () { project_id: this.project_id, _id: this.doc._id, rev: this.doc.version, - inS3: true, + inS3: true }, (error) => { if (error != null) { diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 05a824cb33..01d6662424 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -28,26 +28,26 @@ describe('Getting all docs', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: { mock: 'one' }, - rev: 2, + rev: 2 }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], ranges: { mock: 'two' }, - rev: 4, + rev: 4 }, { _id: ObjectId(), lines: ['111', '222', '333'], ranges: { mock: 'three' }, - rev: 6, - }, + rev: 6 + } ] this.deleted_doc = { _id: ObjectId(), lines: ['deleted'], ranges: { mock: 'four' }, - rev: 8, + rev: 8 } const version = 42 const jobs = Array.from(this.docs).map((doc) => diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index 0ab7f6be58..b41af2827d 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -32,10 +32,10 @@ describe('Getting a doc', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString(), - }, - }, - ], + ts: new Date().toString() + } + } + ] } return DocstoreApp.ensureRunning(() => { return DocstoreClient.createDoc( diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index 2dff763f69..251378a392 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -31,10 +31,10 @@ describe('Applying updates to a doc', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString(), - }, - }, - ], + ts: new Date().toString() + } + } + ] } this.newRanges = { changes: [ @@ -43,10 +43,10 @@ describe('Applying updates to a doc', function () { op: { i: 'bar', p: 6 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString(), - }, - }, - ], + ts: new Date().toString() + } + } + ] } this.version = 42 return DocstoreApp.ensureRunning(() => { diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index a0560a24a0..67dc1760e4 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -48,5 +48,5 @@ module.exports = { } ) } - }, + } } diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index cd2e8639cb..237ef42134 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -54,7 +54,7 @@ module.exports = DocstoreClient = { { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, json: true, - qs, + qs }, callback ) @@ -67,7 +67,7 @@ module.exports = DocstoreClient = { return request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, - json: true, + json: true }, (req, res, body) => { callback(req, res, body) @@ -82,7 +82,7 @@ module.exports = DocstoreClient = { return request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, - json: true, + json: true }, callback ) @@ -98,8 +98,8 @@ module.exports = DocstoreClient = { json: { lines, version, - ranges, - }, + ranges + } }, callback ) @@ -111,7 +111,7 @@ module.exports = DocstoreClient = { } return request.del( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}` }, callback ) @@ -123,7 +123,7 @@ module.exports = DocstoreClient = { } return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive`, + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive` }, callback ) @@ -135,7 +135,7 @@ module.exports = DocstoreClient = { } return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy`, + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy` }, callback ) @@ -151,5 +151,5 @@ module.exports = DocstoreClient = { callback(null, JSON.parse(data)) }) .catch(callback) - }, + } } diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index f3179b2963..026c7654b4 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -32,24 +32,24 @@ describe('DocArchiveManager', function () { md5Sum = 'decafbad' RangeManager = { - jsonRangesToMongo: sinon.stub().returns({ mongo: 'ranges' }), + jsonRangesToMongo: sinon.stub().returns({ mongo: 'ranges' }) } Settings = { docstore: { - bucket: 'wombat', - }, + bucket: 'wombat' + } } Logger = { log: sinon.stub(), - err: sinon.stub(), + err: sinon.stub() } HashDigest = sinon.stub().returns(md5Sum) HashUpdate = sinon.stub().returns({ digest: HashDigest }) Crypto = { - createHash: sinon.stub().returns({ update: HashUpdate }), + createHash: sinon.stub().returns({ update: HashUpdate }) } Streamifier = { - createReadStream: sinon.stub().returns({ stream: 'readStream' }), + createReadStream: sinon.stub().returns({ stream: 'readStream' }) } projectId = ObjectId() @@ -57,69 +57,69 @@ describe('DocArchiveManager', function () { { _id: ObjectId(), inS3: true, - rev: 2, + rev: 2 }, { _id: ObjectId(), inS3: true, - rev: 4, + rev: 4 }, { _id: ObjectId(), inS3: true, - rev: 6, - }, + rev: 6 + } ] mongoDocs = [ { _id: ObjectId(), lines: ['one', 'two', 'three'], - rev: 2, + rev: 2 }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], - rev: 4, + rev: 4 }, { _id: ObjectId(), inS3: true, - rev: 6, + rev: 6 }, { _id: ObjectId(), inS3: true, - rev: 6, + rev: 6 }, { _id: ObjectId(), lines: ['111', '222', '333'], - rev: 6, - }, + rev: 6 + } ] docJson = JSON.stringify({ lines: mongoDocs[0].lines, ranges: mongoDocs[0].ranges, - schema_v: 1, + schema_v: 1 }) stream = { on: sinon.stub(), - resume: sinon.stub(), + resume: sinon.stub() } stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) stream.on.withArgs('end').yields() readStream = { - stream: 'readStream', + stream: 'readStream' } PersistorManager = { getObjectStream: sinon.stub().resolves(stream), sendStream: sinon.stub().resolves(), getObjectMd5Hash: sinon.stub().resolves(md5Sum), - deleteObject: sinon.stub().resolves(), + deleteObject: sinon.stub().resolves() } MongoManager = { @@ -129,8 +129,8 @@ describe('DocArchiveManager', function () { getProjectsDocs: sinon.stub().resolves(mongoDocs), getArchivedProjectDocs: sinon.stub().resolves(archivedDocs), findDoc: sinon.stub().resolves(), - destroyDoc: sinon.stub().resolves(), - }, + destroyDoc: sinon.stub().resolves() + } } for (const mongoDoc of mongoDocs) { MongoManager.promises.findDoc @@ -147,12 +147,12 @@ describe('DocArchiveManager', function () { './MongoManager': MongoManager, './RangeManager': RangeManager, './PersistorManager': PersistorManager, - './Errors': Errors, + './Errors': Errors }, globals: { console, - JSON, - }, + JSON + } }) }) @@ -183,7 +183,7 @@ describe('DocArchiveManager', function () { const json = JSON.stringify({ lines: mongoDocs[0].lines, ranges: mongoDocs[0].ranges, - schema_v: 1, + schema_v: 1 }) await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) @@ -290,7 +290,7 @@ describe('DocArchiveManager', function () { describe('when the doc has the old schema', function () { beforeEach(function () { mongoDoc = { - lines: ['doc', 'lines'], + lines: ['doc', 'lines'] } s3Doc = ['doc', 'lines'] docJson = JSON.stringify(s3Doc) @@ -310,11 +310,11 @@ describe('DocArchiveManager', function () { s3Doc = { lines: ['doc', 'lines'], ranges: { json: 'ranges' }, - schema_v: 1, + schema_v: 1 } mongoDoc = { lines: ['doc', 'lines'], - ranges: { mongo: 'ranges' }, + ranges: { mongo: 'ranges' } } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) @@ -332,10 +332,10 @@ describe('DocArchiveManager', function () { beforeEach(function () { s3Doc = { lines: ['doc', 'lines'], - schema_v: 1, + schema_v: 1 } mongoDoc = { - lines: ['doc', 'lines'], + lines: ['doc', 'lines'] } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) @@ -353,7 +353,7 @@ describe('DocArchiveManager', function () { beforeEach(function () { s3Doc = { lines: ['doc', 'lines'], - schema_v: 2, + schema_v: 2 } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 66d10c5087..e7f5baa567 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -32,15 +32,15 @@ describe('DocManager', function () { jsonRangesToMongo(r) { return r }, - shouldUpdateRanges: sinon.stub().returns(false), + shouldUpdateRanges: sinon.stub().returns(false) }), 'logger-sharelatex': (this.logger = { log: sinon.stub(), warn() {}, - err() {}, + err() {} }), - './Errors': Errors, - }, + './Errors': Errors + } }) this.doc_id = ObjectId().toString() this.project_id = ObjectId().toString() @@ -99,7 +99,7 @@ describe('DocManager', function () { this.DocManager._getDoc = sinon.stub() return (this.doc = { _id: this.doc_id, - lines: ['2134'], + lines: ['2134'] }) }) @@ -117,7 +117,7 @@ describe('DocManager', function () { deleted: true, version: true, ranges: true, - inS3: true, + inS3: true }) .should.equal(true) return done() @@ -154,7 +154,7 @@ describe('DocManager', function () { this.DocManager._getDoc .calledWith(this.project_id, this.doc_id, { lines: true, - inS3: true, + inS3: true }) .should.equal(true) return done() @@ -181,7 +181,7 @@ describe('DocManager', function () { this.doc = { _id: this.doc_id, project_id: this.project_id, - lines: ['mock-lines'], + lines: ['mock-lines'] } this.version = 42 this.MongoManager.findDoc = sinon.stub() @@ -302,7 +302,7 @@ describe('DocManager', function () { _id: this.doc_id, project_id: this.project_id, lines: ['mock-lines'], - inS3: true, + inS3: true } this.MongoManager.findDoc.yields(null, this.doc) this.DocArchiveManager.unarchiveDoc = ( @@ -368,8 +368,8 @@ describe('DocManager', function () { { _id: this.doc_id, project_id: this.project_id, - lines: ['mock-lines'], - }, + lines: ['mock-lines'] + } ] this.MongoManager.getProjectsDocs = sinon .stub() @@ -490,10 +490,10 @@ describe('DocManager', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString(), - }, - }, - ], + ts: new Date().toString() + } + } + ] } this.newRanges = { changes: [ @@ -502,10 +502,10 @@ describe('DocManager', function () { op: { i: 'bar', p: 6 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString(), - }, - }, - ], + ts: new Date().toString() + } + } + ] } this.version = 42 this.doc = { @@ -514,7 +514,7 @@ describe('DocManager', function () { lines: this.oldDocLines, rev: (this.rev = 5), version: this.version, - ranges: this.originalRanges, + ranges: this.originalRanges } this.MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @@ -543,7 +543,7 @@ describe('DocManager', function () { lines: true, version: true, ranges: true, - inS3: true, + inS3: true }) .should.equal(true) }) @@ -789,7 +789,7 @@ describe('DocManager', function () { return this.MongoManager.upsertIntoDocCollection .calledWith(this.project_id, this.doc_id, { lines: this.newDocLines, - ranges: this.originalRanges, + ranges: this.originalRanges }) .should.equal(true) }) diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index b56b334787..46132737f2 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -29,17 +29,17 @@ describe('HttpController', function () { './DocArchiveManager': (this.DocArchiveManager = {}), 'logger-sharelatex': (this.logger = { log: sinon.stub(), - error: sinon.stub(), + error: sinon.stub() }), - './HealthChecker': {}, + './HealthChecker': {} }, - globals: { process }, + globals: { process } }) this.res = { send: sinon.stub(), sendStatus: sinon.stub(), json: sinon.stub(), - setHeader: sinon.stub(), + setHeader: sinon.stub() } this.res.status = sinon.stub().returns(this.res) this.req = { query: {} } @@ -50,14 +50,14 @@ describe('HttpController', function () { _id: this.doc_id, lines: ['mock', 'lines', ' here', '', '', ' spaces '], version: 42, - rev: 5, + rev: 5 } return (this.deletedDoc = { deleted: true, _id: this.doc_id, lines: ['mock', 'lines', ' here', '', '', ' spaces '], version: 42, - rev: 5, + rev: 5 }) }) @@ -66,7 +66,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id, + doc_id: this.doc_id } this.DocManager.getFullDoc = sinon .stub() @@ -86,7 +86,7 @@ describe('HttpController', function () { _id: this.doc_id, lines: this.doc.lines, rev: this.doc.rev, - version: this.doc.version, + version: this.doc.version }) .should.equal(true) }) @@ -96,7 +96,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id, + doc_id: this.doc_id } return (this.DocManager.getFullDoc = sinon .stub() @@ -124,7 +124,7 @@ describe('HttpController', function () { lines: this.doc.lines, rev: this.doc.rev, deleted: true, - version: this.doc.version, + version: this.doc.version }) .should.equal(true) }) @@ -135,7 +135,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id, + doc_id: this.doc_id } this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc) return this.HttpController.getRawDoc(this.req, this.res, this.next) @@ -169,13 +169,13 @@ describe('HttpController', function () { { _id: ObjectId(), lines: ['mock', 'lines', 'one'], - rev: 2, + rev: 2 }, { _id: ObjectId(), lines: ['mock', 'lines', 'two'], - rev: 4, - }, + rev: 4 + } ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -195,13 +195,13 @@ describe('HttpController', function () { { _id: this.docs[0]._id.toString(), lines: this.docs[0].lines, - rev: this.docs[0].rev, + rev: this.docs[0].rev }, { _id: this.docs[1]._id.toString(), lines: this.docs[1].lines, - rev: this.docs[1].rev, - }, + rev: this.docs[1].rev + } ]) .should.equal(true) }) @@ -214,14 +214,14 @@ describe('HttpController', function () { { _id: ObjectId(), lines: ['mock', 'lines', 'one'], - rev: 2, + rev: 2 }, null, { _id: ObjectId(), lines: ['mock', 'lines', 'two'], - rev: 4, - }, + rev: 4 + } ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -235,13 +235,13 @@ describe('HttpController', function () { { _id: this.docs[0]._id.toString(), lines: this.docs[0].lines, - rev: this.docs[0].rev, + rev: this.docs[0].rev }, { _id: this.docs[2]._id.toString(), lines: this.docs[2].lines, - rev: this.docs[2].rev, - }, + rev: this.docs[2].rev + } ]) .should.equal(true) }) @@ -251,7 +251,7 @@ describe('HttpController', function () { .calledWith( { err: sinon.match.has('message', 'null doc'), - project_id: this.project_id, + project_id: this.project_id }, 'encountered null doc' ) @@ -267,12 +267,12 @@ describe('HttpController', function () { this.docs = [ { _id: ObjectId(), - ranges: { mock_ranges: 'one' }, + ranges: { mock_ranges: 'one' } }, { _id: ObjectId(), - ranges: { mock_ranges: 'two' }, - }, + ranges: { mock_ranges: 'two' } + } ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -291,12 +291,12 @@ describe('HttpController', function () { .calledWith([ { _id: this.docs[0]._id.toString(), - ranges: this.docs[0].ranges, + ranges: this.docs[0].ranges }, { _id: this.docs[1]._id.toString(), - ranges: this.docs[1].ranges, - }, + ranges: this.docs[1].ranges + } ]) .should.equal(true) }) @@ -307,7 +307,7 @@ describe('HttpController', function () { beforeEach(function () { return (this.req.params = { project_id: this.project_id, - doc_id: this.doc_id, + doc_id: this.doc_id }) }) @@ -316,7 +316,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), - ranges: (this.ranges = { changes: 'mock' }), + ranges: (this.ranges = { changes: 'mock' }) } this.DocManager.updateDoc = sinon .stub() @@ -348,7 +348,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), - ranges: {}, + ranges: {} } this.DocManager.updateDoc = sinon .stub() @@ -416,7 +416,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = Array(2049).fill('a'.repeat(1024))), version: (this.version = 42), - ranges: (this.ranges = { changes: 'mock' }), + ranges: (this.ranges = { changes: 'mock' }) } return this.HttpController.updateDoc(this.req, this.res, this.next) }) @@ -435,7 +435,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id, + doc_id: this.doc_id } this.DocManager.deleteDoc = sinon.stub().callsArg(2) return this.HttpController.deleteDoc(this.req, this.res, this.next) diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 204a8d96a5..fec3ec0682 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -25,14 +25,14 @@ describe('MongoManager', function () { requires: { './mongojs': { db: (this.db = { docs: {}, docOps: {} }), - ObjectId, + ObjectId }, 'metrics-sharelatex': { timeAsyncMethod: sinon.stub() }, - 'logger-sharelatex': { log() {} }, + 'logger-sharelatex': { log() {} } }, globals: { - console, - }, + console + } }) this.project_id = ObjectId().toString() this.doc_id = ObjectId().toString() @@ -58,7 +58,7 @@ describe('MongoManager', function () { .calledWith( { _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id), + project_id: ObjectId(this.project_id) }, this.filter ) @@ -97,7 +97,7 @@ describe('MongoManager', function () { .calledWith( { project_id: ObjectId(this.project_id), - deleted: { $ne: true }, + deleted: { $ne: true } }, this.filter ) @@ -125,7 +125,7 @@ describe('MongoManager', function () { return this.db.docs.find .calledWith( { - project_id: ObjectId(this.project_id), + project_id: ObjectId(this.project_id) }, this.filter ) @@ -189,7 +189,7 @@ describe('MongoManager', function () { const args = this.db.docs.update.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id), + project_id: ObjectId(this.project_id) }) assert.equal(args[1].$set.deleted, true) return done() @@ -218,13 +218,13 @@ describe('MongoManager', function () { it('should destroy the doc', function () { return sinon.assert.calledWith(this.db.docs.remove, { - _id: ObjectId('123456789012'), + _id: ObjectId('123456789012') }) }) return it('should destroy the docOps', function () { return sinon.assert.calledWith(this.db.docOps.remove, { - doc_id: ObjectId('123456789012'), + doc_id: ObjectId('123456789012') }) }) }) @@ -275,15 +275,15 @@ describe('MongoManager', function () { return this.db.docOps.update .calledWith( { - doc_id: ObjectId(this.doc_id), + doc_id: ObjectId(this.doc_id) }, { $set: { - version: this.version, - }, + version: this.version + } }, { - upsert: true, + upsert: true } ) .should.equal(true) diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index 575b8a1f54..eafc60110b 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -27,9 +27,9 @@ describe('RangeManager', function () { return (this.RangeManager = SandboxedModule.require(modulePath, { requires: { './mongojs': { - ObjectId, - }, - }, + ObjectId + } + } })) }) @@ -47,16 +47,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id, - ts, - }, - }, + ts + } + } ], comments: [ { id: comment_id, - op: { c: 'foo', p: 3, t: thread_id }, - }, - ], + op: { c: 'foo', p: 3, t: thread_id } + } + ] }).should.deep.equal({ changes: [ { @@ -64,16 +64,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id: ObjectId(user_id), - ts: new Date(ts), - }, - }, + ts: new Date(ts) + } + } ], comments: [ { id: ObjectId(comment_id), - op: { c: 'foo', p: 3, t: ObjectId(thread_id) }, - }, - ], + op: { c: 'foo', p: 3, t: ObjectId(thread_id) } + } + ] }) }) @@ -86,29 +86,29 @@ describe('RangeManager', function () { { id: change_id, metadata: { - user_id, - }, - }, + user_id + } + } ], comments: [ { - id: comment_id, - }, - ], + id: comment_id + } + ] }).should.deep.equal({ changes: [ { id: change_id, metadata: { - user_id, - }, - }, + user_id + } + } ], comments: [ { - id: comment_id, - }, - ], + id: comment_id + } + ] }) }) @@ -125,16 +125,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id, - ts, - }, - }, + ts + } + } ], comments: [ { id: comment_id, - op: { c: 'foo', p: 3, t: thread_id }, - }, - ], + op: { c: 'foo', p: 3, t: thread_id } + } + ] } const ranges1_copy = JSON.parse(JSON.stringify(ranges1)) // jsonRangesToMongo modifies in place const ranges2 = JSON.parse( @@ -153,16 +153,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id: ObjectId(), - ts: new Date(), - }, - }, + ts: new Date() + } + } ], comments: [ { id: ObjectId(), - op: { c: 'foo', p: 3, t: ObjectId() }, - }, - ], + op: { c: 'foo', p: 3, t: ObjectId() } + } + ] } return (this.ranges_copy = this.RangeManager.jsonRangesToMongo( JSON.parse(JSON.stringify(this.ranges)) From df0747ec486c80c6290eaf1711f39926ef2319ab Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Fri, 21 Aug 2020 17:50:01 +0100 Subject: [PATCH 278/349] [misc] migrate the app to the native mongo driver acceptance tests to follow in a separate commit --- services/docstore/app.js | 22 ++- services/docstore/app/js/HealthChecker.js | 15 +- services/docstore/app/js/MongoManager.js | 154 ++++++++++-------- services/docstore/app/js/RangeManager.js | 2 +- services/docstore/app/js/mongodb.js | 19 +++ services/docstore/package-lock.json | 64 ++++---- services/docstore/package.json | 1 + .../test/unit/js/DocArchiveManagerTests.js | 2 +- .../docstore/test/unit/js/DocManagerTests.js | 2 +- .../test/unit/js/HttpControllerTests.js | 2 +- .../test/unit/js/MongoManagerTests.js | 65 +++++--- .../test/unit/js/RangeManagerTests.js | 4 +- 12 files changed, 207 insertions(+), 145 deletions(-) create mode 100644 services/docstore/app/js/mongodb.js diff --git a/services/docstore/app.js b/services/docstore/app.js index 555f31137b..7296d311de 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -10,6 +10,7 @@ const Settings = require('settings-sharelatex') const logger = require('logger-sharelatex') const express = require('express') const bodyParser = require('body-parser') +const mongodb = require('./app/js/mongodb') const Errors = require('./app/js/Errors') const HttpController = require('./app/js/HttpController') @@ -76,12 +77,21 @@ const { host } = Settings.internal.docstore if (!module.parent) { // Called directly - app.listen(port, host, function (error) { - if (error != null) { - throw error - } - return logger.info(`Docstore starting up, listening on ${host}:${port}`) - }) + mongodb + .waitForDb() + .then(() => { + app.listen(port, host, function (err) { + if (err) { + logger.fatal({ err }, `Cannot bind to ${host}:${port}. Exiting.`) + process.exit(1) + } + return logger.info(`Docstore starting up, listening on ${host}:${port}`) + }) + }) + .catch((err) => { + logger.fatal({ err }, 'Cannot connect to mongo. Exiting.') + process.exit(1) + }) } module.exports = app diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 70ebc85ad9..a32452a1b2 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -10,7 +10,7 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const { db, ObjectId } = require('./mongojs') +const { getCollection, ObjectId } = require('./mongodb') const request = require('request') const async = require('async') const _ = require('underscore') @@ -19,6 +19,9 @@ const settings = require('settings-sharelatex') const { port } = settings.internal.docstore const logger = require('logger-sharelatex') +const docsCollectionPromise = getCollection('docs') +const docOpsCollectionPromise = getCollection('docOps') + module.exports = { check(callback) { const doc_id = ObjectId() @@ -60,8 +63,14 @@ module.exports = { } }) }, - (cb) => db.docs.remove({ _id: doc_id, project_id }, cb), - (cb) => db.docOps.remove({ doc_id }, cb) + (cb) => + docsCollectionPromise.then((docs) => + docs.deleteOne({ _id: doc_id, project_id }, cb) + ), + (cb) => + docOpsCollectionPromise.then((docOps) => + docOps.deleteOne({ doc_id }, cb) + ) ] return async.series(jobs, callback) } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index b6e90a7ad3..ba1ec83f3d 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -11,28 +11,28 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ let MongoManager -const { db, ObjectId } = require('./mongojs') +const { getCollection, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') const metrics = require('metrics-sharelatex') const { promisify } = require('util') +const docsCollectionPromise = getCollection('docs') +const docOpsCollectionPromise = getCollection('docOps') + module.exports = MongoManager = { findDoc(project_id, doc_id, filter, callback) { if (callback == null) { callback = function (error, doc) {} } - return db.docs.find( - { - _id: ObjectId(doc_id.toString()), - project_id: ObjectId(project_id.toString()) - }, - filter, - function (error, docs) { - if (docs == null) { - docs = [] - } - return callback(error, docs[0]) - } + docsCollectionPromise.then((docs) => + docs.findOne( + { + _id: ObjectId(doc_id.toString()), + project_id: ObjectId(project_id.toString()) + }, + filter, + callback + ) ) }, @@ -44,7 +44,9 @@ module.exports = MongoManager = { if (!options.include_deleted) { query.deleted = { $ne: true } } - return db.docs.find(query, filter, callback) + docsCollectionPromise.then((docs) => + docs.find(query, filter).toArray(callback) + ) }, getArchivedProjectDocs(project_id, callback) { @@ -52,7 +54,7 @@ module.exports = MongoManager = { project_id: ObjectId(project_id.toString()), inS3: true } - return db.docs.find(query, {}, callback) + docsCollectionPromise.then((docs) => docs.find(query).toArray(callback)) }, upsertIntoDocCollection(project_id, doc_id, updates, callback) { @@ -66,24 +68,28 @@ module.exports = MongoManager = { } } update.$set.project_id = ObjectId(project_id) - return db.docs.update( - { _id: ObjectId(doc_id) }, - update, - { upsert: true }, - callback + docsCollectionPromise.then((docs) => + docs.updateOne( + { _id: ObjectId(doc_id) }, + update, + { upsert: true }, + callback + ) ) }, markDocAsDeleted(project_id, doc_id, callback) { - return db.docs.update( - { - _id: ObjectId(doc_id), - project_id: ObjectId(project_id) - }, - { - $set: { deleted: true } - }, - callback + docsCollectionPromise.then((docs) => + docs.updateOne( + { + _id: ObjectId(doc_id), + project_id: ObjectId(project_id) + }, + { + $set: { deleted: true } + }, + callback + ) ) }, @@ -99,30 +105,30 @@ module.exports = MongoManager = { _id: doc_id, rev } - return db.docs.update(query, update, (err) => callback(err)) + docsCollectionPromise.then((docs) => + docs.updateOne(query, update, callback) + ) }, getDocVersion(doc_id, callback) { if (callback == null) { callback = function (error, version) {} } - return db.docOps.find( - { - doc_id: ObjectId(doc_id) - }, - { - version: 1 - }, - function (error, docs) { - if (error != null) { - return callback(error) + docOpsCollectionPromise.then((docOps) => + docOps.findOne( + { + doc_id: ObjectId(doc_id) + }, + { + version: 1 + }, + function (error, doc) { + if (error != null) { + return callback(error) + } + callback(null, (doc && doc.version) || 0) } - if (docs.length < 1 || docs[0].version == null) { - return callback(null, 0) - } else { - return callback(null, docs[0].version) - } - } + ) ) }, @@ -130,36 +136,42 @@ module.exports = MongoManager = { if (callback == null) { callback = function (error) {} } - return db.docOps.update( - { - doc_id: ObjectId(doc_id) - }, - { - $set: { version } - }, - { - upsert: true - }, - callback + docOpsCollectionPromise.then((docOps) => + docOps.updateOne( + { + doc_id: ObjectId(doc_id) + }, + { + $set: { version } + }, + { + upsert: true + }, + callback + ) ) }, destroyDoc(doc_id, callback) { - return db.docs.remove( - { - _id: ObjectId(doc_id) - }, - function (err) { - if (err != null) { - return callback(err) + docsCollectionPromise.then((docs) => + docs.deleteOne( + { + _id: ObjectId(doc_id) + }, + function (err) { + if (err != null) { + return callback(err) + } + docOpsCollectionPromise.then((docOps) => + docOps.deleteOne( + { + doc_id: ObjectId(doc_id) + }, + callback + ) + ) } - return db.docOps.remove( - { - doc_id: ObjectId(doc_id) - }, - callback - ) - } + ) ) } } diff --git a/services/docstore/app/js/RangeManager.js b/services/docstore/app/js/RangeManager.js index b11019657f..fd719e5b15 100644 --- a/services/docstore/app/js/RangeManager.js +++ b/services/docstore/app/js/RangeManager.js @@ -13,7 +13,7 @@ */ let RangeManager const _ = require('underscore') -const { ObjectId } = require('./mongojs') +const { ObjectId } = require('./mongodb') module.exports = RangeManager = { shouldUpdateRanges(doc_ranges, incoming_ranges) { diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js new file mode 100644 index 0000000000..5b0168bda8 --- /dev/null +++ b/services/docstore/app/js/mongodb.js @@ -0,0 +1,19 @@ +const Settings = require('settings-sharelatex') +const { MongoClient, ObjectId } = require('mongodb') + +const clientPromise = MongoClient.connect(Settings.mongo.url) +const dbPromise = clientPromise.then((client) => client.db()) + +async function getCollection(name) { + return (await dbPromise).collection(name) +} + +async function waitForDb() { + await clientPromise +} + +module.exports = { + ObjectId, + getCollection, + waitForDb +} diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index a4c04f4fe1..fe80c62e79 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1438,7 +1438,7 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==" + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" }, "argparse": { "version": "1.0.10", @@ -1727,9 +1727,9 @@ "dev": true }, "bson": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", - "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.5.tgz", + "integrity": "sha512-kDuEzldR21lHciPQAIulLs1LZlCXdLziXI6Mb/TDkwXhb//UORJNPXgcRs2CuO4H0DcMkpfT3/ySsP3unoZjBg==" }, "buffer": { "version": "4.9.2", @@ -1974,7 +1974,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "compressible": { "version": "2.0.18", @@ -2225,7 +2225,7 @@ "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha512-B0n2zDIXpzLzKeoEozorDSa1cHc1t0NjmxP0zuAxbizNU2MBqYJJKYXrrFdKuQliojXynrxgd7l4ahfg/+aA5g==", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "requires": { "strip-bom": "^3.0.0" } @@ -2316,7 +2316,7 @@ "each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha512-4MQloCGGCmT5GJZK5ibgJSvTK1c1QSrNlDvLk6fEyRxjZnXjl+NNFfzhfXpmnWh33Owc9D9klrdzCUi7yc9r4Q==" + "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" }, "ecc-jsbn": { "version": "0.1.2", @@ -3184,7 +3184,7 @@ "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha512-3TOY+4TKV0Ml83PXJQY+JFQaHNV38lzQDIzzXYg1kWdBLenGgoZhAs0CKgzI31vi2pWEpQMq/Yi4bpKwCPkw7g==", + "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" @@ -3193,7 +3193,7 @@ "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", + "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" @@ -3211,7 +3211,7 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==" + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" } } }, @@ -3584,7 +3584,7 @@ "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha512-w0Kz8lJFBoyaurBiNrIvxPqr/gJ6fOfSkpAPOepN3oECqGJag37xPbOv57izi/KP8auHgNYxn5fXtAb+1LsJ6w==", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "requires": { "is-stream": "^1.0.1" }, @@ -3592,7 +3592,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==" + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" } } }, @@ -3613,9 +3613,9 @@ "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" }, "html-escaper": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.1.tgz", - "integrity": "sha512-hNX23TjWwD3q56HpWjUHOKj1+4KKlnjv9PcmBUYKVpga+2cnb9nDx/B1o0yO4n+RZXZdiNxzx6B24C9aNMTkkQ==" + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" }, "http-errors": { "version": "1.7.2", @@ -4301,7 +4301,7 @@ "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==" + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" }, "lodash.get": { "version": "4.4.2", @@ -4804,12 +4804,12 @@ "optional": true }, "mongodb": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.5.tgz", - "integrity": "sha512-GCjDxR3UOltDq00Zcpzql6dQo1sVry60OXJY3TDmFc2SWFY6c8Gn1Ardidc5jDirvJrx2GC3knGOImKphbSL3A==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.0.tgz", + "integrity": "sha512-/XWWub1mHZVoqEsUppE0GV7u9kanLvHxho6EvBxQbShXTKYF9trhZC2NzbulRGeG7xMJHD8IOWRcdKx5LPjAjQ==", "requires": { "bl": "^2.2.0", - "bson": "^1.1.1", + "bson": "^1.1.4", "denque": "^1.4.1", "require_optional": "^1.0.1", "safe-buffer": "^5.1.2", @@ -5186,7 +5186,7 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==" + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-tmpdir": { "version": "1.0.2", @@ -5270,7 +5270,7 @@ "parse-mongo-url": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha512-7bZUusQIrFLwvsLHBnCz2WKYQ5LKO/LwKPnvQxbMIh9gDx8H5ZsknRmLjZdn6GVdrgVOwqDrZKsY0qDLNmRgcw==" + "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" }, "parse-ms": { "version": "2.1.0", @@ -6037,7 +6037,7 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.7.0", @@ -6249,7 +6249,7 @@ "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "requires": { "es6-error": "^4.0.1" } @@ -6365,7 +6365,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, "restore-cursor": { "version": "3.1.0", @@ -6666,7 +6666,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6927,7 +6927,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { "version": "6.0.0", @@ -7055,7 +7055,7 @@ "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", @@ -7083,7 +7083,7 @@ "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -7100,12 +7100,12 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==" + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", @@ -7178,7 +7178,7 @@ "to-mongodb-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha512-vfXXcGYFP8+0L5IPOtUzzVIvPE/G3GN0TKa/PRBlzPqYyhm+UxhPmvv634EQgO4Ot8dHbBFihOslMJQclY8Z9A==" + "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" }, "to-no-case": { "version": "1.0.2", diff --git a/services/docstore/package.json b/services/docstore/package.json index 8ecba94090..cb2d020599 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,6 +26,7 @@ "logger-sharelatex": "^2.2.0", "metrics-sharelatex": "^2.7.0", "mongojs": "3.1.0", + "mongodb": "^3.6.0", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", "tiny-async-pool": "^1.1.0", diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 026c7654b4..dbe6069572 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -3,7 +3,7 @@ const chai = require('chai') const { expect } = chai const modulePath = '../../../app/js/DocArchiveManager.js' const SandboxedModule = require('sandboxed-module') -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const Errors = require('../../../app/js/Errors') chai.use(require('chai-as-promised')) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index e7f5baa567..55955f3704 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -19,7 +19,7 @@ const { assert } = require('chai') chai.should() const { expect } = chai const modulePath = require('path').join(__dirname, '../../../app/js/DocManager') -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const Errors = require('../../../app/js/Errors') describe('DocManager', function () { diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 46132737f2..0c7626baaf 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -19,7 +19,7 @@ const modulePath = require('path').join( __dirname, '../../../app/js/HttpController' ) -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') describe('HttpController', function () { beforeEach(function () { diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index fec3ec0682..fab71a6618 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -16,14 +16,18 @@ const modulePath = require('path').join( __dirname, '../../../app/js/MongoManager' ) -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const { assert } = require('chai') describe('MongoManager', function () { beforeEach(function () { + this.db = {} this.MongoManager = SandboxedModule.require(modulePath, { requires: { - './mongojs': { + './mongodb': { + getCollection: sinon.stub().callsFake((name) => { + return Promise.resolve((this.db[name] = {})) + }), db: (this.db = { docs: {}, docOps: {} }), ObjectId }, @@ -36,14 +40,14 @@ describe('MongoManager', function () { }) this.project_id = ObjectId().toString() this.doc_id = ObjectId().toString() - this.callback = sinon.stub() return (this.stubbedErr = new Error('hello world')) }) describe('findDoc', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) this.doc = { name: 'mock-doc' } - this.db.docs.find = sinon.stub().callsArgWith(2, null, [this.doc]) + this.db.docs.findOne = sinon.stub().callsArgWith(2, null, this.doc) this.filter = { lines: true } return this.MongoManager.findDoc( this.project_id, @@ -54,7 +58,7 @@ describe('MongoManager', function () { }) it('should find the doc', function () { - return this.db.docs.find + this.db.docs.findOne .calledWith( { _id: ObjectId(this.doc_id), @@ -77,13 +81,16 @@ describe('MongoManager', function () { this.doc2 = { name: 'mock-doc2' } this.doc3 = { name: 'mock-doc3' } this.doc4 = { name: 'mock-doc4' } - return (this.db.docs.find = sinon - .stub() - .callsArgWith(2, null, [this.doc, this.doc3, this.doc4])) + this.db.docs.find = sinon.stub().returns({ + toArray: sinon + .stub() + .callsArgWith(0, null, [this.doc, this.doc3, this.doc4]) + }) }) describe('with included_deleted = false', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: false }, @@ -112,7 +119,8 @@ describe('MongoManager', function () { }) return describe('with included_deleted = true', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: true }, @@ -142,7 +150,7 @@ describe('MongoManager', function () { describe('upsertIntoDocCollection', function () { beforeEach(function () { - this.db.docs.update = sinon.stub().callsArgWith(3, this.stubbedErr) + this.db.docs.updateOne = sinon.stub().callsArgWith(3, this.stubbedErr) return (this.oldRev = 77) }) @@ -152,7 +160,7 @@ describe('MongoManager', function () { this.doc_id, { lines: this.lines }, (err) => { - const args = this.db.docs.update.args[0] + const args = this.db.docs.updateOne.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id) }) assert.equal(args[1].$set.lines, this.lines) assert.equal(args[1].$inc.rev, 1) @@ -177,7 +185,7 @@ describe('MongoManager', function () { describe('markDocAsDeleted', function () { beforeEach(function () { - this.db.docs.update = sinon.stub().callsArgWith(2, this.stubbedErr) + this.db.docs.updateOne = sinon.stub().callsArgWith(2, this.stubbedErr) return (this.oldRev = 77) }) @@ -186,7 +194,7 @@ describe('MongoManager', function () { this.project_id, this.doc_id, (err) => { - const args = this.db.docs.update.args[0] + const args = this.db.docs.updateOne.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id), project_id: ObjectId(this.project_id) @@ -211,19 +219,19 @@ describe('MongoManager', function () { describe('destroyDoc', function () { beforeEach(function (done) { - this.db.docs.remove = sinon.stub().yields() - this.db.docOps.remove = sinon.stub().yields() + this.db.docs.deleteOne = sinon.stub().yields() + this.db.docOps.deleteOne = sinon.stub().yields() return this.MongoManager.destroyDoc('123456789012', done) }) it('should destroy the doc', function () { - return sinon.assert.calledWith(this.db.docs.remove, { + return sinon.assert.calledWith(this.db.docs.deleteOne, { _id: ObjectId('123456789012') }) }) return it('should destroy the docOps', function () { - return sinon.assert.calledWith(this.db.docOps.remove, { + return sinon.assert.calledWith(this.db.docOps.deleteOne, { doc_id: ObjectId('123456789012') }) }) @@ -231,14 +239,15 @@ describe('MongoManager', function () { describe('getDocVersion', function () { describe('when the doc exists', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) this.doc = { version: (this.version = 42) } - this.db.docOps.find = sinon.stub().callsArgWith(2, null, [this.doc]) + this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, this.doc) return this.MongoManager.getDocVersion(this.doc_id, this.callback) }) it('should look for the doc in the database', function () { - return this.db.docOps.find + return this.db.docOps.findOne .calledWith({ doc_id: ObjectId(this.doc_id) }, { version: 1 }) .should.equal(true) }) @@ -249,8 +258,9 @@ describe('MongoManager', function () { }) return describe("when the doc doesn't exist", function () { - beforeEach(function () { - this.db.docOps.find = sinon.stub().callsArgWith(2, null, []) + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) + this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, null) return this.MongoManager.getDocVersion(this.doc_id, this.callback) }) @@ -261,9 +271,10 @@ describe('MongoManager', function () { }) return describe('setDocVersion', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(() => done()) this.version = 42 - this.db.docOps.update = sinon.stub().callsArg(3) + this.db.docOps.updateOne = sinon.stub().callsArg(3) return this.MongoManager.setDocVersion( this.doc_id, this.version, @@ -272,7 +283,7 @@ describe('MongoManager', function () { }) it('should update the doc version', function () { - return this.db.docOps.update + return this.db.docOps.updateOne .calledWith( { doc_id: ObjectId(this.doc_id) diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index eafc60110b..471f60e2c8 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -18,7 +18,7 @@ const modulePath = require('path').join( __dirname, '../../../app/js/RangeManager' ) -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const { assert } = require('chai') const _ = require('underscore') @@ -26,7 +26,7 @@ describe('RangeManager', function () { beforeEach(function () { return (this.RangeManager = SandboxedModule.require(modulePath, { requires: { - './mongojs': { + './mongodb': { ObjectId } } From 2fa09928eef7285f9a23cd8a70a14359952753a2 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 24 Aug 2020 10:01:08 +0100 Subject: [PATCH 279/349] [misc] migrate acceptance tests to the native mongo driver, drop mongojs --- services/docstore/app/js/mongojs.js | 9 - services/docstore/package-lock.json | 765 +++--------------- services/docstore/package.json | 1 - .../test/acceptance/js/ArchiveDocsTests.js | 10 +- .../test/acceptance/js/DeletingDocsTests.js | 22 +- .../test/acceptance/js/GettingAllDocsTests.js | 2 +- .../test/acceptance/js/GettingDocsTests.js | 2 +- .../test/acceptance/js/UpdatingDocsTests.js | 2 +- 8 files changed, 135 insertions(+), 678 deletions(-) delete mode 100644 services/docstore/app/js/mongojs.js diff --git a/services/docstore/app/js/mongojs.js b/services/docstore/app/js/mongojs.js deleted file mode 100644 index 41f3bec470..0000000000 --- a/services/docstore/app/js/mongojs.js +++ /dev/null @@ -1,9 +0,0 @@ -// TODO: This file was created by bulk-decaffeinate. -// Sanity-check the conversion and remove this comment. -const Settings = require('settings-sharelatex') -const mongojs = require('mongojs') -const db = mongojs(Settings.mongo.url, ['docs', 'docOps']) -module.exports = { - db, - ObjectId: mongojs.ObjectId -} diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index fe80c62e79..15faeeec6c 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -8,6 +8,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, "requires": { "@babel/highlight": "^7.8.3" } @@ -16,6 +17,7 @@ "version": "7.9.3", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", + "dev": true, "requires": { "@babel/types": "^7.9.0", "jsesc": "^2.5.1", @@ -26,7 +28,8 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true } } }, @@ -34,6 +37,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", @@ -44,6 +48,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -52,6 +57,7 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -59,12 +65,14 @@ "@babel/helper-validator-identifier": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", - "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==" + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "dev": true }, "@babel/highlight": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", @@ -74,7 +82,8 @@ "@babel/parser": { "version": "7.9.3", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.3.tgz", - "integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==" + "integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==", + "dev": true }, "@babel/runtime": { "version": "7.10.5", @@ -99,6 +108,7 @@ "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.6", @@ -109,6 +119,7 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.0", @@ -125,6 +136,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, "requires": { "ms": "^2.1.1" } @@ -132,7 +144,8 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true } } }, @@ -140,6 +153,7 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.9.0", "lodash": "^4.17.13", @@ -1413,6 +1427,7 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -1427,23 +1442,11 @@ "picomatch": "^2.0.4" } }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -1772,17 +1775,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, - "caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", - "requires": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1792,7 +1784,8 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, "camelcase-keys": { "version": "6.1.2", @@ -1838,6 +1831,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -1847,12 +1841,14 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -1911,6 +1907,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", @@ -1920,17 +1917,20 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -1948,6 +1948,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "requires": { "color-name": "1.1.3" } @@ -1955,7 +1956,8 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "combined-stream": { "version": "1.0.8", @@ -1971,11 +1973,6 @@ "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", "dev": true }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" - }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -2091,14 +2088,6 @@ "emitter-listener": "^1.1.1" } }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -2126,18 +2115,6 @@ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, - "cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", - "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - } - }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -2205,7 +2182,8 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==" + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true }, "deep-eql": { "version": "3.0.1", @@ -2222,14 +2200,6 @@ "integrity": "sha512-GtxAN4HvBachZzm4OnWqc45ESpUCMwkYcsjnsPs23FwJbsO+k4t0k9bQCgOmzIlpHO28+WPK/KRbRk0DDHuuDw==", "dev": true }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "requires": { - "strip-bom": "^3.0.0" - } - }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -2313,11 +2283,6 @@ "stream-shift": "^1.0.0" } }, - "each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/each-series/-/each-series-1.0.0.tgz", - "integrity": "sha1-+Ibmxm39sl7x/nNWQUbuXLR4r8s=" - }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -2377,6 +2342,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -2411,11 +2377,6 @@ "is-symbol": "^1.0.2" } }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==" - }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -2437,7 +2398,8 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true }, "eslint": { "version": "6.8.0", @@ -2856,7 +2818,8 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true }, "esquery": { "version": "1.1.0", @@ -2885,7 +2848,8 @@ "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true }, "etag": { "version": "1.8.1", @@ -3053,51 +3017,6 @@ "unpipe": "~1.0.0" } }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "requires": { - "find-up": "^3.0.0" - } - } - } - }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -3181,40 +3100,6 @@ } } }, - "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" - } - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3318,7 +3203,8 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, "get-func-name": { "version": "2.0.0", @@ -3374,7 +3260,8 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true }, "google-auth-library": { "version": "6.0.3", @@ -3554,7 +3441,8 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true }, "has-symbols": { "version": "1.0.1", @@ -3581,21 +3469,6 @@ } } }, - "hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", - "requires": { - "is-stream": "^1.0.1" - }, - "dependencies": { - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - } - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -3610,12 +3483,8 @@ "hosted-git-info": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==" - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "dev": true }, "http-errors": { "version": "1.7.2", @@ -3866,7 +3735,8 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true }, "is-binary-path": { "version": "2.1.0", @@ -3979,7 +3849,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true }, "isstream": { "version": "0.1.2", @@ -3987,116 +3858,6 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==" - }, - "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", - "requires": { - "append-transform": "^1.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", - "requires": { - "html-escaper": "^2.0.0" - } - }, "jmespath": { "version": "0.15.0", "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", @@ -4105,12 +3866,14 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4125,7 +3888,8 @@ "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true }, "json-bigint": { "version": "0.3.0", @@ -4135,11 +3899,6 @@ "bignumber.js": "^7.0.0" } }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" - }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -4298,11 +4057,6 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=" - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -4453,22 +4207,6 @@ "statsd-parser": "~0.0.4" } }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, "make-plural": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", @@ -4525,14 +4263,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", - "requires": { - "source-map": "^0.6.1" - } - }, "mersenne": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", @@ -4816,33 +4546,6 @@ "saslprep": "^1.0.0" } }, - "mongojs": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mongojs/-/mongojs-3.1.0.tgz", - "integrity": "sha512-aXJ4xfXwx9s1cqtKTZ24PypXiWhIgvgENObQzCGbV4QBxEVedy3yuErhx6znk959cF2dOzL2ClgXJvIhfgkpIQ==", - "requires": { - "each-series": "^1.0.0", - "mongodb": "^3.3.2", - "nyc": "^14.1.1", - "once": "^1.4.0", - "parse-mongo-url": "^1.1.1", - "readable-stream": "^3.4.0", - "thunky": "^1.1.0", - "to-mongodb-core": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4887,11 +4590,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "nested-error-stacks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", - "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==" - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -4966,6 +4664,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -4979,91 +4678,6 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -5183,11 +4797,6 @@ "word-wrap": "~1.2.3" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -5233,17 +4842,6 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, - "package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5267,11 +4865,6 @@ "error-ex": "^1.2.0" } }, - "parse-mongo-url": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-mongo-url/-/parse-mongo-url-1.1.1.tgz", - "integrity": "sha1-ZiON9fjnwMjKTNlw1KtqE3PrdbU=" - }, "parse-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", @@ -5285,7 +4878,8 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true }, "path-is-absolute": { "version": "1.0.1", @@ -6034,11 +5628,6 @@ "ipaddr.js": "1.9.1" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" - }, "psl": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", @@ -6246,14 +5835,6 @@ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "requires": { - "es6-error": "^4.0.1" - } - }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -6293,7 +5874,8 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true }, "require-in-the-middle": { "version": "4.0.1", @@ -6337,7 +5919,8 @@ "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "require-relative": { "version": "0.8.7", @@ -6358,6 +5941,7 @@ "version": "1.11.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -6524,7 +6108,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true }, "setprototypeof": { "version": "1.1.1", @@ -6672,46 +6257,11 @@ "memory-pager": "^1.0.2" } }, - "spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "requires": { - "glob": "^7.1.3" - } - } - } - }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -6720,12 +6270,14 @@ "spdx-exceptions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -6734,7 +6286,8 @@ "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true }, "split": { "version": "1.0.1", @@ -6747,7 +6300,8 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, "sse4_crc32": { "version": "6.0.1", @@ -6902,6 +6456,7 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, "requires": { "ansi-regex": "^4.1.0" }, @@ -6909,14 +6464,16 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true } } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true }, "strip-json-comments": { "version": "3.0.1", @@ -7020,109 +6577,6 @@ } } }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - } - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -7142,11 +6596,6 @@ "readable-stream": "2 || 3" } }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" - }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -7173,12 +6622,8 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, - "to-mongodb-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-mongodb-core/-/to-mongodb-core-2.0.0.tgz", - "integrity": "sha1-NZbsdhOsmtO5ioncua77pWnNJ+s=" + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true }, "to-no-case": { "version": "1.0.2", @@ -7384,6 +6829,7 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -7496,6 +6942,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -7503,7 +6950,8 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==" + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true }, "wide-align": { "version": "1.1.3", @@ -7557,6 +7005,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -7566,17 +7015,20 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -7599,16 +7051,6 @@ "mkdirp": "^0.5.1" } }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", @@ -7636,7 +7078,8 @@ "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true }, "yaassertion": { "version": "1.0.2", @@ -7652,6 +7095,7 @@ "version": "13.3.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -7668,12 +7112,14 @@ "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -7681,12 +7127,14 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -7696,6 +7144,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -7704,6 +7153,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -7716,6 +7166,7 @@ "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" diff --git a/services/docstore/package.json b/services/docstore/package.json index cb2d020599..86b9a410fe 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -25,7 +25,6 @@ "express": "^4.17.1", "logger-sharelatex": "^2.2.0", "metrics-sharelatex": "^2.7.0", - "mongojs": "3.1.0", "mongodb": "^3.6.0", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 959af6715b..026fb8dd4d 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -17,7 +17,7 @@ const Settings = require('settings-sharelatex') const chai = require('chai') const { expect } = chai const should = chai.should() -const { db, ObjectId } = require('../../../app/js/mongojs') +const { getCollection, ObjectId } = require('../../../app/js/mongodb') const async = require('async') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') @@ -32,6 +32,14 @@ function uploadContent(path, json, callback) { .catch(callback) } +let db +before(async function () { + db = { + docs: await getCollection('docs'), + docOps: await getCollection('docOps') + } +}) + describe('Archiving', function () { before(function (done) { return DocstoreApp.ensureRunning(done) diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 41a62fbebb..4517b97e36 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -13,13 +13,21 @@ */ const chai = require('chai') chai.should() -const { db, ObjectId } = require('../../../app/js/mongojs') +const { getCollection, ObjectId } = require('../../../app/js/mongodb') const { expect } = chai const DocstoreApp = require('./helpers/DocstoreApp') const Errors = require('../../../app/js/Errors') const DocstoreClient = require('./helpers/DocstoreClient') +let db +before(async function () { + db = { + docs: await getCollection('docs'), + docOps: await getCollection('docOps') + } +}) + describe('Deleting a doc', function () { beforeEach(function (done) { this.project_id = ObjectId() @@ -61,7 +69,7 @@ describe('Deleting a doc', function () { }) return it('should insert a deleted doc into the docs collection', function (done) { - return db.docs.find({ _id: this.doc_id }, (error, docs) => { + return db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { docs[0]._id.should.deep.equal(this.doc_id) docs[0].lines.should.deep.equal(this.lines) docs[0].deleted.should.equal(true) @@ -100,7 +108,7 @@ describe("Destroying a project's documents", function () { }) it('should remove the doc from the docs collection', function (done) { - return db.docs.find({ _id: this.doc_id }, (err, docs) => { + return db.docs.find({ _id: this.doc_id }).toArray((err, docs) => { expect(err).not.to.exist expect(docs).to.deep.equal([]) return done() @@ -108,7 +116,7 @@ describe("Destroying a project's documents", function () { }) return it('should remove the docOps from the docOps collection', function (done) { - return db.docOps.find({ doc_id: this.doc_id }, (err, docOps) => { + return db.docOps.find({ doc_id: this.doc_id }).toArray((err, docOps) => { expect(err).not.to.exist expect(docOps).to.deep.equal([]) return done() @@ -118,7 +126,7 @@ describe("Destroying a project's documents", function () { return describe('when the doc is archived', function () { beforeEach(function (done) { - return DocstoreClient.archiveAllDoc(this.project_id, function (err) { + return DocstoreClient.archiveAllDoc(this.project_id, (err) => { if (err != null) { return done(err) } @@ -127,7 +135,7 @@ describe("Destroying a project's documents", function () { }) it('should remove the doc from the docs collection', function (done) { - return db.docs.find({ _id: this.doc_id }, (err, docs) => { + return db.docs.find({ _id: this.doc_id }).toArray((err, docs) => { expect(err).not.to.exist expect(docs).to.deep.equal([]) return done() @@ -135,7 +143,7 @@ describe("Destroying a project's documents", function () { }) it('should remove the docOps from the docOps collection', function (done) { - return db.docOps.find({ doc_id: this.doc_id }, (err, docOps) => { + return db.docOps.find({ doc_id: this.doc_id }).toArray((err, docOps) => { expect(err).not.to.exist expect(docOps).to.deep.equal([]) return done() diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 01d6662424..143052d71d 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -14,7 +14,7 @@ const sinon = require('sinon') const chai = require('chai') chai.should() -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const async = require('async') const DocstoreApp = require('./helpers/DocstoreApp') diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index b41af2827d..367115d475 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -14,7 +14,7 @@ const sinon = require('sinon') const chai = require('chai') chai.should() -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index 251378a392..3c7d0d36f0 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -13,7 +13,7 @@ const sinon = require('sinon') const chai = require('chai') chai.should() -const { ObjectId } = require('mongojs') +const { ObjectId } = require('mongodb') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') From f9862081b73f5d7fdcaa6faad3d06c5e77471317 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 13 Aug 2020 17:39:49 +0100 Subject: [PATCH 280/349] Add script to migrate data from S3 --- .../docstore/scripts/rearchive-all-docs.js | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 services/docstore/scripts/rearchive-all-docs.js diff --git a/services/docstore/scripts/rearchive-all-docs.js b/services/docstore/scripts/rearchive-all-docs.js new file mode 100644 index 0000000000..731aff9e27 --- /dev/null +++ b/services/docstore/scripts/rearchive-all-docs.js @@ -0,0 +1,123 @@ +const DocArchiveManager = require('../app/js/DocArchiveManager').promises +const MongoManager = require('../app/js/MongoManager').promises +const { getCollection, ObjectId } = require('../app/js/mongodb') +const minimist = require('minimist') + +async function worker(projectId) { + try { + // see if the project needs to be unarchived, and unarchive it + const archivedDocs = await MongoManager.getArchivedProjectDocs(projectId) + if (archivedDocs.length) { + await DocArchiveManager.unArchiveAllDocs(projectId) + } + + // get the doc content so we can validate it + const docs = await MongoManager.getProjectsDocs( + projectId, + { include_deleted: false }, + { lines: 1 } + ) + + // start archiving in the background while we check the content, if it was archived to begin with + let archivePromise + if (archivedDocs.length) { + archivePromise = DocArchiveManager.archiveAllDocs(projectId) + } + + let warning = false + + // validate the doc contents and log any warnings to investigate later + for (const doc of docs) { + if (!doc.lines) { + warning = true + console.error('WARN:', projectId, doc._id, 'has no content') + } + // eslint-disable-next-line no-control-regex + if (doc.lines && doc.lines.some((line) => line.match(/(\r|\u0000)/))) { + warning = true + console.error('WARN:', projectId, doc._id, 'has invalid characters') + } + } + + // ensure the archive process has finished + if (archivePromise) { + await archivePromise + } + + if (!warning) { + // log to stderr along with the other output + console.error('OK:', projectId) + } + } catch (err) { + console.error('ERROR:', projectId, err) + } +} + +async function rearchiveAllDocs() { + const params = minimist(process.argv.slice(2)) + const maxWorkers = params.w || 1 + console.log(`Starting with ${maxWorkers} workers`) + + // start from an objectId and run in ascending order, so we can resume later + const query = {} + const startId = params._[0] + if (startId) { + const validator = new RegExp('^[0-9a-fA-F]{24}$') + if (!validator.test(startId)) { + console.error('Invalid object id') + return + } + query._id = { + $gt: ObjectId(startId) + } + console.log(`Starting from object ID ${startId}`) + } else { + console.log('No object id specified. Starting from the beginning.') + } + + const results = (await getCollection('projects')) + .find(query, { _id: 1 }) + .sort({ _id: 1 }) + let jobCount = 0 + + // keep going until we run out of projects + while (true) { + // get a new project to run a job with + const project = await results.next() + // if there are no more projects, wait until all the jobs have finished and exit + if (!project) { + // eslint-disable-next-line no-unmodified-loop-condition + while (jobCount) { + await new Promise((resolve) => setTimeout(resolve, 50)) + } + return + } + + // wait until there are fewer than maxWorkers jobs running + // eslint-disable-next-line no-unmodified-loop-condition + while (jobCount >= maxWorkers) { + await new Promise((resolve) => setTimeout(resolve, 50)) + } + + // start a new job in the background and then continue the loop + ++jobCount + worker(project._id) + .then(() => --jobCount) + .catch(() => { + console.error('ERROR:', project._id) + --jobCount + }) + } +} + +if (!module.parent) { + rearchiveAllDocs() + .then(() => { + console.log('Finished!') + process.exit(0) + }) + .catch((err) => { + console.error('Something went wrong:', err) + process.exit(1) + }) +} From 96f909deaa132831c821c4b538150ac40170b0b7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2020 19:15:41 +0000 Subject: [PATCH 281/349] Bump bl from 2.2.0 to 2.2.1 Bumps [bl](https://github.com/rvagg/bl) from 2.2.0 to 2.2.1. - [Release notes](https://github.com/rvagg/bl/releases) - [Commits](https://github.com/rvagg/bl/compare/v2.2.0...v2.2.1) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 15faeeec6c..443deb7d83 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1076,11 +1076,6 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" } } }, @@ -1550,9 +1545,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sdk": { - "version": "2.729.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.729.0.tgz", - "integrity": "sha512-x5q/+9wM37tBYCmYNGMj+aU9qeXqhbUH0Dz3wlSpAW55+N4NwlBbpqhyCV3oF9bePEJtEnxLGWNXpb9BNWNhew==", + "version": "2.745.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.745.0.tgz", + "integrity": "sha512-YTmDvxb0foJC/iZOSsn+MdO4g9nPnlyRdhIpFqvPUkrFzWn5rP4mPtDJan2Eu0j4R02pdwfDhmvr82ckH2w7OQ==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -1674,9 +1669,9 @@ "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" }, "bl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz", - "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -4660,6 +4655,11 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", From 09110116249531ae4f738d84801a47a7b8b83416 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Fri, 4 Sep 2020 14:13:07 +0100 Subject: [PATCH 282/349] Add 'endId' parameter to rearchive script --- .../docstore/scripts/rearchive-all-docs.js | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/services/docstore/scripts/rearchive-all-docs.js b/services/docstore/scripts/rearchive-all-docs.js index 731aff9e27..77dfb7cc43 100644 --- a/services/docstore/scripts/rearchive-all-docs.js +++ b/services/docstore/scripts/rearchive-all-docs.js @@ -61,20 +61,32 @@ async function rearchiveAllDocs() { // start from an objectId and run in ascending order, so we can resume later const query = {} const startId = params._[0] + const endId = params.e if (startId) { - const validator = new RegExp('^[0-9a-fA-F]{24}$') - if (!validator.test(startId)) { - console.error('Invalid object id') - return + if (!new RegExp('^[0-9a-fA-F]{24}$').test(startId)) { + throw new Error('Invalid start object id') } query._id = { - $gt: ObjectId(startId) + $gte: ObjectId(startId) } console.log(`Starting from object ID ${startId}`) } else { console.log('No object id specified. Starting from the beginning.') } + if (endId) { + if (!new RegExp('^[0-9a-fA-F]{24}$').test(endId)) { + throw new Error('Invalid end object id') + } + query._id = { + ...(query._id || {}), + ...{ + $lte: ObjectId(endId) + } + } + console.log(`Stopping at object ID ${endId}`) + } + const results = (await getCollection('projects')) .find(query, { _id: 1 }) .sort({ _id: 1 }) From 1988d0afb52b9b714774cdf58e9995d1f215bb66 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <gh2k@users.noreply.github.com> Date: Fri, 4 Sep 2020 14:50:50 +0100 Subject: [PATCH 283/349] Update scripts/rearchive-all-docs.js Co-authored-by: Jakob Ackermann <jakob.ackermann@overleaf.com> --- services/docstore/scripts/rearchive-all-docs.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/services/docstore/scripts/rearchive-all-docs.js b/services/docstore/scripts/rearchive-all-docs.js index 77dfb7cc43..4530a56ce4 100644 --- a/services/docstore/scripts/rearchive-all-docs.js +++ b/services/docstore/scripts/rearchive-all-docs.js @@ -78,12 +78,8 @@ async function rearchiveAllDocs() { if (!new RegExp('^[0-9a-fA-F]{24}$').test(endId)) { throw new Error('Invalid end object id') } - query._id = { - ...(query._id || {}), - ...{ - $lte: ObjectId(endId) - } - } + query._id = query._id || {} + query._id.$lte = ObjectId(endId) console.log(`Stopping at object ID ${endId}`) } From ad4531ff010b7e6fd0f22202753a6183b277c820 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 10 Sep 2020 18:07:14 +0100 Subject: [PATCH 284/349] Upgrade metrics to @overleaf/metrics' --- services/docstore/app.js | 2 +- services/docstore/app/js/MongoManager.js | 2 +- services/docstore/app/js/PersistorManager.js | 2 +- services/docstore/package-lock.json | 247 +++++++++--------- services/docstore/package.json | 2 +- .../test/unit/js/HttpControllerTests.js | 4 + .../test/unit/js/MongoManagerTests.js | 2 +- 7 files changed, 133 insertions(+), 128 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index 7296d311de..a0d7be31ac 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -4,7 +4,7 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const Metrics = require('metrics-sharelatex') +const Metrics = require('@overleaf/metrics') Metrics.initialize('docstore') const Settings = require('settings-sharelatex') const logger = require('logger-sharelatex') diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index ba1ec83f3d..1f503ab061 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -13,7 +13,7 @@ let MongoManager const { getCollection, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') -const metrics = require('metrics-sharelatex') +const metrics = require('@overleaf/metrics') const { promisify } = require('util') const docsCollectionPromise = getCollection('docs') diff --git a/services/docstore/app/js/PersistorManager.js b/services/docstore/app/js/PersistorManager.js index b3d194a210..aae716e7ab 100644 --- a/services/docstore/app/js/PersistorManager.js +++ b/services/docstore/app/js/PersistorManager.js @@ -1,7 +1,7 @@ const settings = require('settings-sharelatex') const persistorSettings = settings.docstore -persistorSettings.Metrics = require('metrics-sharelatex') +persistorSettings.Metrics = require('@overleaf/metrics') const ObjectPersistor = require('@overleaf/object-persistor') const persistor = ObjectPersistor(persistorSettings) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 15faeeec6c..b86ca84bc4 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -517,7 +517,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" }, "debug": { "version": "3.2.6", @@ -1044,6 +1044,32 @@ "uuid": "^3.2.1" } }, + "@overleaf/metrics": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@overleaf/metrics/-/metrics-3.1.0.tgz", + "integrity": "sha512-YUtB2P6LZbk+FRXnmTX8mdiq13IJ98FvZxIKyZp77cmlF9MCAUrtf+nvatC1l5Zce8/RThU9KQBM0p0Na+Ww7g==", + "requires": { + "@google-cloud/debug-agent": "^3.0.0", + "@google-cloud/profiler": "^0.2.3", + "@google-cloud/trace-agent": "^3.2.0", + "compression": "^1.7.4", + "prom-client": "^11.1.3", + "underscore": "~1.6.0", + "yn": "^3.1.1" + }, + "dependencies": { + "underscore": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", + "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=" + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + } + } + }, "@overleaf/o-error": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@overleaf/o-error/-/o-error-3.0.0.tgz", @@ -1087,7 +1113,7 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" }, "@protobufjs/base64": { "version": "1.1.2", @@ -1102,12 +1128,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -1116,27 +1142,27 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" }, "@sindresorhus/is": { "version": "0.15.0", @@ -1547,7 +1573,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "aws-sdk": { "version": "2.729.0", @@ -1633,7 +1659,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-js": { "version": "1.3.1", @@ -1643,7 +1669,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { "tweetnacl": "^0.14.3" @@ -1671,7 +1697,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, "bl": { "version": "2.2.0", @@ -1747,7 +1773,7 @@ "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, "buffer-from": { "version": "1.1.1", @@ -1801,7 +1827,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "chai": { @@ -1939,11 +1965,6 @@ } } }, - "coffee-script": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1988,10 +2009,31 @@ } } }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + } + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "2.0.0", @@ -2113,7 +2155,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cross-spawn": { "version": "6.0.5", @@ -2141,7 +2183,7 @@ "d64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", - "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" + "integrity": "sha512-5eNy3WZziVYnrogqgXhcdEmqcDB2IHurTqLcrgssJsfkMVCUoUaZpK6cJjxxvLV2dUm5SuJMNcYfVGoin9UIRw==" }, "damerau-levenshtein": { "version": "1.0.6", @@ -2152,7 +2194,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -2161,7 +2203,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } @@ -2286,7 +2328,7 @@ "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { "jsbn": "~0.1.0", @@ -2336,7 +2378,7 @@ "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" }, "error-ex": { "version": "1.3.2", @@ -2385,7 +2427,7 @@ "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "requires": { "es6-promise": "^4.0.3" } @@ -2398,7 +2440,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { @@ -2931,7 +2973,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, "fast-crc32c": { @@ -2945,7 +2987,7 @@ "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, "fast-diff": { @@ -2957,7 +2999,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, "fast-levenshtein": { @@ -3029,7 +3071,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" + "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, "flat": { "version": "4.1.0", @@ -3130,7 +3172,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.1.3", @@ -3221,7 +3263,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -3230,7 +3272,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } @@ -3238,7 +3280,7 @@ "glob": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "optional": true, "requires": { "inflight": "^1.0.4", @@ -3399,7 +3441,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { @@ -3609,7 +3651,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3618,7 +3660,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "inquirer": { "version": "7.1.0", @@ -3839,12 +3881,12 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", @@ -3855,7 +3897,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "jmespath": { @@ -3882,7 +3924,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, "jsesc": { @@ -3894,7 +3936,7 @@ "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha512-u+c/u/F+JNPUekHCFyGVycRPyh9UHD5iUhSyIAn10kxbDTJxijwAbT6XHaONEOXuGGfmWUSroheXgHcml4gLgg==", + "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", "requires": { "bignumber.js": "^7.0.0" } @@ -3902,7 +3944,7 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, "json-schema-traverse": { @@ -3920,7 +3962,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "json5": { @@ -3935,7 +3977,7 @@ "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { "assert-plus": "1.0.0", @@ -3947,7 +3989,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } @@ -4050,12 +4092,12 @@ "lodash.at": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=" + "integrity": "sha512-GOTh0SEp+Yosnlpjic+8cl2WM9MykorogkGA9xyIFkkObQ3H3kNZqZ+ohuq4K3FrSVo7hMcZBMataJemrxC3BA==" }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" }, "lodash.get": { "version": "4.4.2", @@ -4066,7 +4108,7 @@ "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" + "integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==" }, "lodash.memoize": { "version": "4.1.2", @@ -4083,7 +4125,7 @@ "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==" + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" }, "lodash.unescape": { "version": "4.0.1", @@ -4198,15 +4240,6 @@ "yallist": "^3.0.2" } }, - "lynx": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/lynx/-/lynx-0.1.1.tgz", - "integrity": "sha512-JI52N0NwK2b/Md0TFPdPtUBI46kjyJXF7+q08l2yvQ56q6QA8s7ZjZQQRoxFpS2jDXNf/B0p8ID+OIKcTsZwzw==", - "requires": { - "mersenne": "~0.0.3", - "statsd-parser": "~0.0.4" - } - }, "make-plural": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", @@ -4263,11 +4296,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, - "mersenne": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/mersenne/-/mersenne-0.0.4.tgz", - "integrity": "sha512-XoSUL+nF8hMTKGQxUs8r3Btdsf1yuKKBdCCGbh3YXgCXuVKishpZv1CNc385w9s8t4Ynwc5h61BwW/FCVulkbg==" - }, "messageformat": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", @@ -4296,33 +4324,6 @@ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" }, - "metrics-sharelatex": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/metrics-sharelatex/-/metrics-sharelatex-2.7.0.tgz", - "integrity": "sha512-fv7TsM2pVhY/VuHqP5p9Ip2BhHfGPrP0e2TuZGCMK9/J83ZuGCrxkpaU3OOz31CWcmcQ5am4Du70EZAaIdA/2A==", - "requires": { - "@google-cloud/debug-agent": "^3.0.0", - "@google-cloud/profiler": "^0.2.3", - "@google-cloud/trace-agent": "^3.2.0", - "coffee-script": "1.6.0", - "lynx": "~0.1.1", - "prom-client": "^11.1.3", - "underscore": "~1.6.0", - "yn": "^3.1.1" - }, - "dependencies": { - "underscore": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz", - "integrity": "sha512-z4o1fvKUojIWh9XuaVLUDdf86RQiq13AC1dmHbTpoyuu+bquHms76v16CjycCbec87J7z0k//SiQVk0sMdFmpQ==" - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" - } - } - }, "mime": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", @@ -4525,7 +4526,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { "version": "2.24.0", @@ -4549,7 +4550,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "mute-stream": { "version": "0.0.8", @@ -4560,7 +4561,7 @@ "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -4582,7 +4583,7 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", "optional": true }, "negotiator": { @@ -4767,10 +4768,15 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } @@ -4884,7 +4890,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", @@ -4934,7 +4940,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "picomatch": { @@ -5913,7 +5919,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", + "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", "dev": true }, "require-main-filename": { @@ -5993,7 +5999,7 @@ "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", "optional": true, "requires": { "glob": "^6.0.1" @@ -6127,7 +6133,7 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" + "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" } } }, @@ -6251,7 +6257,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6342,7 +6348,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } @@ -6350,14 +6356,9 @@ "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==", + "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=", "dev": true }, - "statsd-parser": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/statsd-parser/-/statsd-parser-0.0.4.tgz", - "integrity": "sha512-7XO+ur89EalMXXFQaydsczB8sclr5nDsNIoUu0IzJx1pIbHUhO3LtpSzBwetIuU9DyTLMiVaJBMtWS/Nb2KR4g==" - }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -6484,7 +6485,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" }, "supports-color": { "version": "6.0.0", @@ -6553,7 +6554,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", "requires": { "bintrees": "1.0.1" } @@ -6586,7 +6587,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "3.0.1", @@ -6628,7 +6629,7 @@ "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" + "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" }, "to-regex-range": { "version": "5.0.1", @@ -6642,7 +6643,7 @@ "to-snake-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", + "integrity": "sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==", "requires": { "to-space-case": "^1.0.0" } @@ -6650,7 +6651,7 @@ "to-space-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", + "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", "requires": { "to-no-case": "^1.0.0" } @@ -6708,7 +6709,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, "type-check": { @@ -6807,7 +6808,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "utils-merge": { "version": "1.0.1", @@ -6843,7 +6844,7 @@ "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -6854,7 +6855,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true } } @@ -7040,7 +7041,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", diff --git a/services/docstore/package.json b/services/docstore/package.json index 86b9a410fe..62a0ede96b 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -24,7 +24,7 @@ "body-parser": "^1.19.0", "express": "^4.17.1", "logger-sharelatex": "^2.2.0", - "metrics-sharelatex": "^2.7.0", + "@overleaf/metrics": "^3.1.0", "mongodb": "^3.6.0", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 0c7626baaf..6638dbdbf8 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -23,6 +23,9 @@ const { ObjectId } = require('mongodb') describe('HttpController', function () { beforeEach(function () { + const settings = { + max_doc_length: 2 * 1024 * 1024 + } this.HttpController = SandboxedModule.require(modulePath, { requires: { './DocManager': (this.DocManager = {}), @@ -31,6 +34,7 @@ describe('HttpController', function () { log: sinon.stub(), error: sinon.stub() }), + 'settings-sharelatex': settings, './HealthChecker': {} }, globals: { process } diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index fab71a6618..c33da4f355 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -31,7 +31,7 @@ describe('MongoManager', function () { db: (this.db = { docs: {}, docOps: {} }), ObjectId }, - 'metrics-sharelatex': { timeAsyncMethod: sinon.stub() }, + '@overleaf/metrics': { timeAsyncMethod: sinon.stub() }, 'logger-sharelatex': { log() {} } }, globals: { From 96b85da43e799e4711b5bf8c335952808a45eb12 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Mon, 14 Sep 2020 16:13:18 +0100 Subject: [PATCH 285/349] Update package hashes --- services/docstore/package-lock.json | 144 ++++++++++++++-------------- services/docstore/package.json | 2 +- 2 files changed, 73 insertions(+), 73 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index b86ca84bc4..05a5aef58f 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -517,7 +517,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" }, "debug": { "version": "3.2.6", @@ -1113,7 +1113,7 @@ "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==" }, "@protobufjs/base64": { "version": "1.1.2", @@ -1128,12 +1128,12 @@ "@protobufjs/eventemitter": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==" }, "@protobufjs/fetch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", "requires": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" @@ -1142,27 +1142,27 @@ "@protobufjs/float": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==" }, "@protobufjs/inquire": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==" }, "@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==" }, "@protobufjs/pool": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==" }, "@protobufjs/utf8": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "@sindresorhus/is": { "version": "0.15.0", @@ -1573,7 +1573,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sdk": { "version": "2.729.0", @@ -1659,7 +1659,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha512-9Y0g0Q8rmSt+H33DfKv7FOc3v+iRI+o1lbzt8jGcIosYW37IIW/2XVYq5NPdmaD5NQ59Nk26Kl/vZbwW9Fr8vg==" }, "base64-js": { "version": "1.3.1", @@ -1669,7 +1669,7 @@ "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", "dev": true, "requires": { "tweetnacl": "^0.14.3" @@ -1697,7 +1697,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" + "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" }, "bl": { "version": "2.2.0", @@ -1773,7 +1773,7 @@ "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" }, "buffer-from": { "version": "1.1.1", @@ -1827,7 +1827,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, "chai": { @@ -2033,7 +2033,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "concat-stream": { "version": "2.0.0", @@ -2155,7 +2155,7 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cross-spawn": { "version": "6.0.5", @@ -2183,7 +2183,7 @@ "d64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", - "integrity": "sha512-5eNy3WZziVYnrogqgXhcdEmqcDB2IHurTqLcrgssJsfkMVCUoUaZpK6cJjxxvLV2dUm5SuJMNcYfVGoin9UIRw==" + "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" }, "damerau-levenshtein": { "version": "1.0.6", @@ -2194,7 +2194,7 @@ "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -2203,7 +2203,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true } } @@ -2328,7 +2328,7 @@ "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", "dev": true, "requires": { "jsbn": "~0.1.0", @@ -2378,7 +2378,7 @@ "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" + "integrity": "sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==" }, "error-ex": { "version": "1.3.2", @@ -2427,7 +2427,7 @@ "es6-promisify": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", "requires": { "es6-promise": "^4.0.3" } @@ -2440,7 +2440,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "eslint": { @@ -2973,7 +2973,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", "dev": true }, "fast-crc32c": { @@ -2987,7 +2987,7 @@ "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", "dev": true }, "fast-diff": { @@ -2999,7 +2999,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==", "dev": true }, "fast-levenshtein": { @@ -3071,7 +3071,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" + "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" }, "flat": { "version": "4.1.0", @@ -3172,7 +3172,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "fsevents": { "version": "2.1.3", @@ -3263,7 +3263,7 @@ "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "dev": true, "requires": { "assert-plus": "^1.0.0" @@ -3272,7 +3272,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true } } @@ -3280,7 +3280,7 @@ "glob": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", "optional": true, "requires": { "inflight": "^1.0.4", @@ -3441,7 +3441,7 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", "dev": true }, "har-validator": { @@ -3651,7 +3651,7 @@ "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3660,7 +3660,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "inquirer": { "version": "7.1.0", @@ -3881,12 +3881,12 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", @@ -3897,7 +3897,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "dev": true }, "jmespath": { @@ -3924,7 +3924,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "dev": true }, "jsesc": { @@ -3936,7 +3936,7 @@ "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", + "integrity": "sha512-u+c/u/F+JNPUekHCFyGVycRPyh9UHD5iUhSyIAn10kxbDTJxijwAbT6XHaONEOXuGGfmWUSroheXgHcml4gLgg==", "requires": { "bignumber.js": "^7.0.0" } @@ -3944,7 +3944,7 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==", "dev": true }, "json-schema-traverse": { @@ -3962,7 +3962,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", "dev": true }, "json5": { @@ -3977,7 +3977,7 @@ "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", "dev": true, "requires": { "assert-plus": "1.0.0", @@ -3989,7 +3989,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true } } @@ -4092,12 +4092,12 @@ "lodash.at": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha512-GOTh0SEp+Yosnlpjic+8cl2WM9MykorogkGA9xyIFkkObQ3H3kNZqZ+ohuq4K3FrSVo7hMcZBMataJemrxC3BA==" + "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=" }, "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==" + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, "lodash.get": { "version": "4.4.2", @@ -4108,7 +4108,7 @@ "lodash.has": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==" + "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" }, "lodash.memoize": { "version": "4.1.2", @@ -4125,7 +4125,7 @@ "lodash.pickby": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" + "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==" }, "lodash.unescape": { "version": "4.0.1", @@ -4526,7 +4526,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, "moment": { "version": "2.24.0", @@ -4550,7 +4550,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "mute-stream": { "version": "0.0.8", @@ -4561,7 +4561,7 @@ "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -4583,7 +4583,7 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "optional": true }, "negotiator": { @@ -4776,7 +4776,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "requires": { "wrappy": "1" } @@ -4890,7 +4890,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, "path-is-inside": { "version": "1.0.2", @@ -4940,7 +4940,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", "dev": true }, "picomatch": { @@ -5919,7 +5919,7 @@ "require-like": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha1-rW8wwTvs15cBDEaK+ndcDAprR/o=", + "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "dev": true }, "require-main-filename": { @@ -5999,7 +5999,7 @@ "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", "optional": true, "requires": { "glob": "^6.0.1" @@ -6133,7 +6133,7 @@ "coffee-script": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha1-gIs5bhEPU9AhoZpO8fZb4OjjX6M=" + "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" } } }, @@ -6257,7 +6257,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6348,7 +6348,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true } } @@ -6356,7 +6356,7 @@ "stack-trace": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.9.tgz", - "integrity": "sha1-qPbq7KkGdMMz58Q5U/J1tFFRBpU=", + "integrity": "sha512-vjUc6sfgtgY0dxCdnc40mK6Oftjo9+2K8H/NG81TMhgL392FtiPA9tn9RLyTxXmTLPJPjF3VyzFp6bsWFLisMQ==", "dev": true }, "statuses": { @@ -6485,7 +6485,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { "version": "6.0.0", @@ -6554,7 +6554,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", + "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", "requires": { "bintrees": "1.0.1" } @@ -6587,7 +6587,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, "through2": { "version": "3.0.1", @@ -6629,7 +6629,7 @@ "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", - "integrity": "sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==" + "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo=" }, "to-regex-range": { "version": "5.0.1", @@ -6643,7 +6643,7 @@ "to-snake-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-snake-case/-/to-snake-case-1.0.0.tgz", - "integrity": "sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==", + "integrity": "sha1-znRpE4l5RgGah+Yu366upMYIq4w=", "requires": { "to-space-case": "^1.0.0" } @@ -6651,7 +6651,7 @@ "to-space-case": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz", - "integrity": "sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==", + "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=", "requires": { "to-no-case": "^1.0.0" } @@ -6709,7 +6709,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", "dev": true }, "type-check": { @@ -6808,7 +6808,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "utils-merge": { "version": "1.0.1", @@ -6844,7 +6844,7 @@ "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", "dev": true, "requires": { "assert-plus": "^1.0.0", @@ -6855,7 +6855,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", "dev": true } } @@ -7041,7 +7041,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "write": { "version": "1.0.3", diff --git a/services/docstore/package.json b/services/docstore/package.json index 62a0ede96b..b4c9d54a7e 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -19,12 +19,12 @@ "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write" }, "dependencies": { + "@overleaf/metrics": "^3.1.0", "@overleaf/object-persistor": "git+https://github.com/overleaf/object-persistor.git", "async": "^2.6.3", "body-parser": "^1.19.0", "express": "^4.17.1", "logger-sharelatex": "^2.2.0", - "@overleaf/metrics": "^3.1.0", "mongodb": "^3.6.0", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", From 90a6642b3365f27c9647b16994b1f81588f5c2c2 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Mon, 14 Sep 2020 16:34:34 +0100 Subject: [PATCH 286/349] Replace tiny-async-pool with p-map --- services/docstore/app/js/DocArchiveManager.js | 26 +++++++------------ services/docstore/package-lock.json | 25 ++++++++++++++++-- services/docstore/package.json | 2 +- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index d564113c9b..126fbd6da0 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -7,7 +7,7 @@ const crypto = require('crypto') const Streamifier = require('streamifier') const RangeManager = require('./RangeManager') const PersistorManager = require('./PersistorManager') -const asyncPool = require('tiny-async-pool') +const pMap = require('p-map') const PARALLEL_JOBS = 5 @@ -40,11 +40,9 @@ async function archiveAllDocs(projectId) { } const docsToArchive = docs.filter((doc) => !doc.inS3) - if (docsToArchive.length) { - await asyncPool(PARALLEL_JOBS, docsToArchive, (doc) => - archiveDoc(projectId, doc) - ) - } + await pMap(docsToArchive, (doc) => archiveDoc(projectId, doc), { + concurrency: PARALLEL_JOBS + }) } async function archiveDoc(projectId, doc) { @@ -85,13 +83,9 @@ async function unArchiveAllDocs(projectId) { if (!docs) { throw new Errors.NotFoundError(`No docs for project ${projectId}`) } - if (!docs.length) { - // asyncPool will throw an error with an empty array - return - } - await asyncPool(PARALLEL_JOBS, docs, (doc) => - unarchiveDoc(projectId, doc._id) - ) + await pMap(docs, (doc) => unarchiveDoc(projectId, doc._id), { + concurrency: PARALLEL_JOBS + }) } async function unarchiveDoc(projectId, docId) { @@ -143,9 +137,9 @@ async function destroyAllDocs(projectId) { { _id: 1 } ) if (docs && docs.length) { - await asyncPool(PARALLEL_JOBS, docs, (doc) => - destroyDoc(projectId, doc._id) - ) + await pMap(docs, (doc) => destroyDoc(projectId, doc._id), { + concurrency: PARALLEL_JOBS + }) } } diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 15faeeec6c..16ee117b07 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1382,6 +1382,15 @@ } } }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", @@ -1888,6 +1897,11 @@ "readdirp": "~3.2.0" } }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" + }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -3603,8 +3617,7 @@ "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" }, "inflight": { "version": "1.0.6", @@ -4837,6 +4850,14 @@ } } }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "requires": { + "aggregate-error": "^3.0.0" + } + }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", diff --git a/services/docstore/package.json b/services/docstore/package.json index 86b9a410fe..23392d5e67 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -26,9 +26,9 @@ "logger-sharelatex": "^2.2.0", "metrics-sharelatex": "^2.7.0", "mongodb": "^3.6.0", + "p-map": "^4.0.0", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", - "tiny-async-pool": "^1.1.0", "underscore": "~1.10.2" }, "devDependencies": { From 5d76859622fd7dbf530b4066fb48ec1d341701fc Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Mon, 14 Sep 2020 16:41:40 +0100 Subject: [PATCH 287/349] Remove rearchive script --- .../docstore/scripts/rearchive-all-docs.js | 131 ------------------ 1 file changed, 131 deletions(-) delete mode 100644 services/docstore/scripts/rearchive-all-docs.js diff --git a/services/docstore/scripts/rearchive-all-docs.js b/services/docstore/scripts/rearchive-all-docs.js deleted file mode 100644 index 4530a56ce4..0000000000 --- a/services/docstore/scripts/rearchive-all-docs.js +++ /dev/null @@ -1,131 +0,0 @@ -const DocArchiveManager = require('../app/js/DocArchiveManager').promises -const MongoManager = require('../app/js/MongoManager').promises -const { getCollection, ObjectId } = require('../app/js/mongodb') -const minimist = require('minimist') - -async function worker(projectId) { - try { - // see if the project needs to be unarchived, and unarchive it - const archivedDocs = await MongoManager.getArchivedProjectDocs(projectId) - if (archivedDocs.length) { - await DocArchiveManager.unArchiveAllDocs(projectId) - } - - // get the doc content so we can validate it - const docs = await MongoManager.getProjectsDocs( - projectId, - { include_deleted: false }, - { lines: 1 } - ) - - // start archiving in the background while we check the content, if it was archived to begin with - let archivePromise - if (archivedDocs.length) { - archivePromise = DocArchiveManager.archiveAllDocs(projectId) - } - - let warning = false - - // validate the doc contents and log any warnings to investigate later - for (const doc of docs) { - if (!doc.lines) { - warning = true - console.error('WARN:', projectId, doc._id, 'has no content') - } - // eslint-disable-next-line no-control-regex - if (doc.lines && doc.lines.some((line) => line.match(/(\r|\u0000)/))) { - warning = true - console.error('WARN:', projectId, doc._id, 'has invalid characters') - } - } - - // ensure the archive process has finished - if (archivePromise) { - await archivePromise - } - - if (!warning) { - // log to stderr along with the other output - console.error('OK:', projectId) - } - } catch (err) { - console.error('ERROR:', projectId, err) - } -} - -async function rearchiveAllDocs() { - const params = minimist(process.argv.slice(2)) - const maxWorkers = params.w || 1 - console.log(`Starting with ${maxWorkers} workers`) - - // start from an objectId and run in ascending order, so we can resume later - const query = {} - const startId = params._[0] - const endId = params.e - if (startId) { - if (!new RegExp('^[0-9a-fA-F]{24}$').test(startId)) { - throw new Error('Invalid start object id') - } - query._id = { - $gte: ObjectId(startId) - } - console.log(`Starting from object ID ${startId}`) - } else { - console.log('No object id specified. Starting from the beginning.') - } - - if (endId) { - if (!new RegExp('^[0-9a-fA-F]{24}$').test(endId)) { - throw new Error('Invalid end object id') - } - query._id = query._id || {} - query._id.$lte = ObjectId(endId) - console.log(`Stopping at object ID ${endId}`) - } - - const results = (await getCollection('projects')) - .find(query, { _id: 1 }) - .sort({ _id: 1 }) - let jobCount = 0 - - // keep going until we run out of projects - while (true) { - // get a new project to run a job with - const project = await results.next() - // if there are no more projects, wait until all the jobs have finished and exit - if (!project) { - // eslint-disable-next-line no-unmodified-loop-condition - while (jobCount) { - await new Promise((resolve) => setTimeout(resolve, 50)) - } - return - } - - // wait until there are fewer than maxWorkers jobs running - // eslint-disable-next-line no-unmodified-loop-condition - while (jobCount >= maxWorkers) { - await new Promise((resolve) => setTimeout(resolve, 50)) - } - - // start a new job in the background and then continue the loop - ++jobCount - worker(project._id) - .then(() => --jobCount) - .catch(() => { - console.error('ERROR:', project._id) - --jobCount - }) - } -} - -if (!module.parent) { - rearchiveAllDocs() - .then(() => { - console.log('Finished!') - process.exit(0) - }) - .catch((err) => { - console.error('Something went wrong:', err) - process.exit(1) - }) -} From 465bf473d93c4893dbdb4f46eed9bd1dab31e342 Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Thu, 17 Sep 2020 14:30:25 +0100 Subject: [PATCH 288/349] Upgrade node to 10.22.1 --- services/docstore/.github/dependabot.yml | 6 ++++++ services/docstore/.nvmrc | 2 +- services/docstore/Dockerfile | 2 +- services/docstore/buildscript.txt | 4 ++-- services/docstore/docker-compose.yml | 4 ++-- 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/services/docstore/.github/dependabot.yml b/services/docstore/.github/dependabot.yml index c6f98d843d..e2c64a3351 100644 --- a/services/docstore/.github/dependabot.yml +++ b/services/docstore/.github/dependabot.yml @@ -15,3 +15,9 @@ updates: # 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 + + # currently assign team-magma to all dependabot PRs - this may change in + # future if we reorganise teams + labels: + - "dependencies" + - "Team-Magma" diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index b61c07ffdd..c2f6421352 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -10.21.0 +10.22.1 diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 78a715757d..f0e362fca0 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -2,7 +2,7 @@ # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -FROM node:10.21.0 as base +FROM node:10.22.1 as base WORKDIR /app diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 53561414dc..706cda6a95 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -3,6 +3,6 @@ docstore --docker-repos=gcr.io/overleaf-ops --env-add= --env-pass-through= ---node-version=10.21.0 +--node-version=10.22.1 --public-repo=True ---script-version=3.3.2 +--script-version=3.3.5 diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 4ea846b682..f854ec67a5 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -6,7 +6,7 @@ version: "2.3" services: test_unit: - image: node:10.21.0 + image: node:10.22.1 volumes: - .:/app working_dir: /app @@ -18,7 +18,7 @@ services: user: node test_acceptance: - image: node:10.21.0 + image: node:10.22.1 volumes: - .:/app working_dir: /app From 7dd2d95b162cef8d315d09408078ade7f308e208 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 17 Sep 2020 14:37:55 +0000 Subject: [PATCH 289/349] Bump node-fetch from 2.6.0 to 2.6.1 Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1. - [Release notes](https://github.com/bitinn/node-fetch/releases) - [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md) - [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 84c29d46aa..4c4d39b444 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1571,9 +1571,9 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sdk": { - "version": "2.745.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.745.0.tgz", - "integrity": "sha512-YTmDvxb0foJC/iZOSsn+MdO4g9nPnlyRdhIpFqvPUkrFzWn5rP4mPtDJan2Eu0j4R02pdwfDhmvr82ckH2w7OQ==", + "version": "2.754.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.754.0.tgz", + "integrity": "sha512-87WVpDOY9LlJtbN6/RszHrr8NxN/M/Qb5luNX3IayUUt+emkBrl6ZKPrG+N1s+WXEyLxkNE4fxiBkiS/5/TiEg==", "requires": { "buffer": "4.9.2", "events": "1.1.1", @@ -4647,9 +4647,9 @@ } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-forge": { "version": "0.9.1", From 8a8a830ad31198c17fc14b31a890b3cc64404907 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Fri, 28 Aug 2020 13:13:19 +0100 Subject: [PATCH 290/349] [misc] simplify mongodb collection access using a shared db construct Resolve the getCollection Promises once and store the result in a shared `db` object which can get imported by all the call-sites. The http server is starting only after a Promise of `waitForDb()` resolves. This covers the app code and the acceptance tests. --- services/docstore/app/js/HealthChecker.js | 15 +- services/docstore/app/js/MongoManager.js | 145 ++++++++---------- services/docstore/app/js/mongodb.js | 15 +- .../test/acceptance/js/ArchiveDocsTests.js | 10 +- .../test/acceptance/js/DeletingDocsTests.js | 10 +- .../test/acceptance/js/helpers/DocstoreApp.js | 10 +- .../test/unit/js/MongoManagerTests.js | 23 +-- 7 files changed, 89 insertions(+), 139 deletions(-) diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index a32452a1b2..567774af3e 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -10,7 +10,7 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const { getCollection, ObjectId } = require('./mongodb') +const { db, ObjectId } = require('./mongodb') const request = require('request') const async = require('async') const _ = require('underscore') @@ -19,9 +19,6 @@ const settings = require('settings-sharelatex') const { port } = settings.internal.docstore const logger = require('logger-sharelatex') -const docsCollectionPromise = getCollection('docs') -const docOpsCollectionPromise = getCollection('docOps') - module.exports = { check(callback) { const doc_id = ObjectId() @@ -63,14 +60,8 @@ module.exports = { } }) }, - (cb) => - docsCollectionPromise.then((docs) => - docs.deleteOne({ _id: doc_id, project_id }, cb) - ), - (cb) => - docOpsCollectionPromise.then((docOps) => - docOps.deleteOne({ doc_id }, cb) - ) + (cb) => db.docs.deleteOne({ _id: doc_id, project_id }, cb), + (cb) => db.docOps.deleteOne({ doc_id }, cb) ] return async.series(jobs, callback) } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 1f503ab061..76d9a88f14 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -11,28 +11,23 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ let MongoManager -const { getCollection, ObjectId } = require('./mongodb') +const { db, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') const metrics = require('@overleaf/metrics') const { promisify } = require('util') -const docsCollectionPromise = getCollection('docs') -const docOpsCollectionPromise = getCollection('docOps') - module.exports = MongoManager = { findDoc(project_id, doc_id, filter, callback) { if (callback == null) { callback = function (error, doc) {} } - docsCollectionPromise.then((docs) => - docs.findOne( - { - _id: ObjectId(doc_id.toString()), - project_id: ObjectId(project_id.toString()) - }, - filter, - callback - ) + db.docs.findOne( + { + _id: ObjectId(doc_id.toString()), + project_id: ObjectId(project_id.toString()) + }, + filter, + callback ) }, @@ -44,9 +39,7 @@ module.exports = MongoManager = { if (!options.include_deleted) { query.deleted = { $ne: true } } - docsCollectionPromise.then((docs) => - docs.find(query, filter).toArray(callback) - ) + db.docs.find(query, filter).toArray(callback) }, getArchivedProjectDocs(project_id, callback) { @@ -54,7 +47,7 @@ module.exports = MongoManager = { project_id: ObjectId(project_id.toString()), inS3: true } - docsCollectionPromise.then((docs) => docs.find(query).toArray(callback)) + db.docs.find(query).toArray(callback) }, upsertIntoDocCollection(project_id, doc_id, updates, callback) { @@ -68,28 +61,24 @@ module.exports = MongoManager = { } } update.$set.project_id = ObjectId(project_id) - docsCollectionPromise.then((docs) => - docs.updateOne( - { _id: ObjectId(doc_id) }, - update, - { upsert: true }, - callback - ) + db.docs.updateOne( + { _id: ObjectId(doc_id) }, + update, + { upsert: true }, + callback ) }, markDocAsDeleted(project_id, doc_id, callback) { - docsCollectionPromise.then((docs) => - docs.updateOne( - { - _id: ObjectId(doc_id), - project_id: ObjectId(project_id) - }, - { - $set: { deleted: true } - }, - callback - ) + db.docs.updateOne( + { + _id: ObjectId(doc_id), + project_id: ObjectId(project_id) + }, + { + $set: { deleted: true } + }, + callback ) }, @@ -105,30 +94,26 @@ module.exports = MongoManager = { _id: doc_id, rev } - docsCollectionPromise.then((docs) => - docs.updateOne(query, update, callback) - ) + db.docs.updateOne(query, update, callback) }, getDocVersion(doc_id, callback) { if (callback == null) { callback = function (error, version) {} } - docOpsCollectionPromise.then((docOps) => - docOps.findOne( - { - doc_id: ObjectId(doc_id) - }, - { - version: 1 - }, - function (error, doc) { - if (error != null) { - return callback(error) - } - callback(null, (doc && doc.version) || 0) + db.docOps.findOne( + { + doc_id: ObjectId(doc_id) + }, + { + version: 1 + }, + function (error, doc) { + if (error != null) { + return callback(error) } - ) + callback(null, (doc && doc.version) || 0) + } ) }, @@ -136,42 +121,36 @@ module.exports = MongoManager = { if (callback == null) { callback = function (error) {} } - docOpsCollectionPromise.then((docOps) => - docOps.updateOne( - { - doc_id: ObjectId(doc_id) - }, - { - $set: { version } - }, - { - upsert: true - }, - callback - ) + db.docOps.updateOne( + { + doc_id: ObjectId(doc_id) + }, + { + $set: { version } + }, + { + upsert: true + }, + callback ) }, destroyDoc(doc_id, callback) { - docsCollectionPromise.then((docs) => - docs.deleteOne( - { - _id: ObjectId(doc_id) - }, - function (err) { - if (err != null) { - return callback(err) - } - docOpsCollectionPromise.then((docOps) => - docOps.deleteOne( - { - doc_id: ObjectId(doc_id) - }, - callback - ) - ) + db.docs.deleteOne( + { + _id: ObjectId(doc_id) + }, + function (err) { + if (err != null) { + return callback(err) } - ) + db.docOps.deleteOne( + { + doc_id: ObjectId(doc_id) + }, + callback + ) + } ) } } diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js index 5b0168bda8..1838011999 100644 --- a/services/docstore/app/js/mongodb.js +++ b/services/docstore/app/js/mongodb.js @@ -2,18 +2,21 @@ const Settings = require('settings-sharelatex') const { MongoClient, ObjectId } = require('mongodb') const clientPromise = MongoClient.connect(Settings.mongo.url) -const dbPromise = clientPromise.then((client) => client.db()) - -async function getCollection(name) { - return (await dbPromise).collection(name) -} async function waitForDb() { await clientPromise } +const db = {} +waitForDb().then(async function () { + const internalDb = (await clientPromise).db() + + db.docs = internalDb.collection('docs') + db.docOps = internalDb.collection('docOps') +}) + module.exports = { + db, ObjectId, - getCollection, waitForDb } diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 026fb8dd4d..4a6901f4c7 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -17,7 +17,7 @@ const Settings = require('settings-sharelatex') const chai = require('chai') const { expect } = chai const should = chai.should() -const { getCollection, ObjectId } = require('../../../app/js/mongodb') +const { db, ObjectId } = require('../../../app/js/mongodb') const async = require('async') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') @@ -32,14 +32,6 @@ function uploadContent(path, json, callback) { .catch(callback) } -let db -before(async function () { - db = { - docs: await getCollection('docs'), - docOps: await getCollection('docOps') - } -}) - describe('Archiving', function () { before(function (done) { return DocstoreApp.ensureRunning(done) diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 4517b97e36..24c78903ee 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -13,21 +13,13 @@ */ const chai = require('chai') chai.should() -const { getCollection, ObjectId } = require('../../../app/js/mongodb') +const { db, ObjectId } = require('../../../app/js/mongodb') const { expect } = chai const DocstoreApp = require('./helpers/DocstoreApp') const Errors = require('../../../app/js/Errors') const DocstoreClient = require('./helpers/DocstoreClient') -let db -before(async function () { - db = { - docs: await getCollection('docs'), - docOps: await getCollection('docOps') - } -}) - describe('Deleting a doc', function () { beforeEach(function (done) { this.project_id = ObjectId() diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 67dc1760e4..351a744b13 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -12,6 +12,7 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ const app = require('../../../../app') +const { waitForDb } = require('../../../../app/js/mongodb') require('logger-sharelatex').logger.level('error') const settings = require('settings-sharelatex') @@ -27,9 +28,10 @@ module.exports = { return callback() } else if (this.initing) { return this.callbacks.push(callback) - } else { - this.initing = true - this.callbacks.push(callback) + } + this.initing = true + this.callbacks.push(callback) + waitForDb().then(() => { return app.listen( settings.internal.docstore.port, 'localhost', @@ -47,6 +49,6 @@ module.exports = { })() } ) - } + }) } } diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index c33da4f355..ed0d2376dd 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -21,13 +21,9 @@ const { assert } = require('chai') describe('MongoManager', function () { beforeEach(function () { - this.db = {} this.MongoManager = SandboxedModule.require(modulePath, { requires: { './mongodb': { - getCollection: sinon.stub().callsFake((name) => { - return Promise.resolve((this.db[name] = {})) - }), db: (this.db = { docs: {}, docOps: {} }), ObjectId }, @@ -40,12 +36,12 @@ describe('MongoManager', function () { }) this.project_id = ObjectId().toString() this.doc_id = ObjectId().toString() + this.callback = sinon.stub() return (this.stubbedErr = new Error('hello world')) }) describe('findDoc', function () { - beforeEach(function (done) { - this.callback = sinon.stub().callsFake(() => done()) + beforeEach(function () { this.doc = { name: 'mock-doc' } this.db.docs.findOne = sinon.stub().callsArgWith(2, null, this.doc) this.filter = { lines: true } @@ -89,8 +85,7 @@ describe('MongoManager', function () { }) describe('with included_deleted = false', function () { - beforeEach(function (done) { - this.callback = sinon.stub().callsFake(() => done()) + beforeEach(function () { return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: false }, @@ -119,8 +114,7 @@ describe('MongoManager', function () { }) return describe('with included_deleted = true', function () { - beforeEach(function (done) { - this.callback = sinon.stub().callsFake(() => done()) + beforeEach(function () { return this.MongoManager.getProjectsDocs( this.project_id, { include_deleted: true }, @@ -239,8 +233,7 @@ describe('MongoManager', function () { describe('getDocVersion', function () { describe('when the doc exists', function () { - beforeEach(function (done) { - this.callback = sinon.stub().callsFake(() => done()) + beforeEach(function () { this.doc = { version: (this.version = 42) } this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, this.doc) return this.MongoManager.getDocVersion(this.doc_id, this.callback) @@ -258,8 +251,7 @@ describe('MongoManager', function () { }) return describe("when the doc doesn't exist", function () { - beforeEach(function (done) { - this.callback = sinon.stub().callsFake(() => done()) + beforeEach(function () { this.db.docOps.findOne = sinon.stub().callsArgWith(2, null, null) return this.MongoManager.getDocVersion(this.doc_id, this.callback) }) @@ -271,8 +263,7 @@ describe('MongoManager', function () { }) return describe('setDocVersion', function () { - beforeEach(function (done) { - this.callback = sinon.stub().callsFake(() => done()) + beforeEach(function () { this.version = 42 this.db.docOps.updateOne = sinon.stub().callsArg(3) return this.MongoManager.setDocVersion( From 1e7fa2246daf2fb9c571998b2d76fd665fedd29d Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 7 Sep 2020 09:35:38 +0100 Subject: [PATCH 291/349] [misc] mongodb: refactor the process of setting up the db construct Co-Authored-By: John Lees-Miller <jdleesmiller@gmail.com> --- services/docstore/app/js/mongodb.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js index 1838011999..bbecd6501d 100644 --- a/services/docstore/app/js/mongodb.js +++ b/services/docstore/app/js/mongodb.js @@ -3,17 +3,21 @@ const { MongoClient, ObjectId } = require('mongodb') const clientPromise = MongoClient.connect(Settings.mongo.url) +let setupDbPromise async function waitForDb() { - await clientPromise + if (!setupDbPromise) { + setupDbPromise = setupDb() + } + await setupDbPromise } const db = {} -waitForDb().then(async function () { +async function setupDb() { const internalDb = (await clientPromise).db() db.docs = internalDb.collection('docs') db.docOps = internalDb.collection('docOps') -}) +} module.exports = { db, From 54a82b8c62934131b94b5e112a90e84706c0a9cc Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 7 Sep 2020 09:44:19 +0100 Subject: [PATCH 292/349] [misc] mongodb: export a helper for adding new collections to db Co-Authored-By: Eric Mc Sween <eric.mcsween@overleaf.com> Co-Authored-By: Simon Detheridge <s@sd.ai> --- services/docstore/app/js/mongodb.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js index bbecd6501d..e9c425ad95 100644 --- a/services/docstore/app/js/mongodb.js +++ b/services/docstore/app/js/mongodb.js @@ -18,9 +18,16 @@ async function setupDb() { db.docs = internalDb.collection('docs') db.docOps = internalDb.collection('docOps') } +async function addCollection(name) { + await waitForDb() + const internalDb = (await clientPromise).db() + + db[name] = internalDb.collection(name) +} module.exports = { db, ObjectId, + addCollection, waitForDb } From b37e27f0235a06a87e1c185e5a5564602de21a1e Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 7 Sep 2020 10:16:12 +0100 Subject: [PATCH 293/349] [misc] run the codemod for moving mongo projections into options --- services/docstore/app/js/MongoManager.js | 14 +++++++++++--- .../test/unit/js/MongoManagerTests.js | 19 +++++++++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 76d9a88f14..09b93c7405 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -26,7 +26,9 @@ module.exports = MongoManager = { _id: ObjectId(doc_id.toString()), project_id: ObjectId(project_id.toString()) }, - filter, + { + projection: filter + }, callback ) }, @@ -39,7 +41,11 @@ module.exports = MongoManager = { if (!options.include_deleted) { query.deleted = { $ne: true } } - db.docs.find(query, filter).toArray(callback) + db.docs + .find(query, { + projection: filter + }) + .toArray(callback) }, getArchivedProjectDocs(project_id, callback) { @@ -106,7 +112,9 @@ module.exports = MongoManager = { doc_id: ObjectId(doc_id) }, { - version: 1 + projection: { + version: 1 + } }, function (error, doc) { if (error != null) { diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index ed0d2376dd..12fd3fba6c 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -60,7 +60,9 @@ describe('MongoManager', function () { _id: ObjectId(this.doc_id), project_id: ObjectId(this.project_id) }, - this.filter + { + projection: this.filter + } ) .should.equal(true) }) @@ -101,7 +103,9 @@ describe('MongoManager', function () { project_id: ObjectId(this.project_id), deleted: { $ne: true } }, - this.filter + { + projection: this.filter + } ) .should.equal(true) }) @@ -129,7 +133,9 @@ describe('MongoManager', function () { { project_id: ObjectId(this.project_id) }, - this.filter + { + projection: this.filter + } ) .should.equal(true) }) @@ -241,7 +247,12 @@ describe('MongoManager', function () { it('should look for the doc in the database', function () { return this.db.docOps.findOne - .calledWith({ doc_id: ObjectId(this.doc_id) }, { version: 1 }) + .calledWith( + { doc_id: ObjectId(this.doc_id) }, + { + projection: { version: 1 } + } + ) .should.equal(true) }) From 3644db68487e759cbfe6eb43a46cae271a769662 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Thu, 10 Sep 2020 10:36:15 +0100 Subject: [PATCH 294/349] [misc] mongodb: use the new db connector by default mongojs was enabling it by default as well. --- services/docstore/app/js/mongodb.js | 5 ++++- services/docstore/config/settings.defaults.js | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js index e9c425ad95..566b9a07e9 100644 --- a/services/docstore/app/js/mongodb.js +++ b/services/docstore/app/js/mongodb.js @@ -1,7 +1,10 @@ const Settings = require('settings-sharelatex') const { MongoClient, ObjectId } = require('mongodb') -const clientPromise = MongoClient.connect(Settings.mongo.url) +const clientPromise = MongoClient.connect( + Settings.mongo.url, + Settings.mongo.options +) let setupDbPromise async function waitForDb() { diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index c538b79045..54dc112709 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -14,7 +14,12 @@ const Settings = { } }, - mongo: {}, + mongo: { + options: { + useUnifiedTopology: + (process.env.MONGO_USE_UNIFIED_TOPOLOGY || 'true') === 'true' + } + }, docstore: { backend: process.env.BACKEND || 's3', From 31c757cce27eaeed0d42c654fd93e910fcf797ff Mon Sep 17 00:00:00 2001 From: Simon Detheridge <s@sd.ai> Date: Wed, 23 Sep 2020 14:12:22 +0100 Subject: [PATCH 295/349] Don't throw 404 errors when unarchiving, if the doc is already unarchived --- services/docstore/app/js/DocArchiveManager.js | 34 ++- .../test/unit/js/DocArchiveManagerTests.js | 268 ++++++++++-------- 2 files changed, 183 insertions(+), 119 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 126fbd6da0..9bf9284fd0 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -93,15 +93,33 @@ async function unarchiveDoc(projectId, docId) { { project_id: projectId, doc_id: docId }, 'getting doc from persistor' ) + const originalDoc = await MongoManager.findDoc(projectId, docId, { inS3: 1 }) + if (!originalDoc.inS3) { + // return if it's not actually in S3 as there's nothing to do + return + } const key = `${projectId}/${docId}` - const sourceMd5 = await PersistorManager.getObjectMd5Hash( - settings.docstore.bucket, - key - ) - const stream = await PersistorManager.getObjectStream( - settings.docstore.bucket, - key - ) + let stream, sourceMd5 + try { + sourceMd5 = await PersistorManager.getObjectMd5Hash( + settings.docstore.bucket, + key + ) + stream = await PersistorManager.getObjectStream( + settings.docstore.bucket, + key + ) + } catch (err) { + // if we get a 404, we could be in a race and something else has unarchived the doc already + if (err instanceof Errors.NotFoundError) { + const doc = await MongoManager.findDoc(projectId, docId, { inS3: 1 }) + if (!doc.inS3) { + // the doc has been archived while we were looking for it, so no error + return + } + } + throw err + } stream.resume() const json = await _streamToString(stream) const md5 = crypto.createHash('md5').update(json).digest('hex') diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index dbe6069572..000afb1660 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -128,13 +128,13 @@ describe('DocArchiveManager', function () { upsertIntoDocCollection: sinon.stub().resolves(), getProjectsDocs: sinon.stub().resolves(mongoDocs), getArchivedProjectDocs: sinon.stub().resolves(archivedDocs), - findDoc: sinon.stub().resolves(), + findDoc: sinon.stub().rejects(new Errors.NotFoundError()), destroyDoc: sinon.stub().resolves() } } - for (const mongoDoc of mongoDocs) { + for (const mongoDoc of mongoDocs.concat(archivedDocs)) { MongoManager.promises.findDoc - .withArgs(projectId, mongoDoc._id) + .withArgs(projectId, mongoDoc._id, sinon.match.any) .resolves(mongoDoc) } @@ -253,120 +253,166 @@ describe('DocArchiveManager', function () { describe('unarchiveDoc', function () { let docId - beforeEach(function () { - docId = mongoDocs[0]._id + describe('when the doc is in S3', function () { + beforeEach(function () { + MongoManager.promises.findDoc = sinon.stub().resolves({ inS3: true }) + docId = mongoDocs[0]._id + }) + + it('should resolve when passed a valid document', async function () { + await expect(DocArchiveManager.promises.unarchiveDoc(projectId, docId)) + .to.eventually.be.fulfilled + }) + + it('should throw an error if the md5 does not match', async function () { + PersistorManager.getObjectMd5Hash.resolves('badf00d') + await expect( + DocArchiveManager.promises.unarchiveDoc(projectId, docId) + ).to.eventually.be.rejected.and.be.instanceof(Errors.Md5MismatchError) + }) + + it('should update the doc lines in mongo', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect( + MongoManager.promises.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, { + lines: mongoDocs[0].lines + }) + }) + + it('should delete the doc in s3', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect(PersistorManager.deleteObject).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${docId}` + ) + }) + + describe('doc contents', function () { + let mongoDoc, s3Doc + + describe('when the doc has the old schema', function () { + beforeEach(function () { + mongoDoc = { + lines: ['doc', 'lines'] + } + s3Doc = ['doc', 'lines'] + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should return the docs lines', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect( + MongoManager.promises.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, mongoDoc) + }) + }) + + describe('with the new schema and ranges', function () { + beforeEach(function () { + s3Doc = { + lines: ['doc', 'lines'], + ranges: { json: 'ranges' }, + schema_v: 1 + } + mongoDoc = { + lines: ['doc', 'lines'], + ranges: { mongo: 'ranges' } + } + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should return the doc lines and ranges', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect( + MongoManager.promises.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, mongoDoc) + }) + }) + + describe('with the new schema and no ranges', function () { + beforeEach(function () { + s3Doc = { + lines: ['doc', 'lines'], + schema_v: 1 + } + mongoDoc = { + lines: ['doc', 'lines'] + } + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should return only the doc lines', async function () { + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect( + MongoManager.promises.upsertIntoDocCollection + ).to.have.been.calledWith(projectId, docId, mongoDoc) + }) + }) + + describe('with an unrecognised schema', function () { + beforeEach(function () { + s3Doc = { + lines: ['doc', 'lines'], + schema_v: 2 + } + docJson = JSON.stringify(s3Doc) + stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) + }) + + it('should throw an error', async function () { + await expect( + DocArchiveManager.promises.unarchiveDoc(projectId, docId) + ).to.eventually.be.rejectedWith( + "I don't understand the doc format in s3" + ) + }) + }) + }) }) - it('should resolve when passed a valid document', async function () { - await expect(DocArchiveManager.promises.unarchiveDoc(projectId, docId)).to - .eventually.be.fulfilled + it('should not do anything if the file is already unarchived', async function () { + MongoManager.promises.findDoc.resolves({ inS3: false }) + await DocArchiveManager.promises.unarchiveDoc(projectId, docId) + expect(PersistorManager.getObjectStream).not.to.have.been.called }) - it('should throw an error if the md5 does not match', async function () { - PersistorManager.getObjectMd5Hash.resolves('badf00d') + describe('when the file is removed while we are processing it', function () { + beforeEach(function () { + MongoManager.promises.findDoc = sinon.stub().resolves({ inS3: true }) + MongoManager.promises.findDoc.onSecondCall().resolves({ inS3: false }) + }) + + it('should not throw an error if the file is unarchived before we get for its hash', async function () { + PersistorManager.getObjectMd5Hash = sinon + .stub() + .rejects(new Errors.NotFoundError()) + await expect(DocArchiveManager.promises.unarchiveDoc(projectId, docId)) + .to.eventually.be.fulfilled + expect(PersistorManager.getObjectStream).not.to.have.been.called + }) + + it('should not throw an error if the file is unarchived before we download it', async function () { + PersistorManager.getObjectStream = sinon + .stub() + .rejects(new Errors.NotFoundError()) + await expect(DocArchiveManager.promises.unarchiveDoc(projectId, docId)) + .to.eventually.be.fulfilled + expect(MongoManager.promises.upsertIntoDocCollection).not.to.have.been + .called + }) + }) + + it('should throw an error if the file is not found but is still listed as archived', async function () { + PersistorManager.getObjectStream = sinon + .stub() + .rejects(new Errors.NotFoundError()) await expect( DocArchiveManager.promises.unarchiveDoc(projectId, docId) - ).to.eventually.be.rejected.and.be.instanceof(Errors.Md5MismatchError) - }) - - it('should update the doc lines in mongo', async function () { - await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect( - MongoManager.promises.upsertIntoDocCollection - ).to.have.been.calledWith(projectId, docId, { lines: mongoDocs[0].lines }) - }) - - it('should delete the doc in s3', async function () { - await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect(PersistorManager.deleteObject).to.have.been.calledWith( - Settings.docstore.bucket, - `${projectId}/${docId}` - ) - }) - - describe('doc contents', function () { - let mongoDoc, s3Doc - - describe('when the doc has the old schema', function () { - beforeEach(function () { - mongoDoc = { - lines: ['doc', 'lines'] - } - s3Doc = ['doc', 'lines'] - docJson = JSON.stringify(s3Doc) - stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) - }) - - it('should return the docs lines', async function () { - await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect( - MongoManager.promises.upsertIntoDocCollection - ).to.have.been.calledWith(projectId, docId, mongoDoc) - }) - }) - - describe('with the new schema and ranges', function () { - beforeEach(function () { - s3Doc = { - lines: ['doc', 'lines'], - ranges: { json: 'ranges' }, - schema_v: 1 - } - mongoDoc = { - lines: ['doc', 'lines'], - ranges: { mongo: 'ranges' } - } - docJson = JSON.stringify(s3Doc) - stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) - }) - - it('should return the doc lines and ranges', async function () { - await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect( - MongoManager.promises.upsertIntoDocCollection - ).to.have.been.calledWith(projectId, docId, mongoDoc) - }) - }) - - describe('with the new schema and no ranges', function () { - beforeEach(function () { - s3Doc = { - lines: ['doc', 'lines'], - schema_v: 1 - } - mongoDoc = { - lines: ['doc', 'lines'] - } - docJson = JSON.stringify(s3Doc) - stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) - }) - - it('should return only the doc lines', async function () { - await DocArchiveManager.promises.unarchiveDoc(projectId, docId) - expect( - MongoManager.promises.upsertIntoDocCollection - ).to.have.been.calledWith(projectId, docId, mongoDoc) - }) - }) - - describe('with an unrecognised schema', function () { - beforeEach(function () { - s3Doc = { - lines: ['doc', 'lines'], - schema_v: 2 - } - docJson = JSON.stringify(s3Doc) - stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) - }) - - it('should throw an error', async function () { - await expect( - DocArchiveManager.promises.unarchiveDoc(projectId, docId) - ).to.eventually.be.rejectedWith( - "I don't understand the doc format in s3" - ) - }) - }) + ).to.eventually.be.rejected.and.be.instanceof(Errors.NotFoundError) }) }) From f472594819de0f1a4681e175e8e7c232936a3a1a Mon Sep 17 00:00:00 2001 From: Eric Mc Sween <eric.mcsween@overleaf.com> Date: Mon, 23 Nov 2020 10:56:33 -0500 Subject: [PATCH 296/349] Upgrade build-scripts to 3.4.0 This version fixes docker-compose health checks for dependent services. See https://github.com/overleaf/dev-environment/pull/409 for details. --- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose.ci.yml | 14 +++++++++++--- services/docstore/docker-compose.yml | 14 +++++++++++--- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 706cda6a95..82f94eaa85 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -5,4 +5,4 @@ docstore --env-pass-through= --node-version=10.22.1 --public-repo=True ---script-version=3.3.5 +--script-version=3.4.0 diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index b08834d1e6..44afb1765a 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -23,6 +23,7 @@ services: environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis + QUEUES_REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres GCS_API_ENDPOINT: gcs:9090 @@ -50,7 +51,14 @@ services: user: root mongo: image: mongo:4.0 + healthcheck: + test: "mongo --quiet localhost/test --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 1)'" + interval: 1s + retries: 20 gcs: - build: - context: test/acceptance/deps - dockerfile: Dockerfile.fake-gcs + image: fsouza/fake-gcs-server + command: ["--port=9090", "--scheme=http"] + healthcheck: + test: wget --quiet --output-document=/dev/null http://localhost:9090/storage/v1/b + interval: 1s + retries: 20 diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index f854ec67a5..59d22e79ad 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -28,6 +28,7 @@ services: environment: ELASTIC_SEARCH_DSN: es:9200 REDIS_HOST: redis + QUEUES_REDIS_HOST: redis MONGO_HOST: mongo POSTGRES_HOST: postgres GCS_API_ENDPOINT: gcs:9090 @@ -48,8 +49,15 @@ services: mongo: image: mongo:4.0 + healthcheck: + test: "mongo --quiet localhost/test --eval 'quit(db.runCommand({ ping: 1 }).ok ? 0 : 1)'" + interval: 1s + retries: 20 gcs: - build: - context: test/acceptance/deps - dockerfile: Dockerfile.fake-gcs + image: fsouza/fake-gcs-server + command: ["--port=9090", "--scheme=http"] + healthcheck: + test: wget --quiet --output-document=/dev/null http://localhost:9090/storage/v1/b + interval: 1s + retries: 20 From 1e4bc43e08997385a13eafa6fc1131e3fe0a74d9 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Wed, 25 Nov 2020 11:57:23 +0000 Subject: [PATCH 297/349] [misc] bump metrics module to 3.4.1 - renamed package from `metrics-sharelatex` to `@overleaf/metrics` - drop support for statsd backend - decaffeinate - compress `/metrics` response using gzip - bump debugging agents to latest versions - expose prometheus interfaces for custom metrics (custom tags) - cleanup of open sockets metrics - fix deprecation warnings for header access --- services/docstore/package-lock.json | 1359 ++++++++++++++++----------- services/docstore/package.json | 2 +- 2 files changed, 805 insertions(+), 556 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index ea7503ca4c..0abe5e8c9a 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -195,191 +195,191 @@ } }, "@google-cloud/debug-agent": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-3.2.0.tgz", - "integrity": "sha512-fP87kYbS6aeDna08BivwQ1J260mwJGchRi99XdWCgqbRwuFac8ul0OT5i2wEeDSc5QaDX8ZuWQQ0igZvh1rTyQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@google-cloud/debug-agent/-/debug-agent-5.1.3.tgz", + "integrity": "sha512-WbzeEz4MvPlM7DX2QBsPcWgF62u7LSQv/oMYPl0L+TddTebqjDKiVXwxpzWk61NIfcKiet3dyCbPIt3N5o8XPQ==", "requires": { - "@google-cloud/common": "^0.32.0", - "@sindresorhus/is": "^0.15.0", - "acorn": "^6.0.0", + "@google-cloud/common": "^3.0.0", + "acorn": "^8.0.0", "coffeescript": "^2.0.0", "console-log-level": "^1.4.0", - "extend": "^3.0.1", + "extend": "^3.0.2", "findit2": "^2.2.3", - "gcp-metadata": "^1.0.0", - "lodash.pickby": "^4.6.0", - "p-limit": "^2.2.0", - "pify": "^4.0.1", - "semver": "^6.0.0", + "gcp-metadata": "^4.0.0", + "p-limit": "^3.0.1", + "semver": "^7.0.0", "source-map": "^0.6.1", "split": "^1.0.0" }, "dependencies": { "@google-cloud/common": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz", - "integrity": "sha512-bLdPzFvvBMtVkwsoBtygE9oUm3yrNmPa71gvOgucYI/GqvNP2tb6RYsDHPq98kvignhcgHGDI5wyNgxaCo8bKQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.5.0.tgz", + "integrity": "sha512-10d7ZAvKhq47L271AqvHEd8KzJqGU45TY+rwM2Z3JHuB070FeTi7oJJd7elfrnKaEvaktw3hH2wKnRWxk/3oWQ==", "requires": { - "@google-cloud/projectify": "^0.3.3", - "@google-cloud/promisify": "^0.4.0", - "@types/request": "^2.48.1", - "arrify": "^2.0.0", - "duplexify": "^3.6.0", + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", "ent": "^2.2.0", "extend": "^3.0.2", - "google-auth-library": "^3.1.1", - "pify": "^4.0.1", - "retry-request": "^4.0.0", - "teeny-request": "^3.11.3" + "google-auth-library": "^6.1.1", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" } }, "@google-cloud/projectify": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", - "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" }, "@google-cloud/promisify": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz", - "integrity": "sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "acorn": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", + "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==" + }, + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" + }, + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", "requires": { - "es6-promisify": "^5.0.0" - } - }, - "coffeescript": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", - "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" } }, "gaxios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", - "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", + "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", - "https-proxy-agent": "^2.2.1", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", "node-fetch": "^2.3.0" } }, "gcp-metadata": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz", - "integrity": "sha512-Q6HrgfrCQeEircnNP3rCcEgiDv7eF9+1B+1MMgpE190+/+0mjQR8PxeOaRgxZWmdDAF9EIryHB9g1moPiw1SbQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", "requires": { - "gaxios": "^1.0.2", - "json-bigint": "^0.3.0" + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" } }, "google-auth-library": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz", - "integrity": "sha512-cDQMzTotwyWMrg5jRO7q0A4TL/3GWBgO7I7q5xGKNiiFf9SmGY/OJ1YsLMgI2MVHHsEGyrqYnbnmV1AE+Z6DnQ==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz", + "integrity": "sha512-m9mwvY3GWbr7ZYEbl61isWmk+fvTmOt0YNUfPOUY2VH8K5pZlAIWJjxEi0PqR3OjMretyiQLI6GURMrPSwHQ2g==", "requires": { + "arrify": "^2.0.0", "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", "fast-text-encoding": "^1.0.0", - "gaxios": "^1.2.1", - "gcp-metadata": "^1.0.0", - "gtoken": "^2.3.2", - "https-proxy-agent": "^2.2.1", - "jws": "^3.1.5", - "lru-cache": "^5.0.0", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" } }, "google-p12-pem": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", - "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", + "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", "requires": { - "node-forge": "^0.8.0", - "pify": "^4.0.0" + "node-forge": "^0.10.0" } }, "gtoken": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", - "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz", + "integrity": "sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg==", "requires": { - "gaxios": "^1.0.4", - "google-p12-pem": "^1.0.0", - "jws": "^3.1.5", - "mime": "^2.2.0", - "pify": "^4.0.0" + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0", + "mime": "^2.2.0" } }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "bignumber.js": "^9.0.0" } }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "yallist": "^4.0.0" } }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node-forge": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", - "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" }, "teeny-request": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", + "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", "requires": { - "https-proxy-agent": "^2.2.1", - "node-fetch": "^2.2.0", - "uuid": "^3.3.2" + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" } + }, + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -451,216 +451,180 @@ } }, "@google-cloud/profiler": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-0.2.3.tgz", - "integrity": "sha512-rNvtrFtIebIxZEJ/O0t8n7HciZGIXBo8DvHxWqAmsCaeLvkTtsaL6HmPkwxrNQ1IhbYWAxF+E/DwCiHyhKmgTg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-4.1.0.tgz", + "integrity": "sha512-9e1zXRctLSUHAoAsFGwE4rS28fr0siiG+jXl5OpwTK8ZAUlxb70aosHaZGdsv8YXrYKjuiufjRZ/OXCs0XLI9g==", "requires": { - "@google-cloud/common": "^0.26.0", + "@google-cloud/common": "^3.0.0", "@types/console-log-level": "^1.4.0", - "@types/semver": "^5.5.0", - "bindings": "^1.2.1", + "@types/semver": "^7.0.0", "console-log-level": "^1.4.0", "delay": "^4.0.1", - "extend": "^3.0.1", - "gcp-metadata": "^0.9.0", - "nan": "^2.11.1", - "parse-duration": "^0.1.1", - "pify": "^4.0.0", - "pretty-ms": "^4.0.0", - "protobufjs": "~6.8.6", - "semver": "^5.5.0", - "teeny-request": "^3.3.0" + "extend": "^3.0.2", + "gcp-metadata": "^4.0.0", + "parse-duration": "^0.4.4", + "pprof": "3.0.0", + "pretty-ms": "^7.0.0", + "protobufjs": "~6.10.0", + "semver": "^7.0.0", + "teeny-request": "^7.0.0" }, "dependencies": { "@google-cloud/common": { - "version": "0.26.2", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.26.2.tgz", - "integrity": "sha512-xJ2M/q3MrUbnYZuFlpF01caAlEhAUoRn0NXp93Hn3pkFpfSOG8YfbKbpBAHvcKVbBOAKVIwPsleNtuyuabUwLQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.5.0.tgz", + "integrity": "sha512-10d7ZAvKhq47L271AqvHEd8KzJqGU45TY+rwM2Z3JHuB070FeTi7oJJd7elfrnKaEvaktw3hH2wKnRWxk/3oWQ==", "requires": { - "@google-cloud/projectify": "^0.3.2", - "@google-cloud/promisify": "^0.3.0", - "@types/duplexify": "^3.5.0", - "@types/request": "^2.47.0", - "arrify": "^1.0.1", - "duplexify": "^3.6.0", + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", "ent": "^2.2.0", - "extend": "^3.0.1", - "google-auth-library": "^2.0.0", - "pify": "^4.0.0", - "retry-request": "^4.0.0", - "through2": "^3.0.0" + "extend": "^3.0.2", + "google-auth-library": "^6.1.1", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" } }, "@google-cloud/projectify": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", - "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" }, "@google-cloud/promisify": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.3.1.tgz", - "integrity": "sha512-QzB0/IMvB0eFxFK7Eqh+bfC8NLv3E9ScjWQrPOk6GgfNroxcVITdTlT8NRsRrcp5+QQJVPLkRqKG0PUdaWXmHw==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" }, - "@types/node": { - "version": "10.17.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.26.tgz", - "integrity": "sha512-myMwkO2Cr82kirHY8uknNRHEVtn0wV3DTQfkrjx17jmkstDRZ24gNUdl8AHXVyVclTYI/bNjgTPTAWvWLqXqkw==" + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", "requires": { - "es6-promisify": "^5.0.0" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==" - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "requires": { - "ms": "^2.1.1" + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" } }, "gaxios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", - "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", + "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", - "https-proxy-agent": "^2.2.1", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", "node-fetch": "^2.3.0" } }, "gcp-metadata": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.9.3.tgz", - "integrity": "sha512-caV4S84xAjENtpezLCT/GILEAF5h/bC4cNqZFmt/tjTn8t+JBtTkQrgBrJu3857YdsnlM8rxX/PMcKGtE8hUlw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", "requires": { - "gaxios": "^1.0.2", - "json-bigint": "^0.3.0" + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" } }, "google-auth-library": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-2.0.2.tgz", - "integrity": "sha512-FURxmo1hBVmcfLauuMRKOPYAPKht3dGuI2wjeJFalDUThO0HoYVjr4yxt5cgYSFm1dgUpmN9G/poa7ceTFAIiA==", + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz", + "integrity": "sha512-m9mwvY3GWbr7ZYEbl61isWmk+fvTmOt0YNUfPOUY2VH8K5pZlAIWJjxEi0PqR3OjMretyiQLI6GURMrPSwHQ2g==", "requires": { - "axios": "^0.18.0", - "gcp-metadata": "^0.7.0", - "gtoken": "^2.3.0", - "https-proxy-agent": "^2.2.1", - "jws": "^3.1.5", - "lru-cache": "^5.0.0", - "semver": "^5.5.0" - }, - "dependencies": { - "gcp-metadata": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-0.7.0.tgz", - "integrity": "sha512-ffjC09amcDWjh3VZdkDngIo7WoluyC5Ag9PAYxZbmQLOLNI8lvPtoKTSCyU54j2gwy5roZh6sSMTfkY2ct7K3g==", - "requires": { - "axios": "^0.18.0", - "extend": "^3.0.1", - "retry-axios": "0.3.2" - } - } + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" } }, "google-p12-pem": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", - "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", + "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", "requires": { - "node-forge": "^0.8.0", - "pify": "^4.0.0" + "node-forge": "^0.10.0" } }, "gtoken": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", - "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz", + "integrity": "sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg==", "requires": { - "gaxios": "^1.0.4", - "google-p12-pem": "^1.0.0", - "jws": "^3.1.5", - "mime": "^2.2.0", - "pify": "^4.0.0" + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0", + "mime": "^2.2.0" } }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "bignumber.js": "^9.0.0" } }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "yallist": "^4.0.0" } }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node-forge": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", - "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, - "protobufjs": { - "version": "6.8.9", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.9.tgz", - "integrity": "sha512-j2JlRdUeL/f4Z6x4aU4gj9I2LECglC+5qR2TrWb193Tla1qfdaNQTZ8I27Pt7K0Ajmvjjpft7O3KWTGciz4gpw==", + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" } }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + }, "teeny-request": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", + "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", "requires": { - "https-proxy-agent": "^2.2.1", - "node-fetch": "^2.2.0", - "uuid": "^3.3.2" + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" } + }, + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -809,185 +773,207 @@ } }, "@google-cloud/trace-agent": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-3.6.1.tgz", - "integrity": "sha512-KDo85aPN4gSxJ7oEIOlKd7aGENZFXAM1kbIn1Ds+61gh/K1CQWSyepgJo3nUpAwH6D1ezDWV7Iaf8ueoITc8Uw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-5.1.1.tgz", + "integrity": "sha512-YTcK0RLN90pLCprg0XC8uV4oAVd79vsXhkcxmEVwiOOYjUDvSrAhb7y/0SY606zgfhJHmUTNb/fZSWEtZP/slQ==", "requires": { - "@google-cloud/common": "^0.32.1", + "@google-cloud/common": "^3.0.0", + "@opencensus/propagation-stackdriver": "0.0.22", "builtin-modules": "^3.0.0", "console-log-level": "^1.4.0", "continuation-local-storage": "^3.2.1", - "extend": "^3.0.0", - "gcp-metadata": "^1.0.0", + "extend": "^3.0.2", + "gcp-metadata": "^4.0.0", + "google-auth-library": "^6.0.0", "hex2dec": "^1.0.1", "is": "^3.2.0", "methods": "^1.1.1", - "require-in-the-middle": "^4.0.0", - "semver": "^6.0.0", + "require-in-the-middle": "^5.0.0", + "semver": "^7.0.0", "shimmer": "^1.2.0", - "uuid": "^3.0.1" + "source-map-support": "^0.5.16", + "uuid": "^8.0.0" }, "dependencies": { "@google-cloud/common": { - "version": "0.32.1", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.32.1.tgz", - "integrity": "sha512-bLdPzFvvBMtVkwsoBtygE9oUm3yrNmPa71gvOgucYI/GqvNP2tb6RYsDHPq98kvignhcgHGDI5wyNgxaCo8bKQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.5.0.tgz", + "integrity": "sha512-10d7ZAvKhq47L271AqvHEd8KzJqGU45TY+rwM2Z3JHuB070FeTi7oJJd7elfrnKaEvaktw3hH2wKnRWxk/3oWQ==", "requires": { - "@google-cloud/projectify": "^0.3.3", - "@google-cloud/promisify": "^0.4.0", - "@types/request": "^2.48.1", - "arrify": "^2.0.0", - "duplexify": "^3.6.0", + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", "ent": "^2.2.0", "extend": "^3.0.2", - "google-auth-library": "^3.1.1", - "pify": "^4.0.1", - "retry-request": "^4.0.0", - "teeny-request": "^3.11.3" + "google-auth-library": "^6.1.1", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "dependencies": { + "google-auth-library": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz", + "integrity": "sha512-m9mwvY3GWbr7ZYEbl61isWmk+fvTmOt0YNUfPOUY2VH8K5pZlAIWJjxEi0PqR3OjMretyiQLI6GURMrPSwHQ2g==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + } } }, "@google-cloud/projectify": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-0.3.3.tgz", - "integrity": "sha512-7522YHQ4IhaafgSunsFF15nG0TGVmxgXidy9cITMe+256RgqfcrfWphiMufW+Ou4kqagW/u3yxwbzVEW3dk2Uw==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==" }, "@google-cloud/promisify": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-0.4.0.tgz", - "integrity": "sha512-4yAHDC52TEMCNcMzVC8WlqnKKKq+Ssi2lXoUg9zWWkZ6U6tq9ZBRYLHHCRdfU+EU9YJsVmivwGcKYCjRGjnf4Q==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "@opencensus/core": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", + "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", "requires": { - "es6-promisify": "^5.0.0" + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^7.0.0", + "shimmer": "^1.2.0", + "uuid": "^8.0.0" } }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "@opencensus/propagation-stackdriver": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-stackdriver/-/propagation-stackdriver-0.0.22.tgz", + "integrity": "sha512-eBvf/ihb1mN8Yz/ASkz8nHzuMKqygu77+VNnUeR0yEh3Nj+ykB8VVR6lK+NAFXo1Rd1cOsTmgvuXAZgDAGleQQ==", "requires": { - "ms": "^2.1.1" + "@opencensus/core": "^0.0.22", + "hex2dec": "^1.0.1", + "uuid": "^8.0.0" + } + }, + "bignumber.js": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" + }, + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" } }, "gaxios": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-1.8.4.tgz", - "integrity": "sha512-BoENMnu1Gav18HcpV9IleMPZ9exM+AvUjrAOV4Mzs/vfz2Lu/ABv451iEXByKiMPn2M140uul1txXCg83sAENw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", + "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", - "https-proxy-agent": "^2.2.1", + "https-proxy-agent": "^5.0.0", + "is-stream": "^2.0.0", "node-fetch": "^2.3.0" } }, "gcp-metadata": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-1.0.0.tgz", - "integrity": "sha512-Q6HrgfrCQeEircnNP3rCcEgiDv7eF9+1B+1MMgpE190+/+0mjQR8PxeOaRgxZWmdDAF9EIryHB9g1moPiw1SbQ==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", "requires": { - "gaxios": "^1.0.2", - "json-bigint": "^0.3.0" - } - }, - "google-auth-library": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-3.1.2.tgz", - "integrity": "sha512-cDQMzTotwyWMrg5jRO7q0A4TL/3GWBgO7I7q5xGKNiiFf9SmGY/OJ1YsLMgI2MVHHsEGyrqYnbnmV1AE+Z6DnQ==", - "requires": { - "base64-js": "^1.3.0", - "fast-text-encoding": "^1.0.0", - "gaxios": "^1.2.1", - "gcp-metadata": "^1.0.0", - "gtoken": "^2.3.2", - "https-proxy-agent": "^2.2.1", - "jws": "^3.1.5", - "lru-cache": "^5.0.0", - "semver": "^5.5.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } + "gaxios": "^4.0.0", + "json-bigint": "^1.0.0" } }, "google-p12-pem": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-1.0.4.tgz", - "integrity": "sha512-SwLAUJqUfTB2iS+wFfSS/G9p7bt4eWcc2LyfvmUXe7cWp6p3mpxDo6LLI29MXdU6wvPcQ/up298X7GMC5ylAlA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", + "integrity": "sha512-wS0ek4ZtFx/ACKYF3JhyGe5kzH7pgiQ7J5otlumqR9psmWMYc+U9cErKlCYVYHoUaidXHdZ2xbo34kB+S+24hA==", "requires": { - "node-forge": "^0.8.0", - "pify": "^4.0.0" + "node-forge": "^0.10.0" } }, "gtoken": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-2.3.3.tgz", - "integrity": "sha512-EaB49bu/TCoNeQjhCYKI/CurooBKkGxIqFHsWABW0b25fobBYVTMe84A8EBVVZhl8emiUdNypil9huMOTmyAnw==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz", + "integrity": "sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg==", "requires": { - "gaxios": "^1.0.4", - "google-p12-pem": "^1.0.0", - "jws": "^3.1.5", - "mime": "^2.2.0", - "pify": "^4.0.0" + "gaxios": "^4.0.0", + "google-p12-pem": "^3.0.3", + "jws": "^4.0.0", + "mime": "^2.2.0" } }, - "https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "bignumber.js": "^9.0.0" } }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" + "yallist": "^4.0.0" } }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node-forge": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.8.5.tgz", - "integrity": "sha512-vFMQIWt+J/7FLNyKouZ9TazT74PRV3wgv9UT4cRjC8BffxFbKXkgIWR42URCPSnHm/QDz6BOlb2Q0U4+VQT67Q==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" }, "teeny-request": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.0.1.tgz", + "integrity": "sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==", "requires": { - "https-proxy-agent": "^2.2.1", - "node-fetch": "^2.2.0", - "uuid": "^3.3.2" + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "node-fetch": "^2.6.1", + "stream-events": "^1.0.5", + "uuid": "^8.0.0" } + }, + "uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, @@ -1045,13 +1031,13 @@ } }, "@overleaf/metrics": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@overleaf/metrics/-/metrics-3.1.0.tgz", - "integrity": "sha512-YUtB2P6LZbk+FRXnmTX8mdiq13IJ98FvZxIKyZp77cmlF9MCAUrtf+nvatC1l5Zce8/RThU9KQBM0p0Na+Ww7g==", + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@overleaf/metrics/-/metrics-3.4.1.tgz", + "integrity": "sha512-OgjlzuC+2gPdIEDHhmd9LDMu01tk1ln0cJhw1727BZ+Wgf2Z1hjuHRt4JeCkf+PFTHwJutVYT8v6IGPpNEPtbg==", "requires": { - "@google-cloud/debug-agent": "^3.0.0", - "@google-cloud/profiler": "^0.2.3", - "@google-cloud/trace-agent": "^3.2.0", + "@google-cloud/debug-agent": "^5.1.2", + "@google-cloud/profiler": "^4.0.3", + "@google-cloud/trace-agent": "^5.1.1", "compression": "^1.7.4", "prom-client": "^11.1.3", "underscore": "~1.6.0", @@ -1159,11 +1145,6 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, - "@sindresorhus/is": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.15.0.tgz", - "integrity": "sha512-lu8BpxjAtRCAo5ifytTpCPCj99LF7o/2Myn+NXyNCBqvPYn7Pjd76AMmUB5l7XF1U6t0hcWrlEM5ESufW7wAeA==" - }, "@sinonjs/commons": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", @@ -1214,11 +1195,6 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" }, - "@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" - }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -1230,14 +1206,6 @@ "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz", "integrity": "sha512-x+OscEQwcx5Biair4enH7ov9W+clcqUWaZRaxn5IkT4yNWWjRr2oiYDkY/x1uXSTVZOQ2xlbFQySaQGB+VdXGQ==" }, - "@types/duplexify": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", - "integrity": "sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==", - "requires": { - "@types/node": "*" - } - }, "@types/eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", @@ -1274,38 +1242,10 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.13.tgz", "integrity": "sha512-UfvBE9oRCAJVzfR+3eWm/sdLFe/qroAPEXP3GPJ1SehQiEVgZT6NQZWYbPMiJ3UdcKM06v4j+S1lTcdWCmw+3g==" }, - "@types/request": { - "version": "2.48.5", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.5.tgz", - "integrity": "sha512-/LO7xRVnL3DxJ1WkPGDQrp4VTV1reX9RkC85mJ+Qzykj2Bdw+mG15aAfDahc76HtknjzE16SX/Yddn6MxVbmGQ==", - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - }, - "dependencies": { - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - } - } - }, "@types/semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" - }, - "@types/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==" }, "@typescript-eslint/experimental-utils": { "version": "1.13.0", @@ -1352,6 +1292,11 @@ "semver": "5.5.0" } }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -1372,7 +1317,8 @@ "acorn": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true }, "acorn-jsx": { "version": "5.1.0", @@ -1472,6 +1418,20 @@ "picomatch": "^2.0.4" } }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -1577,7 +1537,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "aws-sdk": { "version": "2.754.0", @@ -1620,15 +1581,6 @@ "integrity": "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==", "dev": true }, - "axios": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz", - "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==", - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" - } - }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -1701,7 +1653,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, "bl": { "version": "2.2.1", @@ -1918,6 +1870,11 @@ "readdirp": "~3.2.0" } }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -1974,6 +1931,16 @@ } } }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "coffeescript": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.5.1.tgz", + "integrity": "sha512-J2jRPX0eeFh5VKyVnoLrfVFgLZtnnmp96WQSLAS8OrLm2wtQLcnikYKe1gViJKDH7vucjuhHvBKKBP3rKcD1tQ==" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1993,6 +1960,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -2106,6 +2074,11 @@ } } }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, "console-log-level": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", @@ -2245,6 +2218,11 @@ "type-detect": "^4.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -2261,14 +2239,20 @@ } }, "delay": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz", - "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-4.4.0.tgz", + "integrity": "sha512-txgOrJu3OdtOfTiEOT2e76dJVfG/1dz2NZ4F0Pyt4UGZJryssMRp5vdM5wQoLwSOBNdrJv3F9PAhp/heqd7vrA==" }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "denque": { "version": "1.4.1", @@ -2285,6 +2269,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -2428,19 +2417,6 @@ "is-symbol": "^1.0.2" } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "requires": { - "es6-promise": "^4.0.3" - } - }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -3080,7 +3056,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" + "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, "flat": { "version": "4.1.0", @@ -3133,24 +3109,6 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "dev": true }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - } - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -3178,6 +3136,14 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3193,8 +3159,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -3202,6 +3167,54 @@ "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", "dev": true }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "gaxios": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.4.tgz", @@ -3467,7 +3480,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -3501,6 +3513,11 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "hash-stream-validation": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.3.tgz", @@ -3628,6 +3645,14 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "requires": { + "minimatch": "^3.0.4" + } + }, "import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", @@ -3670,6 +3695,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, "inquirer": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", @@ -3800,7 +3830,8 @@ "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true }, "is-callable": { "version": "1.2.0", @@ -3808,6 +3839,14 @@ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, + "is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "requires": { + "has": "^1.0.3" + } + }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", @@ -4130,11 +4169,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.pickby": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", - "integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==" - }, "lodash.unescape": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", @@ -4366,8 +4400,24 @@ "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } }, "mkdirp": { "version": "0.5.3", @@ -4534,7 +4584,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { "version": "2.24.0", @@ -4594,6 +4644,36 @@ "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", "optional": true }, + "needle": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", + "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + } + } + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -4669,11 +4749,60 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==" }, + "node-pre-gyp": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.16.0.tgz", + "integrity": "sha512-4efGA+X/YXAHLi1hN8KaPrILULaUn2nWecFrn1k2I+99HpoyvcOGEbtcOxpDiUwPF2ZANMJDh32qwOUPenuR1g==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.3", + "needle": "^2.5.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, "node-uuid": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -4692,6 +4821,45 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -4701,8 +4869,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { "version": "1.8.0", @@ -4816,16 +4983,30 @@ "word-wrap": "~1.2.3" } }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } }, "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -4879,9 +5060,9 @@ } }, "parse-duration": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.1.3.tgz", - "integrity": "sha512-hMOZHfUmjxO5hMKn7Eft+ckP2M4nV4yzauLXiw3PndpkASnx5r8pDAMcOAiqxoemqWjMWmz4fOHQM6n6WwETXw==" + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/parse-duration/-/parse-duration-0.4.4.tgz", + "integrity": "sha512-KbAJuYGUhZkB9gotDiKLnZ7Z3VTacK3fgwmDdB6ZVDtJbMBT6MfLga0WJaYpPDu0mzqT0NgHtHDt5PY4l0nidg==" }, "parse-json": { "version": "2.2.0", @@ -4971,9 +5152,9 @@ "dev": true }, "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", + "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==" }, "pkg-dir": { "version": "2.0.0", @@ -4984,6 +5165,38 @@ "find-up": "^2.1.0" } }, + "pprof": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pprof/-/pprof-3.0.0.tgz", + "integrity": "sha512-uPWbAhoH/zvq1kM3/Fd/wshb4D7sLlGap8t6uCTER4aZRWqqyPYgXzpjWbT0Unn5U25pEy2VREUu27nQ9o9VPA==", + "requires": { + "bindings": "^1.2.1", + "delay": "^4.0.1", + "findit2": "^2.2.3", + "nan": "^2.14.0", + "node-pre-gyp": "^0.16.0", + "p-limit": "^3.0.0", + "pify": "^5.0.0", + "protobufjs": "~6.10.0", + "source-map": "^0.7.3", + "split": "^1.0.1" + }, + "dependencies": { + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -5594,11 +5807,11 @@ } }, "pretty-ms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz", - "integrity": "sha512-qG66ahoLCwpLXD09ZPHSCbUWYTqdosB7SMP4OffgTgL2PBKXMuUsrk5Bwg8q4qPkjTXsKBMr+YK3Ltd/6F9s/Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", + "integrity": "sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==", "requires": { - "parse-ms": "^2.0.0" + "parse-ms": "^2.1.0" } }, "progress": { @@ -5775,6 +5988,24 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + } + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -5905,9 +6136,9 @@ "dev": true }, "require-in-the-middle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.1.tgz", - "integrity": "sha512-EfkM2zANyGkrfIExsECMeNn/uzjvHrE9h36yLXSavmrDiH4tgDNvltAmEKnt4PNLbqKPHZz+uszW2wTKrLUX0w==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.0.3.tgz", + "integrity": "sha512-p/ICV8uMlqC4tjOYabLMxAWCIKa0YUQgZZ6KDM0xgXJNgdGQ1WmL2A07TwmrZw+wi6ITUFKzH5v3n+ENEyXVkA==", "requires": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", @@ -5915,11 +6146,11 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -5928,10 +6159,11 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } } @@ -5988,11 +6220,6 @@ "signal-exit": "^3.0.2" } }, - "retry-axios": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz", - "integrity": "sha512-jp4YlI0qyDFfXiXGhkCOliBN1G7fRH03Nqy8YdShzGqbY5/9S2x/IR6C88ls2DFkbWuL3ASkP7QD3pVrNpPgwQ==" - }, "retry-request": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz", @@ -6135,8 +6362,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "setprototypeof": { "version": "1.1.1", @@ -6275,6 +6501,15 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -6572,10 +6807,24 @@ } } }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", "requires": { "bintrees": "1.0.1" } @@ -6979,7 +7228,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "requires": { "string-width": "^1.0.2 || 2" }, @@ -6987,20 +7235,17 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", - "dev": true + "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==" }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -7010,7 +7255,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -7209,6 +7453,11 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/yn/-/yn-4.0.0.tgz", "integrity": "sha512-huWiiCS4TxKc4SfgmTwW1K7JmXPPAmuXWYy4j9qjQo4+27Kni8mGhAAi1cloRWmBe2EqcLgt3IGqQoRL/MtPgg==" + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/services/docstore/package.json b/services/docstore/package.json index 1707d58368..091fea9a94 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -19,7 +19,7 @@ "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write" }, "dependencies": { - "@overleaf/metrics": "^3.1.0", + "@overleaf/metrics": "^3.4.1", "@overleaf/object-persistor": "git+https://github.com/overleaf/object-persistor.git", "async": "^2.6.3", "body-parser": "^1.19.0", From 9d633c5fa72ab57119fb86f8164f1bbffc7627c2 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Wed, 2 Dec 2020 12:39:01 +0000 Subject: [PATCH 298/349] [misc] install @overleaf/object-persistor from tar-ball --- services/docstore/package-lock.json | 14 +++++++------- services/docstore/package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 0abe5e8c9a..f4d759cb4f 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1062,8 +1062,8 @@ "integrity": "sha512-LsM2s6Iy9G97ktPo0ys4VxtI/m3ahc1ZHwjo5XnhXtjeIkkkVAehsrcRRoV/yWepPjymB0oZonhcfojpjYR/tg==" }, "@overleaf/object-persistor": { - "version": "git+https://github.com/overleaf/object-persistor.git#4ca62157a2beb747e9a56da3ce1569124b90378a", - "from": "git+https://github.com/overleaf/object-persistor.git", + "version": "https://github.com/overleaf/object-persistor/archive/4ca62157a2beb747e9a56da3ce1569124b90378a.tar.gz", + "integrity": "sha512-7USiK1g94cFnREqPqtsvmw0OevEYb6wtnBP7mFA4akjz/YqSM+yTrQnobt8TuBmnzRgGabRmQ8yaeBGEzhmxnA==", "requires": { "@google-cloud/storage": "^5.1.2", "@overleaf/o-error": "^3.0.0", @@ -1088,6 +1088,11 @@ "once": "^1.3.0", "path-is-absolute": "^1.0.0" } + }, + "node-uuid": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", + "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" } } }, @@ -4789,11 +4794,6 @@ } } }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=" - }, "nopt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", diff --git a/services/docstore/package.json b/services/docstore/package.json index 091fea9a94..1d794d1398 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@overleaf/metrics": "^3.4.1", - "@overleaf/object-persistor": "git+https://github.com/overleaf/object-persistor.git", + "@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/4ca62157a2beb747e9a56da3ce1569124b90378a.tar.gz", "async": "^2.6.3", "body-parser": "^1.19.0", "express": "^4.17.1", From 2d69ba69c329b5847820b32e64f6aa24d4cb2931 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 13 Dec 2020 07:35:09 +0000 Subject: [PATCH 299/349] Bump ini from 1.3.5 to 1.3.8 Bumps [ini](https://github.com/isaacs/ini) from 1.3.5 to 1.3.8. - [Release notes](https://github.com/isaacs/ini/releases) - [Commits](https://github.com/isaacs/ini/compare/v1.3.5...v1.3.8) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index f4d759cb4f..bb31cee6a7 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -3701,9 +3701,9 @@ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "inquirer": { "version": "7.1.0", From bbcc47a2c40692bb800449e9ed28571a3b24eb9f Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 4 Jan 2021 11:00:39 +0000 Subject: [PATCH 300/349] [misc] fix ci -- pin fake-gcs to a compatible version --- services/docstore/docker-compose.ci.yml | 2 +- services/docstore/docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/docker-compose.ci.yml b/services/docstore/docker-compose.ci.yml index 44afb1765a..f0cac0710e 100644 --- a/services/docstore/docker-compose.ci.yml +++ b/services/docstore/docker-compose.ci.yml @@ -56,7 +56,7 @@ services: interval: 1s retries: 20 gcs: - image: fsouza/fake-gcs-server + image: fsouza/fake-gcs-server:v1.21.2 command: ["--port=9090", "--scheme=http"] healthcheck: test: wget --quiet --output-document=/dev/null http://localhost:9090/storage/v1/b diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 59d22e79ad..d7b8bbc1c9 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -55,7 +55,7 @@ services: retries: 20 gcs: - image: fsouza/fake-gcs-server + image: fsouza/fake-gcs-server:v1.21.2 command: ["--port=9090", "--scheme=http"] healthcheck: test: wget --quiet --output-document=/dev/null http://localhost:9090/storage/v1/b From 9298f486ad086485525c649a297d6b317e1e0b4e Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 4 Jan 2021 11:55:47 +0000 Subject: [PATCH 301/349] [app] add a new route for archiving a single doc There is a minor opportunity for optimizing the mongo call(s) for archiving: we should include `{ inS3: false }` in the queries instead of filtering locally. It's been like that for years now, so it can stay a little longer. --- services/docstore/app.js | 1 + services/docstore/app/js/DocArchiveManager.js | 21 ++++++ services/docstore/app/js/HttpController.js | 11 +++ .../test/acceptance/js/ArchiveDocsTests.js | 68 +++++++++++++++++++ .../acceptance/js/helpers/DocstoreClient.js | 12 ++++ 5 files changed, 113 insertions(+) diff --git a/services/docstore/app.js b/services/docstore/app.js index a0d7be31ac..d6c499d157 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -56,6 +56,7 @@ app.post( app.delete('/project/:project_id/doc/:doc_id', HttpController.deleteDoc) app.post('/project/:project_id/archive', HttpController.archiveAllDocs) +app.post('/project/:project_id/doc/:doc_id/archive', HttpController.archiveDoc) app.post('/project/:project_id/unarchive', HttpController.unArchiveAllDocs) app.post('/project/:project_id/destroy', HttpController.destroyAllDocs) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 9bf9284fd0..a0868d78f6 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -13,6 +13,7 @@ const PARALLEL_JOBS = 5 module.exports = { archiveAllDocs: callbackify(archiveAllDocs), + archiveDocById: callbackify(archiveDocById), archiveDoc: callbackify(archiveDoc), unArchiveAllDocs: callbackify(unArchiveAllDocs), unarchiveDoc: callbackify(unarchiveDoc), @@ -20,6 +21,7 @@ module.exports = { destroyDoc: callbackify(destroyDoc), promises: { archiveAllDocs, + archiveDocById, archiveDoc, unArchiveAllDocs, unarchiveDoc, @@ -45,6 +47,25 @@ async function archiveAllDocs(projectId) { }) } +async function archiveDocById(projectId, docId) { + const doc = await MongoManager.findDoc(projectId, docId, { + lines: true, + ranges: true, + rev: true, + inS3: true + }) + + if (!doc) { + throw new Errors.NotFoundError( + `Cannot find doc ${docId} in project ${projectId}` + ) + } + + // TODO(das7pad): consider refactoring MongoManager.findDoc to take a query + if (doc.inS3) return + return archiveDoc(projectId, doc) +} + async function archiveDoc(projectId, doc) { logger.log( { project_id: projectId, doc_id: doc._id }, diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 50c779736c..320557a5f6 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -222,6 +222,17 @@ module.exports = HttpController = { }) }, + archiveDoc(req, res, next) { + const { project_id, doc_id } = req.params + logger.log({ project_id, doc_id }, 'archiving a doc') + DocArchive.archiveDocById(project_id, doc_id, function (error) { + if (error) { + return next(error) + } + res.sendStatus(204) + }) + }, + unArchiveAllDocs(req, res, next) { if (next == null) { next = function (error) {} diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 4a6901f4c7..234ded5a72 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -275,6 +275,74 @@ describe('Archiving', function () { }) }) + describe('archiving a single doc', function () { + before(function (done) { + this.project_id = ObjectId() + this.timeout(1000 * 30) + this.doc = { + _id: ObjectId(), + lines: ['foo', 'bar'], + ranges: {}, + version: 2 + } + DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + (error) => { + if (error) { + return done(error) + } + DocstoreClient.archiveDocById( + this.project_id, + this.doc._id, + (error, res) => { + this.res = res + if (error) { + return done(error) + } + done() + } + ) + } + ) + }) + + it('should successully archive the doc', function (done) { + this.res.statusCode.should.equal(204) + done() + }) + + it('should set inS3 and unset lines and ranges in the doc', function (done) { + db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error) { + return done(error) + } + should.not.exist(doc.lines) + should.not.exist(doc.ranges) + doc.inS3.should.equal(true) + done() + }) + }) + + it('should set the doc in s3 correctly', function (done) { + DocstoreClient.getS3Doc( + this.project_id, + this.doc._id, + (error, s3_doc) => { + if (error) { + return done(error) + } + s3_doc.lines.should.deep.equal(this.doc.lines) + s3_doc.ranges.should.deep.equal(this.doc.ranges) + done() + } + ) + }) + }) + describe('a doc with large lines', function () { before(function (done) { this.project_id = ObjectId() diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 237ef42134..92b2b95e21 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -129,6 +129,18 @@ module.exports = DocstoreClient = { ) }, + archiveDocById(project_id, doc_id, callback) { + if (callback == null) { + callback = function (error, res, body) {} + } + return request.post( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/archive` + }, + callback + ) + }, + destroyAllDoc(project_id, callback) { if (callback == null) { callback = function (error, res, body) {} From 1edc6284540748753da1ed253ca341c33446e4e4 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 4 Jan 2021 15:47:13 +0000 Subject: [PATCH 302/349] [misc] MongoManager: drop unused, potentially expensive default options All call-sites specify an options object. --- services/docstore/app/js/MongoManager.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 09b93c7405..313aec033a 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -34,9 +34,6 @@ module.exports = MongoManager = { }, getProjectsDocs(project_id, options, filter, callback) { - if (options == null) { - options = { include_deleted: true } - } const query = { project_id: ObjectId(project_id.toString()) } if (!options.include_deleted) { query.deleted = { $ne: true } From fa101a44f7fa7f151a4cb0f76ab7ff6742c48e57 Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@overleaf.com> Date: Wed, 6 Jan 2021 09:57:08 +0000 Subject: [PATCH 303/349] Update Node to 10.23.1 --- services/docstore/.nvmrc | 2 +- services/docstore/Dockerfile | 2 +- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose.yml | 4 ++-- services/docstore/package-lock.json | 14 +++++++------- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index c2f6421352..2baa2d433a 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -10.22.1 +10.23.1 diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index f0e362fca0..2da67d2436 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -2,7 +2,7 @@ # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -FROM node:10.22.1 as base +FROM node:10.23.1 as base WORKDIR /app diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 82f94eaa85..1324e672a1 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -3,6 +3,6 @@ docstore --docker-repos=gcr.io/overleaf-ops --env-add= --env-pass-through= ---node-version=10.22.1 +--node-version=10.23.1 --public-repo=True --script-version=3.4.0 diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 59d22e79ad..c9d173a986 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -6,7 +6,7 @@ version: "2.3" services: test_unit: - image: node:10.22.1 + image: node:10.23.1 volumes: - .:/app working_dir: /app @@ -18,7 +18,7 @@ services: user: node test_acceptance: - image: node:10.22.1 + image: node:10.23.1 volumes: - .:/app working_dir: /app diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index f4d759cb4f..0496c805ef 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1658,7 +1658,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" + "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" }, "bl": { "version": "2.2.1", @@ -3061,7 +3061,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" + "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" }, "flat": { "version": "4.1.0", @@ -4589,7 +4589,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" }, "moment": { "version": "2.24.0", @@ -6208,7 +6208,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" }, "restore-cursor": { "version": "3.1.0", @@ -6513,7 +6513,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", + "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6741,7 +6741,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" + "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" }, "supports-color": { "version": "6.0.0", @@ -6824,7 +6824,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", + "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", "requires": { "bintrees": "1.0.1" } From 28b1ad32432a547f46b9776b756f5ab9636cdfb3 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 12 Jan 2021 17:29:06 +0000 Subject: [PATCH 304/349] [misc] add a new endpoint for querying the deleted status of a doc `/project/:project_id/doc/:doc_id/deleted` responds with: - 404: the doc does not exist - 200 and body `{"deleted":true}`: doc exists and is deleted - 200 and body `{"deleted":false}`: doc exists and is not deleted --- services/docstore/app.js | 1 + services/docstore/app/js/DocManager.js | 18 ++++++ services/docstore/app/js/HttpController.js | 10 ++++ .../test/acceptance/js/DeletingDocsTests.js | 59 +++++++++++++++++++ .../acceptance/js/helpers/DocstoreClient.js | 10 ++++ 5 files changed, 98 insertions(+) diff --git a/services/docstore/app.js b/services/docstore/app.js index a0d7be31ac..b7fbeea7dd 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -46,6 +46,7 @@ Metrics.injectMetricsRoute(app) app.get('/project/:project_id/doc', HttpController.getAllDocs) app.get('/project/:project_id/ranges', HttpController.getAllRanges) app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc) +app.get('/project/:project_id/doc/:doc_id/deleted', HttpController.isDocDeleted) app.get('/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc) // Add 64kb overhead for the JSON encoding, and double the size to allow for ranges in the json payload app.post( diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index edd9c0f1cd..bbb4f7fecd 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -90,6 +90,24 @@ module.exports = DocManager = { ) }, + isDocDeleted(projectId, docId, callback) { + MongoManager.findDoc(projectId, docId, { deleted: true }, function ( + err, + doc + ) { + if (err) { + return callback(err) + } + if (!doc) { + return callback( + new Errors.NotFoundError(`No such project/doc: ${projectId}/${docId}`) + ) + } + // `doc.deleted` is `undefined` for non deleted docs + callback(null, Boolean(doc.deleted)) + }) + }, + getFullDoc(project_id, doc_id, callback) { if (callback == null) { callback = function (err, doc) {} diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 50c779736c..8c1254bc2b 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -44,6 +44,16 @@ module.exports = HttpController = { }) }, + isDocDeleted(req, res, next) { + const { doc_id: docId, project_id: projectId } = req.params + DocManager.isDocDeleted(projectId, docId, function (error, deleted) { + if (error) { + return next(error) + } + res.json({ deleted }) + }) + }, + getRawDoc(req, res, next) { if (next == null) { next = function (error) {} diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 24c78903ee..80a448cdcc 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -44,6 +44,19 @@ describe('Deleting a doc', function () { }) }) + it('should show as not deleted on /deleted', function (done) { + DocstoreClient.isDocDeleted( + this.project_id, + this.doc_id, + (error, res, body) => { + if (error) return done(error) + expect(res.statusCode).to.equal(200) + expect(body).to.have.property('deleted').to.equal(false) + done() + } + ) + }) + describe('when the doc exists', function () { beforeEach(function (done) { return DocstoreClient.deleteDoc( @@ -60,6 +73,19 @@ describe('Deleting a doc', function () { return db.docs.remove({ _id: this.doc_id }, done) }) + it('should mark the doc as deleted on /deleted', function (done) { + DocstoreClient.isDocDeleted( + this.project_id, + this.doc_id, + (error, res, body) => { + if (error) return done(error) + expect(res.statusCode).to.equal(200) + expect(body).to.have.property('deleted').to.equal(true) + done() + } + ) + }) + return it('should insert a deleted doc into the docs collection', function (done) { return db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { docs[0]._id.should.deep.equal(this.doc_id) @@ -70,7 +96,40 @@ describe('Deleting a doc', function () { }) }) + describe('when the doc exists in another project', function () { + const otherProjectId = ObjectId() + + it('should show as not existing on /deleted', function (done) { + DocstoreClient.isDocDeleted(otherProjectId, this.doc_id, (error, res) => { + if (error) return done(error) + expect(res.statusCode).to.equal(404) + done() + }) + }) + + it('should return a 404 when trying to delete', function (done) { + DocstoreClient.deleteDoc(otherProjectId, this.doc_id, (error, res) => { + if (error) return done(error) + expect(res.statusCode).to.equal(404) + done() + }) + }) + }) + return describe('when the doc does not exist', function () { + it('should show as not existing on /deleted', function (done) { + const missing_doc_id = ObjectId() + DocstoreClient.isDocDeleted( + this.project_id, + missing_doc_id, + (error, res) => { + if (error) return done(error) + expect(res.statusCode).to.equal(404) + done() + } + ) + }) + return it('should return a 404', function (done) { const missing_doc_id = ObjectId() return DocstoreClient.deleteDoc( diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 237ef42134..9b7588bd65 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -60,6 +60,16 @@ module.exports = DocstoreClient = { ) }, + isDocDeleted(project_id, doc_id, callback) { + request.get( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/deleted`, + json: true + }, + callback + ) + }, + getAllDocs(project_id, callback) { if (callback == null) { callback = function (error, res, body) {} From 708bdfd197a7147e03f156012afc38bf95166b45 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 4 Jan 2021 13:36:19 +0000 Subject: [PATCH 305/349] [DocManager] optionally flush docs out of mongo when deleting them --- services/docstore/app/js/DocManager.js | 14 ++++ services/docstore/config/settings.defaults.js | 2 + .../test/acceptance/js/DeletingDocsTests.js | 71 +++++++++++++++++- .../docstore/test/unit/js/DocManagerTests.js | 72 ++++++++++++++++++- 4 files changed, 155 insertions(+), 4 deletions(-) diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index bbb4f7fecd..409668c313 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -20,6 +20,7 @@ const logger = require('logger-sharelatex') const _ = require('underscore') const DocArchive = require('./DocArchiveManager') const RangeManager = require('./RangeManager') +const Settings = require('settings-sharelatex') module.exports = DocManager = { // TODO: For historical reasons, the doc version is currently stored in the docOps @@ -304,6 +305,19 @@ module.exports = DocManager = { ) ) } + + if (Settings.docstore.archiveOnSoftDelete) { + // The user will not read this doc anytime soon. Flush it out of mongo. + DocArchive.archiveDocById(project_id, doc_id, (err) => { + if (err) { + logger.warn( + { project_id, doc_id, err }, + 'archiving a single doc in the background failed' + ) + } + }) + } + return MongoManager.markDocAsDeleted(project_id, doc_id, callback) }) } diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 54dc112709..0bbf99424e 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -22,6 +22,8 @@ const Settings = { }, docstore: { + archiveOnSoftDelete: process.env.ARCHIVE_ON_SOFT_DELETE === 'true', + backend: process.env.BACKEND || 's3', healthCheck: { project_id: process.env.HEALTH_CHECK_PROJECT_ID diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 80a448cdcc..d32cd52b6b 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -17,6 +17,7 @@ const { db, ObjectId } = require('../../../app/js/mongodb') const { expect } = chai const DocstoreApp = require('./helpers/DocstoreApp') const Errors = require('../../../app/js/Errors') +const Settings = require('settings-sharelatex') const DocstoreClient = require('./helpers/DocstoreClient') @@ -86,7 +87,7 @@ describe('Deleting a doc', function () { ) }) - return it('should insert a deleted doc into the docs collection', function (done) { + it('should insert a deleted doc into the docs collection', function (done) { return db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { docs[0]._id.should.deep.equal(this.doc_id) docs[0].lines.should.deep.equal(this.lines) @@ -94,6 +95,74 @@ describe('Deleting a doc', function () { return done() }) }) + + it('should not export the doc to s3', function (done) { + setTimeout(() => { + DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error) => { + expect(error).to.be.instanceOf(Errors.NotFoundError) + done() + }) + }, 1000) + }) + }) + + describe('when archiveOnSoftDelete is enabled', function () { + let archiveOnSoftDelete + beforeEach(function overwriteSetting() { + archiveOnSoftDelete = Settings.docstore.archiveOnSoftDelete + Settings.docstore.archiveOnSoftDelete = true + }) + afterEach(function restoreSetting() { + Settings.docstore.archiveOnSoftDelete = archiveOnSoftDelete + }) + + beforeEach(function deleteDoc(done) { + DocstoreClient.deleteDoc(this.project_id, this.doc_id, (error, res) => { + this.res = res + done() + }) + }) + + beforeEach(function waitForBackgroundFlush(done) { + setTimeout(done, 500) + }) + + afterEach(function cleanupDoc(done) { + db.docs.remove({ _id: this.doc_id }, done) + }) + + it('should set the deleted flag in the doc', function (done) { + db.docs.findOne({ _id: this.doc_id }, (error, doc) => { + if (error) { + return done(error) + } + expect(doc.deleted).to.equal(true) + done() + }) + }) + + it('should set inS3 and unset lines and ranges in the doc', function (done) { + db.docs.findOne({ _id: this.doc_id }, (error, doc) => { + if (error) { + return done(error) + } + expect(doc.lines).to.not.exist + expect(doc.ranges).to.not.exist + expect(doc.inS3).to.equal(true) + done() + }) + }) + + it('should set the doc in s3 correctly', function (done) { + DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error, s3_doc) => { + if (error) { + return done(error) + } + expect(s3_doc.lines).to.deep.equal(this.lines) + expect(s3_doc.ranges).to.deep.equal(this.ranges) + done() + }) + }) }) describe('when the doc exists in another project', function () { diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 55955f3704..597129b1bd 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -15,6 +15,7 @@ const SandboxedModule = require('sandboxed-module') const sinon = require('sinon') const chai = require('chai') +chai.use(require('sinon-chai')) const { assert } = require('chai') chai.should() const { expect } = chai @@ -34,6 +35,7 @@ describe('DocManager', function () { }, shouldUpdateRanges: sinon.stub().returns(false) }), + 'settings-sharelatex': (this.settings = { docstore: {} }), 'logger-sharelatex': (this.logger = { log: sinon.stub(), warn() {}, @@ -423,13 +425,15 @@ describe('DocManager', function () { describe('deleteDoc', function () { describe('when the doc exists', function () { - beforeEach(function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(done) this.lines = ['mock', 'doc', 'lines'] this.rev = 77 this.DocManager.checkDocExists = sinon .stub() .callsArgWith(2, null, true) - this.MongoManager.markDocAsDeleted = sinon.stub().callsArg(2) + this.MongoManager.markDocAsDeleted = sinon.stub().yields(null) + this.DocArchiveManager.archiveDocById = sinon.stub().yields(null) return this.DocManager.deleteDoc( this.project_id, this.doc_id, @@ -449,9 +453,71 @@ describe('DocManager', function () { .should.equal(true) }) - return it('should return the callback', function () { + it('should return the callback', function () { return this.callback.called.should.equal(true) }) + + describe('background flush disabled', function () { + beforeEach(function () { + this.settings.docstore.archiveOnSoftDelete = false + }) + + it('should not flush the doc out of mongo', function () { + this.DocArchiveManager.archiveDocById.should.not.have.been.called + }) + }) + + describe('background flush enabled', function () { + beforeEach(function (done) { + this.settings.docstore.archiveOnSoftDelete = true + this.callback = sinon.stub().callsFake(done) + this.DocManager.deleteDoc(this.project_id, this.doc_id, this.callback) + }) + + it('should not fail the delete process', function () { + this.callback.should.have.been.calledWith(null) + }) + + it('should flush the doc out of mongo', function () { + this.DocArchiveManager.archiveDocById.should.have.been.calledWith( + this.project_id, + this.doc_id + ) + }) + + describe('when the background flush fails', function () { + beforeEach(function (done) { + this.err = new Error('foo') + this.DocManager.checkDocExists = sinon.stub().yields(null, true) + this.MongoManager.markDocAsDeleted = sinon.stub().yields(null) + this.DocArchiveManager.archiveDocById = sinon + .stub() + .yields(this.err) + this.logger.warn = sinon.stub() + this.callback = sinon.stub().callsFake(done) + this.DocManager.deleteDoc( + this.project_id, + this.doc_id, + this.callback + ) + }) + + it('should log a warning', function () { + this.logger.warn.should.have.been.calledWith( + sinon.match({ + project_id: this.project_id, + doc_id: this.doc_id, + err: this.err + }), + 'archiving a single doc in the background failed' + ) + }) + + it('should not fail the delete process', function () { + this.callback.should.have.been.calledWith(null) + }) + }) + }) }) return describe('when the doc does not exist', function () { From 12bef53645dc21a3778b175c451cacead72df5d7 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 4 Jan 2021 17:04:33 +0000 Subject: [PATCH 306/349] [DocArchiveManager] optionally do not un-archive soft deleted docs --- services/docstore/app/js/DocArchiveManager.js | 7 ++- services/docstore/app/js/MongoManager.js | 9 ++++ services/docstore/config/settings.defaults.js | 2 + .../test/acceptance/js/ArchiveDocsTests.js | 51 +++++++++++++++++-- 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index a0868d78f6..a123ccdfb6 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -100,7 +100,12 @@ async function archiveDoc(projectId, doc) { } async function unArchiveAllDocs(projectId) { - const docs = await MongoManager.getArchivedProjectDocs(projectId) + let docs + if (settings.docstore.keepSoftDeletedDocsArchived) { + docs = await MongoManager.getNonDeletedArchivedProjectDocs(projectId) + } else { + docs = await MongoManager.getArchivedProjectDocs(projectId) + } if (!docs) { throw new Errors.NotFoundError(`No docs for project ${projectId}`) } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 313aec033a..c6bd24c639 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -53,6 +53,15 @@ module.exports = MongoManager = { db.docs.find(query).toArray(callback) }, + getNonDeletedArchivedProjectDocs(project_id, callback) { + const query = { + project_id: ObjectId(project_id.toString()), + deleted: { $ne: true }, + inS3: true + } + db.docs.find(query).toArray(callback) + }, + upsertIntoDocCollection(project_id, doc_id, updates, callback) { const update = { $set: updates, diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 0bbf99424e..1ab77e784b 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -23,6 +23,8 @@ const Settings = { docstore: { archiveOnSoftDelete: process.env.ARCHIVE_ON_SOFT_DELETE === 'true', + keepSoftDeletedDocsArchived: + process.env.KEEP_SOFT_DELETED_DOCS_ARCHIVED === 'true', backend: process.env.BACKEND || 's3', healthCheck: { diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 234ded5a72..f8531f23a2 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -167,7 +167,7 @@ describe('Archiving', function () { }) describe('a deleted doc', function () { - before(function (done) { + beforeEach(function (done) { this.project_id = ObjectId() this.doc = { _id: ObjectId(), @@ -241,8 +241,8 @@ describe('Archiving', function () { ) }) - return describe('after unarchiving from a request for the project', function () { - before(function (done) { + describe('after unarchiving from a request for the project', function () { + beforeEach(function (done) { return DocstoreClient.getAllDocs( this.project_id, (error, res, fetched_docs) => { @@ -273,6 +273,51 @@ describe('Archiving', function () { }) }) }) + + describe('when keepSoftDeletedDocsArchived is enabled', function () { + let keepSoftDeletedDocsArchived + beforeEach(function overwriteSetting() { + keepSoftDeletedDocsArchived = + Settings.docstore.keepSoftDeletedDocsArchived + Settings.docstore.keepSoftDeletedDocsArchived = true + }) + afterEach(function restoreSetting() { + Settings.docstore.keepSoftDeletedDocsArchived = keepSoftDeletedDocsArchived + }) + + describe('after unarchiving from a request for the project', function () { + beforeEach(function (done) { + DocstoreClient.getAllDocs( + this.project_id, + (error, res, fetched_docs) => { + this.fetched_docs = fetched_docs + if (error) { + return done(error) + } + done() + } + ) + }) + + it('should not included the deleted', function (done) { + this.fetched_docs.length.should.equal(0) + done() + }) + + it('should not have restored the deleted doc to mongo', function (done) { + db.docs.findOne({ _id: this.doc._id }, (error, doc) => { + if (error) { + return done(error) + } + expect(doc.lines).to.not.exist + expect(doc.ranges).to.not.exist + expect(doc.inS3).to.equal(true) + expect(doc.deleted).to.equal(true) + done() + }) + }) + }) + }) }) describe('archiving a single doc', function () { From 21d0b05dfff81aa3e12083b29bf2aa172fcb08bc Mon Sep 17 00:00:00 2001 From: Christopher Hoskin <christopher.hoskin@gmail.com> Date: Tue, 9 Feb 2021 12:45:57 +0000 Subject: [PATCH 307/349] Update README as Credentials are no longer required for acceptance tests --- services/docstore/README.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/services/docstore/README.md b/services/docstore/README.md index dacfd2873b..09b27ac25a 100644 --- a/services/docstore/README.md +++ b/services/docstore/README.md @@ -3,10 +3,6 @@ overleaf/docstore A CRUD API for storing and updating text documents in projects -## Tests -``` -AWS_BUCKET=**** AWS_ACCESS_KEY_ID=**** AWS_SECRET_ACCESS_KEY=**** make test -``` License ------- From dd4f4057f43088328abb3aee31331d3d92f3aabe Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 15 Feb 2021 13:13:48 +0000 Subject: [PATCH 308/349] [misc] add a new endpoint for changing a docs meta data -- incl. deleted - Validate the request payload with joi -- includes acceptance tests. - Reject updates to docs that have been deleted. --- services/docstore/app.js | 20 ++ services/docstore/app/js/DocManager.js | 36 ++++ services/docstore/app/js/Errors.js | 3 + services/docstore/app/js/HttpController.js | 11 + services/docstore/app/js/MongoManager.js | 11 + services/docstore/package-lock.json | 97 ++++++++- services/docstore/package.json | 1 + .../test/acceptance/js/DeletingDocsTests.js | 156 ++++++++++++-- .../acceptance/js/helpers/DocstoreClient.js | 42 +++- .../docstore/test/unit/js/DocManagerTests.js | 193 ++++++++++++++++++ .../test/unit/js/HttpControllerTests.js | 23 +++ .../test/unit/js/MongoManagerTests.js | 27 +++ 12 files changed, 593 insertions(+), 27 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index 9be08d046c..bd04f6647f 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -10,6 +10,11 @@ const Settings = require('settings-sharelatex') const logger = require('logger-sharelatex') const express = require('express') const bodyParser = require('body-parser') +const { + celebrate: validate, + Joi, + errors: handleValidationErrors +} = require('celebrate') const mongodb = require('./app/js/mongodb') const Errors = require('./app/js/Errors') const HttpController = require('./app/js/HttpController') @@ -54,6 +59,18 @@ app.post( bodyParser.json({ limit: (Settings.max_doc_length + 64 * 1024) * 2 }), HttpController.updateDoc ) +app.patch( + '/project/:project_id/doc/:doc_id', + bodyParser.json(), + validate({ + body: { + deleted: Joi.boolean(), + name: Joi.string().when('deleted', { is: true, then: Joi.required() }), + deletedAt: Joi.date().when('deleted', { is: true, then: Joi.required() }) + } + }), + HttpController.patchDoc +) app.delete('/project/:project_id/doc/:doc_id', HttpController.deleteDoc) app.post('/project/:project_id/archive', HttpController.archiveAllDocs) @@ -65,10 +82,13 @@ app.get('/health_check', HttpController.healthCheck) app.get('/status', (req, res) => res.send('docstore is alive')) +app.use(handleValidationErrors()) app.use(function (error, req, res, next) { logger.error({ err: error, req }, 'request errored') if (error instanceof Errors.NotFoundError) { return res.sendStatus(404) + } else if (error instanceof Errors.InvalidOperation) { + return res.status(400).send(error.message) } else { return res.status(500).send('Oops, something went wrong') } diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 409668c313..648bc8d944 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -320,5 +320,41 @@ module.exports = DocManager = { return MongoManager.markDocAsDeleted(project_id, doc_id, callback) }) + }, + + patchDoc(project_id, doc_id, meta, callback) { + const projection = { _id: 1, deleted: true } + MongoManager.findDoc(project_id, doc_id, projection, (error, doc) => { + if (error != null) { + return callback(error) + } + if (!doc) { + return callback( + new Errors.NotFoundError( + `No such project/doc to delete: ${project_id}/${doc_id}` + ) + ) + } + + // deletion is a one-way operation + if (doc.deleted) + return callback( + new Errors.InvalidOperation('Cannot PATCH after doc deletion') + ) + + if (meta.deleted && Settings.docstore.archiveOnSoftDelete) { + // The user will not read this doc anytime soon. Flush it out of mongo. + DocArchive.archiveDocById(project_id, doc_id, (err) => { + if (err) { + logger.warn( + { project_id, doc_id, err }, + 'archiving a single doc in the background failed' + ) + } + }) + } + + MongoManager.patchDoc(project_id, doc_id, meta, callback) + }) } } diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index 6a74485494..1b9332b4a0 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -4,7 +4,10 @@ const { Errors } = require('@overleaf/object-persistor') class Md5MismatchError extends OError {} +class InvalidOperation extends OError {} + module.exports = { Md5MismatchError, + InvalidOperation, ...Errors } diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 947b83036c..8cb852b4dd 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -188,6 +188,17 @@ module.exports = HttpController = { }) }, + patchDoc(req, res, next) { + const { project_id, doc_id } = req.params + logger.log({ project_id, doc_id }, 'patching doc') + DocManager.patchDoc(project_id, doc_id, req.body, function (error) { + if (error) { + return next(error) + } + res.sendStatus(204) + }) + }, + _buildDocView(doc) { const doc_view = { _id: doc._id != null ? doc._id.toString() : undefined } for (const attribute of ['lines', 'rev', 'version', 'ranges', 'deleted']) { diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index c6bd24c639..ea8f7f710b 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -94,6 +94,17 @@ module.exports = MongoManager = { ) }, + patchDoc(project_id, doc_id, meta, callback) { + db.docs.updateOne( + { + _id: ObjectId(doc_id), + project_id: ObjectId(project_id) + }, + { $set: meta }, + callback + ) + }, + markDocAsArchived(doc_id, rev, callback) { const update = { $set: {}, diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 30c414d75f..f492376dfd 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1001,6 +1001,49 @@ "protobufjs": "^6.8.6" } }, + "@hapi/address": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", + "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@hapi/formula": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", + "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==" + }, + "@hapi/hoek": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", + "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==" + }, + "@hapi/joi": { + "version": "17.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz", + "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==", + "requires": { + "@hapi/address": "^4.0.1", + "@hapi/formula": "^2.0.0", + "@hapi/hoek": "^9.0.0", + "@hapi/pinpoint": "^2.0.0", + "@hapi/topo": "^5.0.0" + } + }, + "@hapi/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==" + }, + "@hapi/topo": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", + "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, "@opencensus/core": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.20.tgz", @@ -1150,6 +1193,24 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "@sideway/address": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.1.tgz", + "integrity": "sha512-+I5aaQr3m0OAmMr7RQ3fR9zx55sejEYR2BFJaxL+zT3VM2611X0SHvPWIbAUBZVTn/YzYKbV8gJ2oT/QELknfQ==", + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==" + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + }, "@sinonjs/commons": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", @@ -1658,7 +1719,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, "bl": { "version": "2.2.1", @@ -1791,6 +1852,16 @@ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", "dev": true }, + "celebrate": { + "version": "13.0.4", + "resolved": "https://registry.npmjs.org/celebrate/-/celebrate-13.0.4.tgz", + "integrity": "sha512-gUtAjEtFyY9PvuuQJq1uyuF46gLetVZzyUKXBDBqqvgzCjTSfwXP8L+WcGt1NrLQvUxXdlzhFolW2Bt9DDEV+g==", + "requires": { + "escape-html": "1.0.3", + "joi": "17.x.x", + "lodash": "4.17.x" + } + }, "chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", @@ -3061,7 +3132,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" + "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, "flat": { "version": "4.1.0", @@ -3957,6 +4028,18 @@ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" }, + "joi": { + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-17.4.0.tgz", + "integrity": "sha512-F4WiW2xaV6wc1jxete70Rw4V/VuMd6IN+a5ilZsxG4uYtUXWu2kq9W5P2dz30e7Gmw8RCbY/u/uk+dMPma9tAg==", + "requires": { + "@hapi/hoek": "^9.0.0", + "@hapi/topo": "^5.0.0", + "@sideway/address": "^4.1.0", + "@sideway/formula": "^3.0.0", + "@sideway/pinpoint": "^2.0.0" + } + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4589,7 +4672,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { "version": "2.24.0", @@ -6208,7 +6291,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, "restore-cursor": { "version": "3.1.0", @@ -6513,7 +6596,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6741,7 +6824,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { "version": "6.0.0", @@ -6824,7 +6907,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", "requires": { "bintrees": "1.0.1" } diff --git a/services/docstore/package.json b/services/docstore/package.json index 1d794d1398..06e5fa6fc3 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -23,6 +23,7 @@ "@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/4ca62157a2beb747e9a56da3ce1569124b90378a.tar.gz", "async": "^2.6.3", "body-parser": "^1.19.0", + "celebrate": "^13.0.4", "express": "^4.17.1", "logger-sharelatex": "^2.2.0", "mongodb": "^3.6.0", diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index d32cd52b6b..3872a62762 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -21,7 +21,7 @@ const Settings = require('settings-sharelatex') const DocstoreClient = require('./helpers/DocstoreClient') -describe('Deleting a doc', function () { +function deleteTestSuite(deleteDoc) { beforeEach(function (done) { this.project_id = ObjectId() this.doc_id = ObjectId() @@ -60,14 +60,10 @@ describe('Deleting a doc', function () { describe('when the doc exists', function () { beforeEach(function (done) { - return DocstoreClient.deleteDoc( - this.project_id, - this.doc_id, - (error, res, doc) => { - this.res = res - return done() - } - ) + deleteDoc(this.project_id, this.doc_id, (error, res, doc) => { + this.res = res + return done() + }) }) afterEach(function (done) { @@ -108,16 +104,16 @@ describe('Deleting a doc', function () { describe('when archiveOnSoftDelete is enabled', function () { let archiveOnSoftDelete - beforeEach(function overwriteSetting() { + beforeEach('overwrite settings', function () { archiveOnSoftDelete = Settings.docstore.archiveOnSoftDelete Settings.docstore.archiveOnSoftDelete = true }) - afterEach(function restoreSetting() { + afterEach('restore settings', function () { Settings.docstore.archiveOnSoftDelete = archiveOnSoftDelete }) - beforeEach(function deleteDoc(done) { - DocstoreClient.deleteDoc(this.project_id, this.doc_id, (error, res) => { + beforeEach('delete Doc', function (done) { + deleteDoc(this.project_id, this.doc_id, (error, res) => { this.res = res done() }) @@ -177,7 +173,7 @@ describe('Deleting a doc', function () { }) it('should return a 404 when trying to delete', function (done) { - DocstoreClient.deleteDoc(otherProjectId, this.doc_id, (error, res) => { + deleteDoc(otherProjectId, this.doc_id, (error, res) => { if (error) return done(error) expect(res.statusCode).to.equal(404) done() @@ -201,15 +197,137 @@ describe('Deleting a doc', function () { return it('should return a 404', function (done) { const missing_doc_id = ObjectId() - return DocstoreClient.deleteDoc( + deleteDoc(this.project_id, missing_doc_id, (error, res, doc) => { + res.statusCode.should.equal(404) + return done() + }) + }) + }) +} + +describe('Delete via DELETE', function () { + deleteTestSuite(DocstoreClient.deleteDocLegacy) +}) + +describe('Delete via PATCH', function () { + deleteTestSuite(DocstoreClient.deleteDoc) + + describe('deleting a doc twice', function () { + beforeEach('perform 1st DELETE request', function (done) { + DocstoreClient.deleteDoc(this.project_id, this.doc_id, done) + }) + + beforeEach('get doc before 2nd DELETE request', function (done) { + db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { + if (error) return done(error) + this.docBefore = docs[0] + if (!this.docBefore) return done(new Error('doc not found')) + done() + }) + }) + + beforeEach('perform 2nd DELETE request', function (done) { + DocstoreClient.deleteDoc(this.project_id, this.doc_id, (error, res) => { + this.res1 = res + done(error) + }) + }) + + it('should reject the 2nd request', function () { + expect(this.res1.statusCode).to.equal(400) + }) + + it('should not alter the previous doc state', function (done) { + db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { + if (error) return done(error) + const docAfter = docs[0] + if (!docAfter) return done(new Error('doc not found')) + + expect(docAfter).to.deep.equal(this.docBefore) + done() + }) + }) + }) + + describe('when providing a custom doc name in the delete request', function () { + beforeEach(function (done) { + DocstoreClient.deleteDocWithName( this.project_id, - missing_doc_id, - (error, res, doc) => { - res.statusCode.should.equal(404) - return done() + this.doc_id, + 'wombat.tex', + done + ) + }) + + it('should insert the doc name into the docs collection', function (done) { + db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { + if (error) return done(error) + expect(docs[0].name).to.equal('wombat.tex') + done() + }) + }) + }) + + describe('when providing a custom deletedAt date in the delete request', function () { + beforeEach('record date and delay', function (done) { + this.deletedAt = new Date() + setTimeout(done, 5) + }) + + beforeEach('perform deletion with past date', function (done) { + DocstoreClient.deleteDocWithDate( + this.project_id, + this.doc_id, + this.deletedAt, + done + ) + }) + + it('should insert the date into the docs collection', function (done) { + db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { + if (error) return done(error) + expect(docs[0].deletedAt.toISOString()).to.equal( + this.deletedAt.toISOString() + ) + done() + }) + }) + }) + + describe('when providing no doc name in the delete request', function () { + beforeEach(function (done) { + DocstoreClient.deleteDocWithName( + this.project_id, + this.doc_id, + '', + (error, res) => { + this.res = res + done(error) } ) }) + + it('should reject the request', function () { + expect(this.res.statusCode).to.equal(400) + }) + }) + + describe('when providing no date in the delete request', function () { + beforeEach(function (done) { + DocstoreClient.deleteDocWithDate( + this.project_id, + this.doc_id, + '', + (error, res) => { + this.res = res + done(error) + } + ) + }) + + it('should reject the request', function () { + expect(this.res.statusCode).to.equal(400) + }) }) }) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index ee4f26520e..7248fff744 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -115,7 +115,7 @@ module.exports = DocstoreClient = { ) }, - deleteDoc(project_id, doc_id, callback) { + deleteDocLegacy(project_id, doc_id, callback) { if (callback == null) { callback = function (error, res, body) {} } @@ -127,6 +127,46 @@ module.exports = DocstoreClient = { ) }, + deleteDoc(project_id, doc_id, callback) { + DocstoreClient.deleteDocWithDateAndName( + project_id, + doc_id, + new Date(), + 'main.tex', + callback + ) + }, + + deleteDocWithDate(project_id, doc_id, date, callback) { + DocstoreClient.deleteDocWithDateAndName( + project_id, + doc_id, + date, + 'main.tex', + callback + ) + }, + + deleteDocWithName(project_id, doc_id, name, callback) { + DocstoreClient.deleteDocWithDateAndName( + project_id, + doc_id, + new Date(), + name, + callback + ) + }, + + deleteDocWithDateAndName(project_id, doc_id, deletedAt, name, callback) { + request.patch( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + json: { name, deleted: true, deletedAt } + }, + callback + ) + }, + archiveAllDoc(project_id, callback) { if (callback == null) { callback = function (error, res, body) {} diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 597129b1bd..d581ce743b 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -545,6 +545,199 @@ describe('DocManager', function () { }) }) + describe('patchDoc', function () { + describe('when the doc exists', function () { + beforeEach(function () { + this.lines = ['mock', 'doc', 'lines'] + this.rev = 77 + this.MongoManager.findDoc = sinon + .stub() + .yields(null, { _id: ObjectId(this.doc_id) }) + this.MongoManager.patchDoc = sinon.stub().yields(null) + this.DocArchiveManager.archiveDocById = sinon.stub().yields(null) + this.meta = {} + }) + + describe('standard path', function () { + beforeEach(function (done) { + this.callback = sinon.stub().callsFake(done) + this.DocManager.patchDoc( + this.project_id, + this.doc_id, + this.meta, + this.callback + ) + }) + + it('should get the doc', function () { + expect(this.MongoManager.findDoc).to.have.been.calledWith( + this.project_id, + this.doc_id + ) + }) + + it('should persist the meta', function () { + expect(this.MongoManager.patchDoc).to.have.been.calledWith( + this.project_id, + this.doc_id, + this.meta + ) + }) + + it('should return the callback', function () { + expect(this.callback).to.have.been.calledWith(null) + }) + }) + + describe('background flush disabled and deleting a doc', function () { + beforeEach(function (done) { + this.settings.docstore.archiveOnSoftDelete = false + this.meta.deleted = true + + this.callback = sinon.stub().callsFake(done) + this.DocManager.patchDoc( + this.project_id, + this.doc_id, + this.meta, + this.callback + ) + }) + + it('should not flush the doc out of mongo', function () { + expect(this.DocArchiveManager.archiveDocById).to.not.have.been.called + }) + }) + + describe('background flush enabled and not deleting a doc', function () { + beforeEach(function (done) { + this.settings.docstore.archiveOnSoftDelete = false + this.meta.deleted = false + this.callback = sinon.stub().callsFake(done) + this.DocManager.patchDoc( + this.project_id, + this.doc_id, + this.meta, + this.callback + ) + }) + + it('should not flush the doc out of mongo', function () { + expect(this.DocArchiveManager.archiveDocById).to.not.have.been.called + }) + }) + + describe('background flush enabled and deleting a doc', function () { + beforeEach(function () { + this.settings.docstore.archiveOnSoftDelete = true + this.meta.deleted = true + this.logger.warn = sinon.stub() + }) + + describe('when the background flush succeeds', function () { + beforeEach(function (done) { + this.DocArchiveManager.archiveDocById = sinon.stub().yields(null) + this.callback = sinon.stub().callsFake(done) + this.DocManager.patchDoc( + this.project_id, + this.doc_id, + this.meta, + this.callback + ) + }) + + it('should not log a warning', function () { + expect(this.logger.warn).to.not.have.been.called + }) + + it('should flush the doc out of mongo', function () { + expect( + this.DocArchiveManager.archiveDocById + ).to.have.been.calledWith(this.project_id, this.doc_id) + }) + }) + + describe('when the background flush fails', function () { + beforeEach(function (done) { + this.err = new Error('foo') + this.DocArchiveManager.archiveDocById = sinon + .stub() + .yields(this.err) + this.callback = sinon.stub().callsFake(done) + this.DocManager.patchDoc( + this.project_id, + this.doc_id, + this.meta, + this.callback + ) + }) + + it('should log a warning', function () { + expect(this.logger.warn).to.have.been.calledWith( + sinon.match({ + project_id: this.project_id, + doc_id: this.doc_id, + err: this.err + }), + 'archiving a single doc in the background failed' + ) + }) + + it('should not fail the delete process', function () { + expect(this.callback).to.have.been.calledWith(null) + }) + }) + }) + }) + + describe('when the doc is already deleted', function () { + beforeEach(function (done) { + this.MongoManager.findDoc = sinon + .stub() + .yields(null, { _id: ObjectId(this.doc_id), deleted: true }) + this.MongoManager.patchDoc = sinon.stub() + + this.callback = sinon.stub().callsFake(() => done()) + this.DocManager.patchDoc( + this.project_id, + this.doc_id, + 'tomato.tex', + this.callback + ) + }) + + it('should reject the operation', function () { + expect(this.callback).to.have.been.calledWith( + sinon.match.has('message', 'Cannot PATCH after doc deletion') + ) + }) + + it('should not persist the change to mongo', function () { + expect(this.MongoManager.patchDoc).to.not.have.been.called + }) + }) + + describe('when the doc does not exist', function () { + beforeEach(function () { + this.MongoManager.findDoc = sinon.stub().yields(null) + this.DocManager.patchDoc( + this.project_id, + this.doc_id, + {}, + this.callback + ) + }) + + it('should return a NotFoundError', function () { + expect(this.callback).to.have.been.calledWith( + sinon.match.has( + 'message', + `No such project/doc to delete: ${this.project_id}/${this.doc_id}` + ) + ) + }) + }) + }) + return describe('updateDoc', function () { beforeEach(function () { this.oldDocLines = ['old', 'doc', 'lines'] diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 6638dbdbf8..16d4c7f584 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -456,6 +456,29 @@ describe('HttpController', function () { }) }) + describe('patchDoc', function () { + beforeEach(function () { + this.req.params = { + project_id: this.project_id, + doc_id: this.doc_id + } + this.req.body = { name: 'foo.tex' } + this.DocManager.patchDoc = sinon.stub().yields(null) + this.HttpController.patchDoc(this.req, this.res, this.next) + }) + + it('should delete the document', function () { + expect(this.DocManager.patchDoc).to.have.been.calledWith( + this.project_id, + this.doc_id + ) + }) + + it('should return a 204 (No Content)', function () { + expect(this.res.sendStatus).to.have.been.calledWith(204) + }) + }) + describe('archiveAllDocs', function () { beforeEach(function () { this.req.params = { project_id: this.project_id } diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 12fd3fba6c..eca77a55d9 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -72,6 +72,33 @@ describe('MongoManager', function () { }) }) + describe('patchDoc', function () { + beforeEach(function (done) { + this.db.docs.updateOne = sinon.stub().yields(null) + this.meta = { name: 'foo.tex' } + this.callback.callsFake(done) + this.MongoManager.patchDoc( + this.project_id, + this.doc_id, + this.meta, + this.callback + ) + }) + + it('should pass the parameter along', function () { + this.db.docs.updateOne.should.have.been.calledWith( + { + _id: ObjectId(this.doc_id), + project_id: ObjectId(this.project_id) + }, + { + $set: this.meta + }, + this.callback + ) + }) + }) + describe('getProjectsDocs', function () { beforeEach(function () { this.filter = { lines: true } From f6ab3a33af4649073d777298fcfd3324eca86f8e Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 16 Feb 2021 15:10:10 +0000 Subject: [PATCH 309/349] [misc] bump the version of the metrics module to 3.5.1 --- services/docstore/package-lock.json | 202 +++++++++++++++------------- services/docstore/package.json | 2 +- 2 files changed, 113 insertions(+), 91 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 30c414d75f..272bf9ca6d 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -239,9 +239,9 @@ "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" }, "acorn": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.4.tgz", - "integrity": "sha512-XNP0PqF1XD19ZlLKvB7cMmnZswW4C/03pRHgirB30uSJTaS3A3V1/P4sS3HPvFmjoriPCJQs+JDSbm4bL1TxGQ==" + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.5.tgz", + "integrity": "sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg==" }, "bignumber.js": { "version": "9.0.1", @@ -260,9 +260,9 @@ } }, "gaxios": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", - "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", @@ -281,9 +281,9 @@ } }, "google-auth-library": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz", - "integrity": "sha512-m9mwvY3GWbr7ZYEbl61isWmk+fvTmOt0YNUfPOUY2VH8K5pZlAIWJjxEi0PqR3OjMretyiQLI6GURMrPSwHQ2g==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", "requires": { "arrify": "^2.0.0", "base64-js": "^1.3.0", @@ -305,14 +305,13 @@ } }, "gtoken": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz", - "integrity": "sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", "requires": { "gaxios": "^4.0.0", "google-p12-pem": "^3.0.3", - "jws": "^4.0.0", - "mime": "^2.2.0" + "jws": "^4.0.0" } }, "json-bigint": { @@ -355,9 +354,12 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } }, "teeny-request": { "version": "7.0.1", @@ -372,9 +374,9 @@ } }, "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "yallist": { "version": "4.0.0", @@ -513,9 +515,9 @@ } }, "gaxios": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", - "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", @@ -534,9 +536,9 @@ } }, "google-auth-library": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz", - "integrity": "sha512-m9mwvY3GWbr7ZYEbl61isWmk+fvTmOt0YNUfPOUY2VH8K5pZlAIWJjxEi0PqR3OjMretyiQLI6GURMrPSwHQ2g==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", "requires": { "arrify": "^2.0.0", "base64-js": "^1.3.0", @@ -558,14 +560,13 @@ } }, "gtoken": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz", - "integrity": "sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", "requires": { "gaxios": "^4.0.0", "google-p12-pem": "^3.0.3", - "jws": "^4.0.0", - "mime": "^2.2.0" + "jws": "^4.0.0" } }, "json-bigint": { @@ -600,9 +601,12 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } }, "teeny-request": { "version": "7.0.1", @@ -617,9 +621,9 @@ } }, "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "yallist": { "version": "4.0.0", @@ -773,9 +777,9 @@ } }, "@google-cloud/trace-agent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-5.1.1.tgz", - "integrity": "sha512-YTcK0RLN90pLCprg0XC8uV4oAVd79vsXhkcxmEVwiOOYjUDvSrAhb7y/0SY606zgfhJHmUTNb/fZSWEtZP/slQ==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@google-cloud/trace-agent/-/trace-agent-5.1.3.tgz", + "integrity": "sha512-f+5DX7n6QpDlHA+4kr81z69SLAdrlvd9T8skqCMgnYvtXx14AwzXZyzEDf3jppOYzYoqPPJv8XYiyYHHmYD0BA==", "requires": { "@google-cloud/common": "^3.0.0", "@opencensus/propagation-stackdriver": "0.0.22", @@ -784,7 +788,7 @@ "continuation-local-storage": "^3.2.1", "extend": "^3.0.2", "gcp-metadata": "^4.0.0", - "google-auth-library": "^6.0.0", + "google-auth-library": "^7.0.0", "hex2dec": "^1.0.1", "is": "^3.2.0", "methods": "^1.1.1", @@ -812,9 +816,9 @@ }, "dependencies": { "google-auth-library": { - "version": "6.1.3", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.3.tgz", - "integrity": "sha512-m9mwvY3GWbr7ZYEbl61isWmk+fvTmOt0YNUfPOUY2VH8K5pZlAIWJjxEi0PqR3OjMretyiQLI6GURMrPSwHQ2g==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", "requires": { "arrify": "^2.0.0", "base64-js": "^1.3.0", @@ -878,9 +882,9 @@ } }, "gaxios": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.0.1.tgz", - "integrity": "sha512-jOin8xRZ/UytQeBpSXFqIzqU7Fi5TqgPNLlUsSB8kjJ76+FiGBfImF8KJu++c6J4jOldfJUtt0YmkRj2ZpSHTQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", @@ -898,6 +902,22 @@ "json-bigint": "^1.0.0" } }, + "google-auth-library": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.0.2.tgz", + "integrity": "sha512-vjyNZR3pDLC0u7GHLfj+Hw9tGprrJwoMwkYGqURCXYITjCrP9HprOyxVV+KekdLgATtWGuDkQG2MTh0qpUPUgg==", + "requires": { + "arrify": "^2.0.0", + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "fast-text-encoding": "^1.0.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", + "gtoken": "^5.0.4", + "jws": "^4.0.0", + "lru-cache": "^6.0.0" + } + }, "google-p12-pem": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.0.3.tgz", @@ -907,14 +927,13 @@ } }, "gtoken": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz", - "integrity": "sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", "requires": { "gaxios": "^4.0.0", "google-p12-pem": "^3.0.3", - "jws": "^4.0.0", - "mime": "^2.2.0" + "jws": "^4.0.0" } }, "json-bigint": { @@ -949,9 +968,12 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } }, "teeny-request": { "version": "7.0.1", @@ -966,9 +988,9 @@ } }, "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "yallist": { "version": "4.0.0", @@ -1031,9 +1053,9 @@ } }, "@overleaf/metrics": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@overleaf/metrics/-/metrics-3.4.1.tgz", - "integrity": "sha512-OgjlzuC+2gPdIEDHhmd9LDMu01tk1ln0cJhw1727BZ+Wgf2Z1hjuHRt4JeCkf+PFTHwJutVYT8v6IGPpNEPtbg==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@overleaf/metrics/-/metrics-3.5.1.tgz", + "integrity": "sha512-RLHxkMF7Y3725L3QwXo9cIn2gGobsMYUGuxKxg7PVMrPTMsomHEMeG7StOxCO7ML1Z/BwB/9nsVYNrsRdAJtKg==", "requires": { "@google-cloud/debug-agent": "^5.1.2", "@google-cloud/profiler": "^4.0.3", @@ -1658,7 +1680,7 @@ "bintrees": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", - "integrity": "sha512-tbaUB1QpTIj4cKY8c1rvNAvEQXA+ekzHmbe4jzNfW3QWsF9GnnP/BRWyl6/qqS53heoYJ93naaFcm/jooONH8g==" + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" }, "bl": { "version": "2.2.1", @@ -1742,9 +1764,9 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "builtin-modules": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz", - "integrity": "sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", + "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==" }, "bunyan": { "version": "1.8.14", @@ -2244,9 +2266,9 @@ } }, "delay": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/delay/-/delay-4.4.0.tgz", - "integrity": "sha512-txgOrJu3OdtOfTiEOT2e76dJVfG/1dz2NZ4F0Pyt4UGZJryssMRp5vdM5wQoLwSOBNdrJv3F9PAhp/heqd7vrA==" + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/delay/-/delay-4.4.1.tgz", + "integrity": "sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ==" }, "delayed-stream": { "version": "1.0.0", @@ -3061,7 +3083,7 @@ "findit2": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/findit2/-/findit2-2.2.3.tgz", - "integrity": "sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog==" + "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, "flat": { "version": "4.1.0", @@ -3845,9 +3867,9 @@ "dev": true }, "is-core-module": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", - "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", "requires": { "has": "^1.0.3" } @@ -4589,7 +4611,7 @@ "module-details-from-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==" + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { "version": "2.24.0", @@ -4650,9 +4672,9 @@ "optional": true }, "needle": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", - "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -4668,9 +4690,9 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "sax": { "version": "1.2.4", @@ -6136,9 +6158,9 @@ "dev": true }, "require-in-the-middle": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.0.3.tgz", - "integrity": "sha512-p/ICV8uMlqC4tjOYabLMxAWCIKa0YUQgZZ6KDM0xgXJNgdGQ1WmL2A07TwmrZw+wi6ITUFKzH5v3n+ENEyXVkA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", + "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", "requires": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", @@ -6159,11 +6181,11 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "requires": { - "is-core-module": "^2.1.0", + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } } @@ -6208,7 +6230,7 @@ "resolve-from": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha512-qpFcKaXsq8+oRoLilkwyc7zHGF5i9Q2/25NIgLQQ/+VVv9rU4qvr6nXVAw1DsnXJyQkZsR4Ytfbtg5ehfcUssQ==" + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, "restore-cursor": { "version": "3.1.0", @@ -6513,7 +6535,7 @@ "sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", - "integrity": "sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==", + "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=", "optional": true, "requires": { "memory-pager": "^1.0.2" @@ -6741,7 +6763,7 @@ "stubs": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==" + "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { "version": "6.0.0", @@ -6824,7 +6846,7 @@ "tdigest": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", - "integrity": "sha512-CXcDY/NIgIbKZPx5H4JJNpq6JwJhU5Z4+yWj4ZghDc7/9nVajiRlPPyMXRePPPlBfcayUqtoCXjo7/Hm82ecUA==", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", "requires": { "bintrees": "1.0.1" } diff --git a/services/docstore/package.json b/services/docstore/package.json index 1d794d1398..9ffec5b7e8 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -19,7 +19,7 @@ "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write" }, "dependencies": { - "@overleaf/metrics": "^3.4.1", + "@overleaf/metrics": "^3.5.1", "@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/4ca62157a2beb747e9a56da3ce1569124b90378a.tar.gz", "async": "^2.6.3", "body-parser": "^1.19.0", From 26bc074098f1f4e18961e485966ee030bb0132ed Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Wed, 17 Feb 2021 11:31:01 +0000 Subject: [PATCH 310/349] [DocstoreManager] patchDoc: allow updates after deletion --- services/docstore/app.js | 2 - services/docstore/app/js/DocManager.js | 6 --- services/docstore/app/js/Errors.js | 3 -- .../test/acceptance/js/DeletingDocsTests.js | 37 ------------------- .../docstore/test/unit/js/DocManagerTests.js | 27 -------------- 5 files changed, 75 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index bd04f6647f..790a916f33 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -87,8 +87,6 @@ app.use(function (error, req, res, next) { logger.error({ err: error, req }, 'request errored') if (error instanceof Errors.NotFoundError) { return res.sendStatus(404) - } else if (error instanceof Errors.InvalidOperation) { - return res.status(400).send(error.message) } else { return res.status(500).send('Oops, something went wrong') } diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 648bc8d944..2f19087388 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -336,12 +336,6 @@ module.exports = DocManager = { ) } - // deletion is a one-way operation - if (doc.deleted) - return callback( - new Errors.InvalidOperation('Cannot PATCH after doc deletion') - ) - if (meta.deleted && Settings.docstore.archiveOnSoftDelete) { // The user will not read this doc anytime soon. Flush it out of mongo. DocArchive.archiveDocById(project_id, doc_id, (err) => { diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index 1b9332b4a0..6a74485494 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -4,10 +4,7 @@ const { Errors } = require('@overleaf/object-persistor') class Md5MismatchError extends OError {} -class InvalidOperation extends OError {} - module.exports = { Md5MismatchError, - InvalidOperation, ...Errors } diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 3872a62762..27d3c212c7 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -212,43 +212,6 @@ describe('Delete via DELETE', function () { describe('Delete via PATCH', function () { deleteTestSuite(DocstoreClient.deleteDoc) - describe('deleting a doc twice', function () { - beforeEach('perform 1st DELETE request', function (done) { - DocstoreClient.deleteDoc(this.project_id, this.doc_id, done) - }) - - beforeEach('get doc before 2nd DELETE request', function (done) { - db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { - if (error) return done(error) - this.docBefore = docs[0] - if (!this.docBefore) return done(new Error('doc not found')) - done() - }) - }) - - beforeEach('perform 2nd DELETE request', function (done) { - DocstoreClient.deleteDoc(this.project_id, this.doc_id, (error, res) => { - this.res1 = res - done(error) - }) - }) - - it('should reject the 2nd request', function () { - expect(this.res1.statusCode).to.equal(400) - }) - - it('should not alter the previous doc state', function (done) { - db.docs.find({ _id: this.doc_id }).toArray((error, docs) => { - if (error) return done(error) - const docAfter = docs[0] - if (!docAfter) return done(new Error('doc not found')) - - expect(docAfter).to.deep.equal(this.docBefore) - done() - }) - }) - }) - describe('when providing a custom doc name in the delete request', function () { beforeEach(function (done) { DocstoreClient.deleteDocWithName( diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index d581ce743b..50caa69501 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -689,33 +689,6 @@ describe('DocManager', function () { }) }) - describe('when the doc is already deleted', function () { - beforeEach(function (done) { - this.MongoManager.findDoc = sinon - .stub() - .yields(null, { _id: ObjectId(this.doc_id), deleted: true }) - this.MongoManager.patchDoc = sinon.stub() - - this.callback = sinon.stub().callsFake(() => done()) - this.DocManager.patchDoc( - this.project_id, - this.doc_id, - 'tomato.tex', - this.callback - ) - }) - - it('should reject the operation', function () { - expect(this.callback).to.have.been.calledWith( - sinon.match.has('message', 'Cannot PATCH after doc deletion') - ) - }) - - it('should not persist the change to mongo', function () { - expect(this.MongoManager.patchDoc).to.not.have.been.called - }) - }) - describe('when the doc does not exist', function () { beforeEach(function () { this.MongoManager.findDoc = sinon.stub().yields(null) From 0c169cb2428f8e9b769fb5994eb8a75816425ff6 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Wed, 17 Feb 2021 11:31:27 +0000 Subject: [PATCH 311/349] [HttpController] double down on request validation --- services/docstore/app/js/HttpController.js | 12 ++++++++- .../test/unit/js/HttpControllerTests.js | 27 ++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 8cb852b4dd..59603ca06a 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -191,7 +191,17 @@ module.exports = HttpController = { patchDoc(req, res, next) { const { project_id, doc_id } = req.params logger.log({ project_id, doc_id }, 'patching doc') - DocManager.patchDoc(project_id, doc_id, req.body, function (error) { + + const allowedFields = ['deleted', 'deletedAt', 'name'] + const meta = {} + Object.entries(req.body).forEach(([field, value]) => { + if (allowedFields.includes(field)) { + meta[field] = value + } else { + logger.fatal({ field }, 'joi validation for pathDoc is broken') + } + }) + DocManager.patchDoc(project_id, doc_id, meta, function (error) { if (error) { return next(error) } diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 16d4c7f584..4fc3651ada 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -32,7 +32,8 @@ describe('HttpController', function () { './DocArchiveManager': (this.DocArchiveManager = {}), 'logger-sharelatex': (this.logger = { log: sinon.stub(), - error: sinon.stub() + error: sinon.stub(), + fatal: sinon.stub() }), 'settings-sharelatex': settings, './HealthChecker': {} @@ -477,6 +478,30 @@ describe('HttpController', function () { it('should return a 204 (No Content)', function () { expect(this.res.sendStatus).to.have.been.calledWith(204) }) + + describe('with an invalid payload', function () { + beforeEach(function () { + this.req.body = { cannot: 'happen' } + + this.DocManager.patchDoc = sinon.stub().yields(null) + this.HttpController.patchDoc(this.req, this.res, this.next) + }) + + it('should log a message', function () { + expect(this.logger.fatal).to.have.been.calledWith( + { field: 'cannot' }, + 'joi validation for pathDoc is broken' + ) + }) + + it('should not pass the invalid field along', function () { + expect(this.DocManager.patchDoc).to.have.been.calledWith( + this.project_id, + this.doc_id, + {} + ) + }) + }) }) describe('archiveAllDocs', function () { From 8915e1d026c79db979144276019da90e08a10e08 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Thu, 18 Feb 2021 10:10:14 +0000 Subject: [PATCH 312/349] [misc] add a new endpoint for getting deleted docs --- services/docstore/app.js | 1 + services/docstore/app/js/DocManager.js | 4 + services/docstore/app/js/HttpController.js | 18 +++ services/docstore/app/js/MongoManager.js | 19 +++ services/docstore/config/settings.defaults.js | 2 + .../test/acceptance/js/DeletingDocsTests.js | 132 ++++++++++++++++++ .../acceptance/js/helpers/DocstoreClient.js | 16 +++ .../test/unit/js/MongoManagerTests.js | 47 ++++++- 8 files changed, 238 insertions(+), 1 deletion(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index 790a916f33..08260dfbba 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -48,6 +48,7 @@ app.param('doc_id', function (req, res, next, docId) { Metrics.injectMetricsRoute(app) +app.get('/project/:project_id/doc-deleted', HttpController.getAllDeletedDocs) app.get('/project/:project_id/doc', HttpController.getAllDocs) app.get('/project/:project_id/ranges', HttpController.getAllRanges) app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc) diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 2f19087388..4a97c3688a 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -150,6 +150,10 @@ module.exports = DocManager = { ) }, + getAllDeletedDocs(project_id, filter, callback) { + MongoManager.getProjectsDeletedDocs(project_id, filter, callback) + }, + getAllNonDeletedDocs(project_id, filter, callback) { if (callback == null) { callback = function (error, docs) {} diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 59603ca06a..0d7fc62061 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -95,6 +95,24 @@ module.exports = HttpController = { ) }, + getAllDeletedDocs(req, res, next) { + const { project_id } = req.params + logger.log({ project_id }, 'getting all deleted docs') + DocManager.getAllDeletedDocs(project_id, { name: true }, function ( + error, + docs + ) { + if (error) { + return next(error) + } + res.json( + docs.map((doc) => { + return { _id: doc._id.toString(), name: doc.name } + }) + ) + }) + }, + getAllRanges(req, res, next) { if (next == null) { next = function (error) {} diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index ea8f7f710b..753abaf1ea 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -14,6 +14,7 @@ let MongoManager const { db, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') const metrics = require('@overleaf/metrics') +const Settings = require('settings-sharelatex') const { promisify } = require('util') module.exports = MongoManager = { @@ -33,6 +34,24 @@ module.exports = MongoManager = { ) }, + getProjectsDeletedDocs(project_id, filter, callback) { + db.docs + .find( + { + project_id: ObjectId(project_id.toString()), + deleted: true, + // TODO(das7pad): remove name filter after back filling data + name: { $exists: true } + }, + { + projection: filter, + sort: { deletedAt: -1 }, + limit: Settings.max_deleted_docs + } + ) + .toArray(callback) + }, + getProjectsDocs(project_id, options, filter, callback) { const query = { project_id: ObjectId(project_id.toString()) } if (!options.include_deleted) { diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 1ab77e784b..808470b950 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -38,6 +38,8 @@ const Settings = { } }, + max_deleted_docs: parseInt(process.env.MAX_DELETED_DOCS, 10) || 2000, + max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024 // 2mb } diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 27d3c212c7..232931102e 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -207,6 +207,23 @@ function deleteTestSuite(deleteDoc) { describe('Delete via DELETE', function () { deleteTestSuite(DocstoreClient.deleteDocLegacy) + + describe('when the doc gets no name on delete', function () { + beforeEach(function (done) { + DocstoreClient.deleteDocLegacy(this.project_id, this.doc_id, done) + }) + + it('should not show the doc in the deleted docs response', function (done) { + DocstoreClient.getAllDeletedDocs( + this.project_id, + (error, deletedDocs) => { + if (error) return done(error) + expect(deletedDocs).to.deep.equal([]) + done() + } + ) + }) + }) }) describe('Delete via PATCH', function () { @@ -292,6 +309,121 @@ describe('Delete via PATCH', function () { expect(this.res.statusCode).to.equal(400) }) }) + + describe('before deleting anything', function () { + it('should show nothing in deleted docs response', function (done) { + DocstoreClient.getAllDeletedDocs( + this.project_id, + (error, deletedDocs) => { + if (error) return done(error) + expect(deletedDocs).to.deep.equal([]) + done() + } + ) + }) + }) + + describe('when the doc gets a name on delete', function () { + beforeEach(function (done) { + DocstoreClient.deleteDoc(this.project_id, this.doc_id, done) + }) + + it('should show the doc in deleted docs response', function (done) { + DocstoreClient.getAllDeletedDocs( + this.project_id, + (error, deletedDocs) => { + if (error) return done(error) + expect(deletedDocs).to.deep.equal([ + { _id: this.doc_id.toString(), name: 'main.tex' } + ]) + done() + } + ) + }) + + describe('after deleting multiple docs', function () { + beforeEach('create doc2', function (done) { + this.doc_id2 = ObjectId() + DocstoreClient.createDoc( + this.project_id, + this.doc_id2, + this.lines, + this.version, + this.ranges, + done + ) + }) + beforeEach('delete doc2', function (done) { + DocstoreClient.deleteDocWithName( + this.project_id, + this.doc_id2, + 'two.tex', + done + ) + }) + beforeEach('create doc3', function (done) { + this.doc_id3 = ObjectId() + DocstoreClient.createDoc( + this.project_id, + this.doc_id3, + this.lines, + this.version, + this.ranges, + done + ) + }) + beforeEach('delete doc3', function (done) { + DocstoreClient.deleteDocWithName( + this.project_id, + this.doc_id3, + 'three.tex', + done + ) + }) + it('should show all the docs as deleted', function (done) { + DocstoreClient.getAllDeletedDocs( + this.project_id, + (error, deletedDocs) => { + if (error) return done(error) + + expect(deletedDocs).to.deep.equal([ + { _id: this.doc_id3.toString(), name: 'three.tex' }, + { _id: this.doc_id2.toString(), name: 'two.tex' }, + { _id: this.doc_id.toString(), name: 'main.tex' } + ]) + done() + } + ) + }) + + describe('with one more than max_deleted_docs permits', function () { + let maxDeletedDocsBefore + beforeEach(function () { + maxDeletedDocsBefore = Settings.max_deleted_docs + Settings.max_deleted_docs = 2 + }) + afterEach(function () { + Settings.max_deleted_docs = maxDeletedDocsBefore + }) + + it('should omit the first deleted doc', function (done) { + DocstoreClient.getAllDeletedDocs( + this.project_id, + (error, deletedDocs) => { + if (error) return done(error) + + expect(deletedDocs).to.deep.equal([ + { _id: this.doc_id3.toString(), name: 'three.tex' }, + { _id: this.doc_id2.toString(), name: 'two.tex' } + // dropped main.tex + ]) + done() + } + ) + }) + }) + }) + }) }) describe("Destroying a project's documents", function () { diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 7248fff744..fda0a66e1c 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -85,6 +85,22 @@ module.exports = DocstoreClient = { ) }, + getAllDeletedDocs(project_id, callback) { + request.get( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc-deleted`, + json: true + }, + (error, res, body) => { + if (error) return callback(error) + if (res.statusCode !== 200) { + return callback(new Error('unexpected statusCode')) + } + callback(null, body) + } + ) + }, + getAllRanges(project_id, callback) { if (callback == null) { callback = function (error, res, body) {} diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index eca77a55d9..0b073937f0 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -28,7 +28,8 @@ describe('MongoManager', function () { ObjectId }, '@overleaf/metrics': { timeAsyncMethod: sinon.stub() }, - 'logger-sharelatex': { log() {} } + 'logger-sharelatex': { log() {} }, + 'settings-sharelatex': { max_deleted_docs: 42 } }, globals: { console @@ -175,6 +176,50 @@ describe('MongoManager', function () { }) }) + describe('getProjectsDeletedDocs', function () { + beforeEach(function (done) { + this.filter = { name: true } + this.doc1 = { _id: '1', name: 'mock-doc1.tex' } + this.doc2 = { _id: '2', name: 'mock-doc2.tex' } + this.doc3 = { _id: '3', name: 'mock-doc3.tex' } + this.db.docs.find = sinon.stub().returns({ + toArray: sinon.stub().yields(null, [this.doc1, this.doc2, this.doc3]) + }) + this.callback.callsFake(done) + this.MongoManager.getProjectsDeletedDocs( + this.project_id, + this.filter, + this.callback + ) + }) + + it('should find the deleted docs via the project_id', function () { + this.db.docs.find + .calledWith({ + project_id: ObjectId(this.project_id), + deleted: true, + name: { $exists: true } + }) + .should.equal(true) + }) + + it('should filter, sort by deletedAt and limit', function () { + this.db.docs.find + .calledWith(sinon.match.any, { + projection: this.filter, + sort: { deletedAt: -1 }, + limit: 42 + }) + .should.equal(true) + }) + + it('should call the callback with the docs', function () { + this.callback + .calledWith(null, [this.doc1, this.doc2, this.doc3]) + .should.equal(true) + }) + }) + describe('upsertIntoDocCollection', function () { beforeEach(function () { this.db.docs.updateOne = sinon.stub().callsArgWith(3, this.stubbedErr) From 5efae3bee6cb177b5d0d299d3c743d4304011c9d Mon Sep 17 00:00:00 2001 From: Eric Mc Sween <eric.mcsween@overleaf.com> Date: Fri, 12 Mar 2021 17:16:01 -0500 Subject: [PATCH 313/349] Add a global test setup file Configure chai and SandboxedModule globally instead of in every test file. Also add globals that are required for SandboxedModule to work in Node 12. --- services/docstore/.mocharc.json | 3 ++ .../test/acceptance/js/ArchiveDocsTests.js | 46 +++++++++---------- .../test/acceptance/js/DeletingDocsTests.js | 4 +- .../test/acceptance/js/GettingAllDocsTests.js | 2 - .../test/acceptance/js/GettingDocsTests.js | 2 - .../test/acceptance/js/UpdatingDocsTests.js | 2 - services/docstore/test/setup.js | 40 ++++++++++++++++ .../test/unit/js/DocArchiveManagerTests.js | 16 +------ .../docstore/test/unit/js/DocManagerTests.js | 13 +----- .../test/unit/js/HttpControllerTests.js | 13 +----- .../test/unit/js/MongoManagerTests.js | 5 -- .../test/unit/js/RangeManagerTests.js | 4 +- 12 files changed, 71 insertions(+), 79 deletions(-) create mode 100644 services/docstore/.mocharc.json create mode 100644 services/docstore/test/setup.js diff --git a/services/docstore/.mocharc.json b/services/docstore/.mocharc.json new file mode 100644 index 0000000000..dc3280aa96 --- /dev/null +++ b/services/docstore/.mocharc.json @@ -0,0 +1,3 @@ +{ + "require": "test/setup.js" +} diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index f8531f23a2..61ed52ad99 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -14,9 +14,7 @@ */ process.env.BACKEND = 'gcs' const Settings = require('settings-sharelatex') -const chai = require('chai') -const { expect } = chai -const should = chai.should() +const { expect } = require('chai') const { db, ObjectId } = require('../../../app/js/mongodb') const async = require('async') const DocstoreApp = require('./helpers/DocstoreApp') @@ -96,8 +94,8 @@ describe('Archiving', function () { ((doc) => { return (callback) => { return db.docs.findOne({ _id: doc._id }, (error, doc) => { - should.not.exist(doc.lines) - should.not.exist(doc.ranges) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) return callback() }) @@ -155,7 +153,7 @@ describe('Archiving', function () { return db.docs.findOne({ _id: doc._id }, (error, doc) => { doc.lines.should.deep.equal(this.docs[i].lines) doc.ranges.should.deep.equal(this.docs[i].ranges) - should.not.exist(doc.inS3) + expect(doc.inS3).not.to.exist return callback() }) } @@ -218,8 +216,8 @@ describe('Archiving', function () { if (error != null) { throw error } - should.not.exist(doc.lines) - should.not.exist(doc.ranges) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) doc.deleted.should.equal(true) return done() @@ -267,7 +265,7 @@ describe('Archiving', function () { } doc.lines.should.deep.equal(this.doc.lines) doc.ranges.should.deep.equal(this.doc.ranges) - should.not.exist(doc.inS3) + expect(doc.inS3).not.to.exist doc.deleted.should.equal(true) return done() }) @@ -365,8 +363,8 @@ describe('Archiving', function () { if (error) { return done(error) } - should.not.exist(doc.lines) - should.not.exist(doc.ranges) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) done() }) @@ -433,8 +431,8 @@ describe('Archiving', function () { if (error != null) { throw error } - should.not.exist(doc.lines) - should.not.exist(doc.ranges) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) return done() }) @@ -476,7 +474,7 @@ describe('Archiving', function () { } doc.lines.should.deep.equal(this.doc.lines) doc.ranges.should.deep.equal(this.doc.ranges) - should.not.exist(doc.inS3) + expect(doc.inS3).not.to.exist return done() }) }) @@ -907,8 +905,8 @@ describe('Archiving', function () { if (error != null) { throw error } - should.not.exist(doc.lines) - should.not.exist(doc.ranges) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) return done() }) @@ -950,7 +948,7 @@ describe('Archiving', function () { } doc.lines.should.deep.equal(this.doc.lines) doc.ranges.should.deep.equal(this.doc.ranges) - should.not.exist(doc.inS3) + expect(doc.inS3).not.to.exist return done() }) }) @@ -1026,8 +1024,8 @@ describe('Archiving', function () { if (error != null) { throw error } - should.not.exist(doc.lines) - should.not.exist(doc.ranges) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) return done() }) @@ -1070,7 +1068,7 @@ describe('Archiving', function () { } doc.lines.should.deep.equal(this.doc.lines) doc.ranges.should.deep.equal(this.doc.ranges) - should.not.exist(doc.inS3) + expect(doc.inS3).not.to.exist return done() }) }) @@ -1123,8 +1121,8 @@ describe('Archiving', function () { if (error != null) { throw error } - should.not.exist(doc.lines) - should.not.exist(doc.ranges) + expect(doc.lines).not.to.exist + expect(doc.ranges).not.to.exist doc.inS3.should.equal(true) return done() }) @@ -1166,7 +1164,7 @@ describe('Archiving', function () { } doc.lines.should.deep.equal(this.doc.lines) doc.ranges.should.deep.equal(this.doc.ranges) - should.not.exist(doc.inS3) + expect(doc.inS3).not.to.exist return done() }) }) @@ -1220,7 +1218,7 @@ describe('Archiving', function () { throw error } doc.lines.should.deep.equal(this.doc.lines) - should.not.exist(doc.inS3) + expect(doc.inS3).not.to.exist return done() }) }) diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 232931102e..d481e5795b 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -11,10 +11,8 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -const chai = require('chai') -chai.should() const { db, ObjectId } = require('../../../app/js/mongodb') -const { expect } = chai +const { expect } = require('chai') const DocstoreApp = require('./helpers/DocstoreApp') const Errors = require('../../../app/js/Errors') const Settings = require('settings-sharelatex') diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 143052d71d..2d38ca5fba 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -12,8 +12,6 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ const sinon = require('sinon') -const chai = require('chai') -chai.should() const { ObjectId } = require('mongodb') const async = require('async') const DocstoreApp = require('./helpers/DocstoreApp') diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index 367115d475..7847abd84a 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -12,8 +12,6 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ const sinon = require('sinon') -const chai = require('chai') -chai.should() const { ObjectId } = require('mongodb') const DocstoreApp = require('./helpers/DocstoreApp') diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index 3c7d0d36f0..45d3cb9239 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -11,8 +11,6 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ const sinon = require('sinon') -const chai = require('chai') -chai.should() const { ObjectId } = require('mongodb') const DocstoreApp = require('./helpers/DocstoreApp') diff --git a/services/docstore/test/setup.js b/services/docstore/test/setup.js new file mode 100644 index 0000000000..f738f1c70f --- /dev/null +++ b/services/docstore/test/setup.js @@ -0,0 +1,40 @@ +const chai = require('chai') +const sinon = require('sinon') +const sinonChai = require('sinon-chai') +const chaiAsPromised = require('chai-as-promised') +const SandboxedModule = require('sandboxed-module') + +// Chai configuration +chai.should() +chai.use(sinonChai) +chai.use(chaiAsPromised) + +// Global stubs +const sandbox = sinon.createSandbox() +const stubs = { + logger: { + log: sandbox.stub(), + warn: sandbox.stub(), + err: sandbox.stub(), + error: sandbox.stub(), + fatal: sandbox.stub() + } +} + +// SandboxedModule configuration +SandboxedModule.configure({ + requires: { + 'logger-sharelatex': stubs.logger + }, + globals: { Buffer, JSON, console, process } +}) + +exports.mochaHooks = { + beforeEach() { + this.logger = stubs.logger + }, + + afterEach() { + sandbox.reset() + } +} diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 000afb1660..7d3218226d 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -1,21 +1,16 @@ const sinon = require('sinon') -const chai = require('chai') -const { expect } = chai +const { expect } = require('chai') const modulePath = '../../../app/js/DocArchiveManager.js' const SandboxedModule = require('sandboxed-module') const { ObjectId } = require('mongodb') const Errors = require('../../../app/js/Errors') -chai.use(require('chai-as-promised')) -chai.use(require('sinon-chai')) - describe('DocArchiveManager', function () { let DocArchiveManager, PersistorManager, MongoManager, RangeManager, Settings, - Logger, Crypto, Streamifier, HashDigest, @@ -39,10 +34,6 @@ describe('DocArchiveManager', function () { bucket: 'wombat' } } - Logger = { - log: sinon.stub(), - err: sinon.stub() - } HashDigest = sinon.stub().returns(md5Sum) HashUpdate = sinon.stub().returns({ digest: HashDigest }) Crypto = { @@ -141,17 +132,12 @@ describe('DocArchiveManager', function () { DocArchiveManager = SandboxedModule.require(modulePath, { requires: { 'settings-sharelatex': Settings, - 'logger-sharelatex': Logger, crypto: Crypto, streamifier: Streamifier, './MongoManager': MongoManager, './RangeManager': RangeManager, './PersistorManager': PersistorManager, './Errors': Errors - }, - globals: { - console, - JSON } }) }) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 50caa69501..624ca641af 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -14,11 +14,7 @@ */ const SandboxedModule = require('sandboxed-module') const sinon = require('sinon') -const chai = require('chai') -chai.use(require('sinon-chai')) -const { assert } = require('chai') -chai.should() -const { expect } = chai +const { assert, expect } = require('chai') const modulePath = require('path').join(__dirname, '../../../app/js/DocManager') const { ObjectId } = require('mongodb') const Errors = require('../../../app/js/Errors') @@ -36,11 +32,6 @@ describe('DocManager', function () { shouldUpdateRanges: sinon.stub().returns(false) }), 'settings-sharelatex': (this.settings = { docstore: {} }), - 'logger-sharelatex': (this.logger = { - log: sinon.stub(), - warn() {}, - err() {} - }), './Errors': Errors } }) @@ -493,7 +484,6 @@ describe('DocManager', function () { this.DocArchiveManager.archiveDocById = sinon .stub() .yields(this.err) - this.logger.warn = sinon.stub() this.callback = sinon.stub().callsFake(done) this.DocManager.deleteDoc( this.project_id, @@ -630,7 +620,6 @@ describe('DocManager', function () { beforeEach(function () { this.settings.docstore.archiveOnSoftDelete = true this.meta.deleted = true - this.logger.warn = sinon.stub() }) describe('when the background flush succeeds', function () { diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 4fc3651ada..219d35119c 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -10,11 +10,8 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ const SandboxedModule = require('sandboxed-module') -const { assert } = require('chai') const sinon = require('sinon') -const chai = require('chai') -chai.should() -const { expect } = chai +const { assert, expect } = require('chai') const modulePath = require('path').join( __dirname, '../../../app/js/HttpController' @@ -30,15 +27,9 @@ describe('HttpController', function () { requires: { './DocManager': (this.DocManager = {}), './DocArchiveManager': (this.DocArchiveManager = {}), - 'logger-sharelatex': (this.logger = { - log: sinon.stub(), - error: sinon.stub(), - fatal: sinon.stub() - }), 'settings-sharelatex': settings, './HealthChecker': {} - }, - globals: { process } + } }) this.res = { send: sinon.stub(), diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 0b073937f0..2e23087d19 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -11,7 +11,6 @@ */ const SandboxedModule = require('sandboxed-module') const sinon = require('sinon') -require('chai').should() const modulePath = require('path').join( __dirname, '../../../app/js/MongoManager' @@ -28,11 +27,7 @@ describe('MongoManager', function () { ObjectId }, '@overleaf/metrics': { timeAsyncMethod: sinon.stub() }, - 'logger-sharelatex': { log() {} }, 'settings-sharelatex': { max_deleted_docs: 42 } - }, - globals: { - console } }) this.project_id = ObjectId().toString() diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index 471f60e2c8..afea8f04c6 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -12,14 +12,12 @@ */ const SandboxedModule = require('sandboxed-module') const sinon = require('sinon') -require('chai').should() -const { expect } = require('chai') +const { assert, expect } = require('chai') const modulePath = require('path').join( __dirname, '../../../app/js/RangeManager' ) const { ObjectId } = require('mongodb') -const { assert } = require('chai') const _ = require('underscore') describe('RangeManager', function () { From 71470d3410a4fea619cd81c66b1c464dbce89cfa Mon Sep 17 00:00:00 2001 From: Eric Mc Sween <eric.mcsween@overleaf.com> Date: Fri, 12 Mar 2021 17:17:08 -0500 Subject: [PATCH 314/349] Upgrade to Node 12 --- services/docstore/.nvmrc | 2 +- services/docstore/Dockerfile | 2 +- services/docstore/Makefile | 6 ++++-- services/docstore/buildscript.txt | 4 ++-- services/docstore/docker-compose.yml | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index 2baa2d433a..e68b860383 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -10.23.1 +12.21.0 diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 2da67d2436..4f417a2a4b 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -2,7 +2,7 @@ # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -FROM node:10.23.1 as base +FROM node:12.21.0 as base WORKDIR /app diff --git a/services/docstore/Makefile b/services/docstore/Makefile index 77f11edeea..110e12fe8c 100644 --- a/services/docstore/Makefile +++ b/services/docstore/Makefile @@ -21,8 +21,10 @@ DOCKER_COMPOSE_TEST_UNIT = \ COMPOSE_PROJECT_NAME=test_unit_$(BUILD_DIR_NAME) $(DOCKER_COMPOSE) clean: - docker rmi ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) - docker rmi gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + -docker rmi ci/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + -docker rmi gcr.io/overleaf-ops/$(PROJECT_NAME):$(BRANCH_NAME)-$(BUILD_NUMBER) + -$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local + -$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local format: $(DOCKER_COMPOSE) run --rm test_unit npm run --silent format diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 1324e672a1..892e4769cb 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -3,6 +3,6 @@ docstore --docker-repos=gcr.io/overleaf-ops --env-add= --env-pass-through= ---node-version=10.23.1 +--node-version=12.21.0 --public-repo=True ---script-version=3.4.0 +--script-version=3.7.0 diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index 5e1111988b..d4a91fff95 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -6,7 +6,7 @@ version: "2.3" services: test_unit: - image: node:10.23.1 + image: node:12.21.0 volumes: - .:/app working_dir: /app @@ -18,7 +18,7 @@ services: user: node test_acceptance: - image: node:10.23.1 + image: node:12.21.0 volumes: - .:/app working_dir: /app From a21a6a2e72da89325ca466aed22bc29ddd8c13f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 Mar 2021 15:23:12 +0000 Subject: [PATCH 315/349] Bump y18n from 4.0.0 to 4.0.1 Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.1. - [Release notes](https://github.com/yargs/y18n/releases) - [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md) - [Commits](https://github.com/yargs/y18n/commits) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 36 +++-------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 5f825cb68b..34fcee0912 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1023,41 +1023,11 @@ "protobufjs": "^6.8.6" } }, - "@hapi/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", - "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/formula": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", - "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==" - }, "@hapi/hoek": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==" }, - "@hapi/joi": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz", - "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==", - "requires": { - "@hapi/address": "^4.0.1", - "@hapi/formula": "^2.0.0", - "@hapi/hoek": "^9.0.0", - "@hapi/pinpoint": "^2.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "@hapi/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==" - }, "@hapi/topo": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", @@ -7447,9 +7417,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yaassertion": { From e80d0132685b5bb4f74f97ba14a5a31578e0be7f Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 12 Apr 2021 17:31:18 +0100 Subject: [PATCH 316/349] [misc] drop the deleteDoc endpoint -- use patchDoc instead --- services/docstore/app.js | 4 +- services/docstore/app/js/DocManager.js | 52 ------ services/docstore/app/js/HttpController.js | 15 -- services/docstore/app/js/MongoManager.js | 13 -- .../test/acceptance/js/DeletingDocsTests.js | 21 --- .../acceptance/js/helpers/DocstoreClient.js | 12 -- .../docstore/test/unit/js/DocManagerTests.js | 166 ------------------ .../test/unit/js/HttpControllerTests.js | 21 --- .../test/unit/js/MongoManagerTests.js | 34 ---- 9 files changed, 3 insertions(+), 335 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index 08260dfbba..c6d2df480c 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -72,7 +72,9 @@ app.patch( }), HttpController.patchDoc ) -app.delete('/project/:project_id/doc/:doc_id', HttpController.deleteDoc) +app.delete('/project/:project_id/doc/:doc_id', (req, res) => { + res.status(500).send('DELETE-ing a doc is DEPRECATED. PATCH the doc instead.') +}) app.post('/project/:project_id/archive', HttpController.archiveAllDocs) app.post('/project/:project_id/doc/:doc_id/archive', HttpController.archiveDoc) diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 4a97c3688a..39e95f7961 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -74,23 +74,6 @@ module.exports = DocManager = { }) }, - checkDocExists(project_id, doc_id, callback) { - if (callback == null) { - callback = function (err, exists) {} - } - return DocManager._getDoc( - project_id, - doc_id, - { _id: 1, inS3: true }, - function (err, doc) { - if (err != null) { - return callback(err) - } - return callback(err, doc != null) - } - ) - }, - isDocDeleted(projectId, docId, callback) { MongoManager.findDoc(projectId, docId, { deleted: true }, function ( err, @@ -291,41 +274,6 @@ module.exports = DocManager = { ) }, - deleteDoc(project_id, doc_id, callback) { - if (callback == null) { - callback = function (error) {} - } - return DocManager.checkDocExists(project_id, doc_id, function ( - error, - exists - ) { - if (error != null) { - return callback(error) - } - if (!exists) { - return callback( - new Errors.NotFoundError( - `No such project/doc to delete: ${project_id}/${doc_id}` - ) - ) - } - - if (Settings.docstore.archiveOnSoftDelete) { - // The user will not read this doc anytime soon. Flush it out of mongo. - DocArchive.archiveDocById(project_id, doc_id, (err) => { - if (err) { - logger.warn( - { project_id, doc_id, err }, - 'archiving a single doc in the background failed' - ) - } - }) - } - - return MongoManager.markDocAsDeleted(project_id, doc_id, callback) - }) - }, - patchDoc(project_id, doc_id, meta, callback) { const projection = { _id: 1, deleted: true } MongoManager.findDoc(project_id, doc_id, projection, (error, doc) => { diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 0d7fc62061..885c241f39 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -191,21 +191,6 @@ module.exports = HttpController = { ) }, - deleteDoc(req, res, next) { - if (next == null) { - next = function (error) {} - } - const { project_id } = req.params - const { doc_id } = req.params - logger.log({ project_id, doc_id }, 'deleting doc') - return DocManager.deleteDoc(project_id, doc_id, function (error) { - if (error != null) { - return next(error) - } - return res.sendStatus(204) - }) - }, - patchDoc(req, res, next) { const { project_id, doc_id } = req.params logger.log({ project_id, doc_id }, 'patching doc') diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 753abaf1ea..7dc0afeb6c 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -100,19 +100,6 @@ module.exports = MongoManager = { ) }, - markDocAsDeleted(project_id, doc_id, callback) { - db.docs.updateOne( - { - _id: ObjectId(doc_id), - project_id: ObjectId(project_id) - }, - { - $set: { deleted: true } - }, - callback - ) - }, - patchDoc(project_id, doc_id, meta, callback) { db.docs.updateOne( { diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index d481e5795b..0d4e1942dc 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -203,27 +203,6 @@ function deleteTestSuite(deleteDoc) { }) } -describe('Delete via DELETE', function () { - deleteTestSuite(DocstoreClient.deleteDocLegacy) - - describe('when the doc gets no name on delete', function () { - beforeEach(function (done) { - DocstoreClient.deleteDocLegacy(this.project_id, this.doc_id, done) - }) - - it('should not show the doc in the deleted docs response', function (done) { - DocstoreClient.getAllDeletedDocs( - this.project_id, - (error, deletedDocs) => { - if (error) return done(error) - expect(deletedDocs).to.deep.equal([]) - done() - } - ) - }) - }) -}) - describe('Delete via PATCH', function () { deleteTestSuite(DocstoreClient.deleteDoc) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index fda0a66e1c..390a1a0931 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -131,18 +131,6 @@ module.exports = DocstoreClient = { ) }, - deleteDocLegacy(project_id, doc_id, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.del( - { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}` - }, - callback - ) - }, - deleteDoc(project_id, doc_id, callback) { DocstoreClient.deleteDocWithDateAndName( project_id, diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 624ca641af..1656cd2a6e 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -42,51 +42,6 @@ describe('DocManager', function () { return (this.stubbedError = new Error('blew up')) }) - describe('checkDocExists', function () { - beforeEach(function () { - return (this.DocManager._getDoc = sinon.stub()) - }) - - it('should call get doc with a quick filter', function (done) { - this.DocManager._getDoc.callsArgWith(3, null, { _id: this.doc_id }) - return this.DocManager.checkDocExists( - this.project_id, - this.doc_id, - (err, exist) => { - exist.should.equal(true) - this.DocManager._getDoc - .calledWith(this.project_id, this.doc_id, { _id: 1, inS3: true }) - .should.equal(true) - return done() - } - ) - }) - - it('should return false when doc is not there', function (done) { - this.DocManager._getDoc.callsArgWith(3, null) - return this.DocManager.checkDocExists( - this.project_id, - this.doc_id, - (err, exist) => { - exist.should.equal(false) - return done() - } - ) - }) - - return it('should return error when get doc errors', function (done) { - this.DocManager._getDoc.callsArgWith(3, 'error') - return this.DocManager.checkDocExists( - this.project_id, - this.doc_id, - (err, exist) => { - err.should.equal('error') - return done() - } - ) - }) - }) - describe('getFullDoc', function () { beforeEach(function () { this.DocManager._getDoc = sinon.stub() @@ -414,127 +369,6 @@ describe('DocManager', function () { }) }) - describe('deleteDoc', function () { - describe('when the doc exists', function () { - beforeEach(function (done) { - this.callback = sinon.stub().callsFake(done) - this.lines = ['mock', 'doc', 'lines'] - this.rev = 77 - this.DocManager.checkDocExists = sinon - .stub() - .callsArgWith(2, null, true) - this.MongoManager.markDocAsDeleted = sinon.stub().yields(null) - this.DocArchiveManager.archiveDocById = sinon.stub().yields(null) - return this.DocManager.deleteDoc( - this.project_id, - this.doc_id, - this.callback - ) - }) - - it('should get the doc', function () { - return this.DocManager.checkDocExists - .calledWith(this.project_id, this.doc_id) - .should.equal(true) - }) - - it('should mark doc as deleted', function () { - return this.MongoManager.markDocAsDeleted - .calledWith(this.project_id, this.doc_id) - .should.equal(true) - }) - - it('should return the callback', function () { - return this.callback.called.should.equal(true) - }) - - describe('background flush disabled', function () { - beforeEach(function () { - this.settings.docstore.archiveOnSoftDelete = false - }) - - it('should not flush the doc out of mongo', function () { - this.DocArchiveManager.archiveDocById.should.not.have.been.called - }) - }) - - describe('background flush enabled', function () { - beforeEach(function (done) { - this.settings.docstore.archiveOnSoftDelete = true - this.callback = sinon.stub().callsFake(done) - this.DocManager.deleteDoc(this.project_id, this.doc_id, this.callback) - }) - - it('should not fail the delete process', function () { - this.callback.should.have.been.calledWith(null) - }) - - it('should flush the doc out of mongo', function () { - this.DocArchiveManager.archiveDocById.should.have.been.calledWith( - this.project_id, - this.doc_id - ) - }) - - describe('when the background flush fails', function () { - beforeEach(function (done) { - this.err = new Error('foo') - this.DocManager.checkDocExists = sinon.stub().yields(null, true) - this.MongoManager.markDocAsDeleted = sinon.stub().yields(null) - this.DocArchiveManager.archiveDocById = sinon - .stub() - .yields(this.err) - this.callback = sinon.stub().callsFake(done) - this.DocManager.deleteDoc( - this.project_id, - this.doc_id, - this.callback - ) - }) - - it('should log a warning', function () { - this.logger.warn.should.have.been.calledWith( - sinon.match({ - project_id: this.project_id, - doc_id: this.doc_id, - err: this.err - }), - 'archiving a single doc in the background failed' - ) - }) - - it('should not fail the delete process', function () { - this.callback.should.have.been.calledWith(null) - }) - }) - }) - }) - - return describe('when the doc does not exist', function () { - beforeEach(function () { - this.DocManager.checkDocExists = sinon - .stub() - .callsArgWith(2, null, false) - return this.DocManager.deleteDoc( - this.project_id, - this.doc_id, - this.callback - ) - }) - - return it('should return a NotFoundError', function () { - return this.callback - .calledWith( - sinon.match.has( - 'message', - `No such project/doc to delete: ${this.project_id}/${this.doc_id}` - ) - ) - .should.equal(true) - }) - }) - }) - describe('patchDoc', function () { describe('when the doc exists', function () { beforeEach(function () { diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 219d35119c..d0686cda42 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -427,27 +427,6 @@ describe('HttpController', function () { }) }) - describe('deleteDoc', function () { - beforeEach(function () { - this.req.params = { - project_id: this.project_id, - doc_id: this.doc_id - } - this.DocManager.deleteDoc = sinon.stub().callsArg(2) - return this.HttpController.deleteDoc(this.req, this.res, this.next) - }) - - it('should delete the document', function () { - return this.DocManager.deleteDoc - .calledWith(this.project_id, this.doc_id) - .should.equal(true) - }) - - return it('should return a 204 (No Content)', function () { - return this.res.sendStatus.calledWith(204).should.equal(true) - }) - }) - describe('patchDoc', function () { beforeEach(function () { this.req.params = { diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 2e23087d19..7bf2c2d1a6 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -250,40 +250,6 @@ describe('MongoManager', function () { }) }) - describe('markDocAsDeleted', function () { - beforeEach(function () { - this.db.docs.updateOne = sinon.stub().callsArgWith(2, this.stubbedErr) - return (this.oldRev = 77) - }) - - it('should process the update', function (done) { - return this.MongoManager.markDocAsDeleted( - this.project_id, - this.doc_id, - (err) => { - const args = this.db.docs.updateOne.args[0] - assert.deepEqual(args[0], { - _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id) - }) - assert.equal(args[1].$set.deleted, true) - return done() - } - ) - }) - - return it('should return the error', function (done) { - return this.MongoManager.markDocAsDeleted( - this.project_id, - this.doc_id, - (err) => { - err.should.equal(this.stubbedErr) - return done() - } - ) - }) - }) - describe('destroyDoc', function () { beforeEach(function (done) { this.db.docs.deleteOne = sinon.stub().yields() From 5bcd142b6f1956af136b93f468762de40158c905 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 12 Apr 2021 16:54:11 +0100 Subject: [PATCH 317/349] [MongoManager] drop name filter from getProjectsDeletedDocs All the doc names we had in the projects collection are back-filled now. A few docs will get dummy values back-filled. --- services/docstore/app/js/MongoManager.js | 4 +--- services/docstore/test/unit/js/MongoManagerTests.js | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 7dc0afeb6c..8c6538ea76 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -39,9 +39,7 @@ module.exports = MongoManager = { .find( { project_id: ObjectId(project_id.toString()), - deleted: true, - // TODO(das7pad): remove name filter after back filling data - name: { $exists: true } + deleted: true }, { projection: filter, diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 7bf2c2d1a6..4e54a56586 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -192,8 +192,7 @@ describe('MongoManager', function () { this.db.docs.find .calledWith({ project_id: ObjectId(this.project_id), - deleted: true, - name: { $exists: true } + deleted: true }) .should.equal(true) }) From 3f94dd4dbfbf3a3697cf087a2bc4e233954a53bd Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Fri, 16 Apr 2021 09:27:09 +0100 Subject: [PATCH 318/349] [DocArchiveManager] destroy in small batches Also add settings options for PARALLEL_JOBS and DESTROY_BATCH_SIZE. --- services/docstore/app/js/DocArchiveManager.js | 18 +++++++++++------- services/docstore/app/js/MongoManager.js | 12 +++++++----- services/docstore/config/settings.defaults.js | 5 ++++- .../test/unit/js/DocArchiveManagerTests.js | 5 +++++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index a123ccdfb6..b9fe93ac0f 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -9,7 +9,8 @@ const RangeManager = require('./RangeManager') const PersistorManager = require('./PersistorManager') const pMap = require('p-map') -const PARALLEL_JOBS = 5 +const PARALLEL_JOBS = settings.parallelArchiveJobs +const DESTROY_BATCH_SIZE = settings.destroyBatchSize module.exports = { archiveAllDocs: callbackify(archiveAllDocs), @@ -175,12 +176,15 @@ async function unarchiveDoc(projectId, docId) { } async function destroyAllDocs(projectId) { - const docs = await MongoManager.getProjectsDocs( - projectId, - { include_deleted: true }, - { _id: 1 } - ) - if (docs && docs.length) { + while (true) { + const docs = await MongoManager.getProjectsDocs( + projectId, + { include_deleted: true, limit: DESTROY_BATCH_SIZE }, + { _id: 1 } + ) + if (!docs || docs.length === 0) { + break + } await pMap(docs, (doc) => destroyDoc(projectId, doc._id), { concurrency: PARALLEL_JOBS }) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 753abaf1ea..582c99c945 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -57,11 +57,13 @@ module.exports = MongoManager = { if (!options.include_deleted) { query.deleted = { $ne: true } } - db.docs - .find(query, { - projection: filter - }) - .toArray(callback) + const queryOptions = { + projection: filter + } + if (options.limit) { + queryOptions.limit = options.limit + } + db.docs.find(query, queryOptions).toArray(callback) }, getArchivedProjectDocs(project_id, callback) { diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 808470b950..7f42154770 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -40,7 +40,10 @@ const Settings = { max_deleted_docs: parseInt(process.env.MAX_DELETED_DOCS, 10) || 2000, - max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024 // 2mb + max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024, // 2mb + + destroyBatchSize: parseInt(process.env.DESTROY_BATCH_SIZE, 10) || 2000, + parallelArchiveJobs: parseInt(process.env.PARALLEL_ARCHIVE_JOBS, 10) || 5 } if (process.env.MONGO_CONNECTION_STRING != null) { diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 7d3218226d..ceb490108f 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -518,6 +518,11 @@ describe('DocArchiveManager', function () { }) describe('destroyAllDocs', function () { + beforeEach(function () { + MongoManager.promises.getProjectsDocs.onCall(0).resolves(mongoDocs) + MongoManager.promises.getProjectsDocs.onCall(1).resolves([]) + }) + it('should resolve with valid arguments', async function () { await expect(DocArchiveManager.promises.destroyAllDocs(projectId)).to .eventually.be.fulfilled From f5274e52c18b2c7cf821de09d9e48d512127d116 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Thu, 29 Apr 2021 15:30:53 +0100 Subject: [PATCH 319/349] [misc] add linting for missing explicit dependencies and fix any errors --- services/docstore/.eslintrc | 13 ++- services/docstore/buildscript.txt | 2 +- services/docstore/package-lock.json | 131 ++++++---------------------- services/docstore/package.json | 2 + 4 files changed, 42 insertions(+), 106 deletions(-) diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc index 76dad1561d..321353f971 100644 --- a/services/docstore/.eslintrc +++ b/services/docstore/.eslintrc @@ -22,7 +22,10 @@ "rules": { // Swap the no-unused-expressions rule with a more chai-friendly one "no-unused-expressions": 0, - "chai-friendly/no-unused-expressions": "error" + "chai-friendly/no-unused-expressions": "error", + + // Do not allow importing of implicit dependencies. + "import/no-extraneous-dependencies": "error" }, "overrides": [ { @@ -57,7 +60,13 @@ "files": ["app/**/*.js", "app.js", "index.js"], "rules": { // don't allow console.log in backend code - "no-console": "error" + "no-console": "error", + + // Do not allow importing of implicit dependencies. + "import/no-extraneous-dependencies": ["error", { + // Do not allow importing of devDependencies. + "devDependencies": false + }] } } ] diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 892e4769cb..84b47af18d 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -5,4 +5,4 @@ docstore --env-pass-through= --node-version=12.21.0 --public-repo=True ---script-version=3.7.0 +--script-version=3.8.0 diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 5f825cb68b..9597725922 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1023,41 +1023,11 @@ "protobufjs": "^6.8.6" } }, - "@hapi/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", - "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/formula": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", - "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==" - }, "@hapi/hoek": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==" }, - "@hapi/joi": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz", - "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==", - "requires": { - "@hapi/address": "^4.0.1", - "@hapi/formula": "^2.0.0", - "@hapi/hoek": "^9.0.0", - "@hapi/pinpoint": "^2.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "@hapi/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==" - }, "@hapi/topo": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", @@ -1450,7 +1420,6 @@ "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -1584,8 +1553,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" }, "assertion-error": { "version": "1.1.0", @@ -1625,8 +1593,7 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "aws-sdk": { "version": "2.754.0", @@ -1654,14 +1621,12 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "dev": true + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==" }, "aws4": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", - "dev": true + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, "axe-core": { "version": "3.5.5", @@ -1714,7 +1679,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -1871,8 +1835,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", - "dev": true + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" }, "celebrate": { "version": "13.0.4", @@ -2058,7 +2021,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -2275,7 +2237,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dev": true, "requires": { "assert-plus": "^1.0.0" }, @@ -2283,8 +2244,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -2344,8 +2304,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "delegates": { "version": "1.0.0", @@ -2425,7 +2384,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -3056,8 +3014,7 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "dev": true + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==" }, "fast-crc32c": { "version": "2.0.0", @@ -3070,8 +3027,7 @@ "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==", - "dev": true + "integrity": "sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==" }, "fast-diff": { "version": "1.2.0", @@ -3082,8 +3038,7 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==", - "dev": true + "integrity": "sha512-eIgZvM9C3P05kg0qxfqaVU6Tma4QedCPIByQOcemV0vju8ot3cS2DpHi4m2G2JvbSMI152rjfLX0p1pkSdyPlQ==" }, "fast-levenshtein": { "version": "2.0.6", @@ -3210,14 +3165,12 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "dev": true + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==" }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -3384,7 +3337,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dev": true, "requires": { "assert-plus": "^1.0.0" }, @@ -3392,8 +3344,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -3561,14 +3512,12 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "dev": true + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==" }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -3693,7 +3642,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -4042,8 +3990,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", - "dev": true + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" }, "jmespath": { "version": "0.15.0", @@ -4081,8 +4028,7 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "dev": true + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, "jsesc": { "version": "2.5.2", @@ -4101,14 +4047,12 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==", - "dev": true + "integrity": "sha512-a3xHnILGMtk+hDOqNwHzF6e2fNbiMrXZvxKQiEv2MlgQP+pjIOzqAmKYD2mDpXYE/44M7g+n9p2bKkYWDUcXCQ==" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -4119,8 +4063,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { "version": "1.0.1", @@ -4135,7 +4078,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -4146,8 +4088,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -4968,8 +4909,7 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "object-assign": { "version": "4.1.1", @@ -5247,8 +5187,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", - "dev": true + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "picomatch": { "version": "2.2.2", @@ -5976,8 +5915,7 @@ "psl": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", - "dev": true + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" }, "pump": { "version": "3.0.0", @@ -6202,7 +6140,6 @@ "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -6229,8 +6166,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" } } }, @@ -6684,7 +6620,6 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -6701,7 +6636,6 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -6709,8 +6643,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, @@ -7040,7 +6973,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -7049,8 +6981,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" } } }, @@ -7076,7 +7007,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -7084,8 +7014,7 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", - "dev": true + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "type-check": { "version": "0.3.2", @@ -7158,7 +7087,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" }, @@ -7166,8 +7094,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" } } }, @@ -7220,7 +7147,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -7230,8 +7156,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" } } }, diff --git a/services/docstore/package.json b/services/docstore/package.json index 572f497f8d..10a3bf965e 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -20,6 +20,7 @@ }, "dependencies": { "@overleaf/metrics": "^3.5.1", + "@overleaf/o-error": "^3.0.0", "@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/4ca62157a2beb747e9a56da3ce1569124b90378a.tar.gz", "async": "^2.6.3", "body-parser": "^1.19.0", @@ -28,6 +29,7 @@ "logger-sharelatex": "^2.2.0", "mongodb": "^3.6.0", "p-map": "^4.0.0", + "request": "^2.88.2", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", "underscore": "~1.10.2" From 7e583c1bcd15f57cd88cad3a4a00c1a6782dfd2b Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Fri, 30 Apr 2021 09:44:26 +0100 Subject: [PATCH 320/349] [misc] drop request from devDependencies Co-Authored-By: Alf Eaton <alf.eaton@overleaf.com> --- services/docstore/package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/services/docstore/package.json b/services/docstore/package.json index 10a3bf965e..b919a100e9 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -58,7 +58,6 @@ "mocha": "^7.2.0", "prettier": "^2.0.0", "prettier-eslint-cli": "^5.0.0", - "request": "~2.88.2", "sandboxed-module": "~2.0.4", "sinon": "~9.0.2", "sinon-chai": "^3.5.0" From 9ba82378501a46af98cc65838391c72ec97f5c2a Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Wed, 5 May 2021 10:57:12 +0100 Subject: [PATCH 321/349] [DocArchiveManager] retry the deletion of doc archives three times --- services/docstore/app/js/DocArchiveManager.js | 27 +++++++++++-- services/docstore/config/settings.defaults.js | 1 + .../test/unit/js/DocArchiveManagerTests.js | 40 ++++++++++++++++++- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index b9fe93ac0f..13bf8db6cd 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -11,6 +11,7 @@ const pMap = require('p-map') const PARALLEL_JOBS = settings.parallelArchiveJobs const DESTROY_BATCH_SIZE = settings.destroyBatchSize +const DESTROY_RETRY_COUNT = settings.destroyRetryCount module.exports = { archiveAllDocs: callbackify(archiveAllDocs), @@ -204,14 +205,32 @@ async function destroyDoc(projectId, docId) { } if (doc.inS3) { - await PersistorManager.deleteObject( - settings.docstore.bucket, - `${projectId}/${docId}` - ) + await destroyArchiveWithRetry(projectId, docId) } await MongoManager.destroyDoc(docId) } +async function destroyArchiveWithRetry(projectId, docId) { + let attempt = 0 + let lastError + while (attempt++ <= DESTROY_RETRY_COUNT) { + try { + await PersistorManager.deleteObject( + settings.docstore.bucket, + `${projectId}/${docId}` + ) + return + } catch (err) { + lastError = err + logger.warn( + { projectId, docId, err, attempt }, + 'destroying archive failed' + ) + } + } + throw lastError +} + async function _streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 7f42154770..69fed07181 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -43,6 +43,7 @@ const Settings = { max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024, // 2mb destroyBatchSize: parseInt(process.env.DESTROY_BATCH_SIZE, 10) || 2000, + destroyRetryCount: parseInt(process.env.DESTROY_RETRY_COUNT || '3', 10), parallelArchiveJobs: parseInt(process.env.PARALLEL_ARCHIVE_JOBS, 10) || 5 } diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index ceb490108f..a324cfe916 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -32,7 +32,10 @@ describe('DocArchiveManager', function () { Settings = { docstore: { bucket: 'wombat' - } + }, + parallelArchiveJobs: 3, + destroyBatchSize: 10, + destroyRetryCount: 3 } HashDigest = sinon.stub().returns(md5Sum) HashUpdate = sinon.stub().returns({ digest: HashDigest }) @@ -436,6 +439,41 @@ describe('DocArchiveManager', function () { it('should delete the doc in mongo', async function () { await DocArchiveManager.promises.destroyDoc(projectId, docId) }) + + describe('when the destroy request errors', function () { + beforeEach(function () { + mongoDocs[0].inS3 = true + PersistorManager.deleteObject.onFirstCall().rejects(new Error('1')) + PersistorManager.deleteObject.onSecondCall().rejects(new Error('2')) + PersistorManager.deleteObject.onThirdCall().resolves() + }) + + it('should retry', async function () { + await DocArchiveManager.promises.destroyDoc(projectId, docId) + expect(PersistorManager.deleteObject).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${docId}` + ) + expect(PersistorManager.deleteObject.callCount).to.equal(3) + }) + }) + + describe('when the destroy request errors permanent', function () { + beforeEach(function () { + mongoDocs[0].inS3 = true + PersistorManager.deleteObject.rejects(new Error('permanent')) + }) + + it('should retry and fail eventually', async function () { + await expect(DocArchiveManager.promises.destroyDoc(projectId, docId)) + .to.eventually.be.rejected + expect(PersistorManager.deleteObject).to.have.been.calledWith( + Settings.docstore.bucket, + `${projectId}/${docId}` + ) + expect(PersistorManager.deleteObject.callCount).to.equal(4) + }) + }) }) describe('when the doc is not in s3', function () { From 847ff87ce3b2348c05ff178518a0c8c51b19e832 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 04:33:05 +0000 Subject: [PATCH 322/349] Bump lodash from 4.17.19 to 4.17.21 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.19 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.19...4.17.21) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 36 +++-------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 5f825cb68b..33c4e44309 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1023,41 +1023,11 @@ "protobufjs": "^6.8.6" } }, - "@hapi/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", - "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/formula": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", - "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==" - }, "@hapi/hoek": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==" }, - "@hapi/joi": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz", - "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==", - "requires": { - "@hapi/address": "^4.0.1", - "@hapi/formula": "^2.0.0", - "@hapi/hoek": "^9.0.0", - "@hapi/pinpoint": "^2.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "@hapi/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==" - }, "@hapi/topo": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", @@ -4242,9 +4212,9 @@ } }, "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.at": { "version": "4.6.0", From eb8a3118d82cbc44f445eda781c5cdb19d87ff29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 13:04:24 +0000 Subject: [PATCH 323/349] Bump hosted-git-info from 2.8.5 to 2.8.9 Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.5 to 2.8.9. - [Release notes](https://github.com/npm/hosted-git-info/releases) - [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md) - [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.5...v2.8.9) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 36 +++-------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 5f825cb68b..87a73511d4 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1023,41 +1023,11 @@ "protobufjs": "^6.8.6" } }, - "@hapi/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@hapi/address/-/address-4.1.0.tgz", - "integrity": "sha512-SkszZf13HVgGmChdHo/PxchnSaCJ6cetVqLzyciudzZRT0jcOouIF/Q93mgjw8cce+D+4F4C1Z/WrfFN+O3VHQ==", - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@hapi/formula": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/formula/-/formula-2.0.0.tgz", - "integrity": "sha512-V87P8fv7PI0LH7LiVi8Lkf3x+KCO7pQozXRssAHNXXL9L1K+uyu4XypLXwxqVDKgyQai6qj3/KteNlrqDx4W5A==" - }, "@hapi/hoek": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==" }, - "@hapi/joi": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-17.1.1.tgz", - "integrity": "sha512-p4DKeZAoeZW4g3u7ZeRo+vCDuSDgSvtsB/NpfjXEHTUjSeINAi/RrVOWiVQ1isaoLzMvFEhe8n5065mQq1AdQg==", - "requires": { - "@hapi/address": "^4.0.1", - "@hapi/formula": "^2.0.0", - "@hapi/hoek": "^9.0.0", - "@hapi/pinpoint": "^2.0.0", - "@hapi/topo": "^5.0.0" - } - }, - "@hapi/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@hapi/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-vzXR5MY7n4XeIvLpfl3HtE3coZYO4raKXW766R6DZw/6aLqR26iuZ109K7a0NtF2Db0jxqh7xz2AxkUwpUFybw==" - }, "@hapi/topo": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", @@ -3647,9 +3617,9 @@ "integrity": "sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==" }, "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "http-errors": { From acbf8b5898eac2020023b46f9164d602ebffb777 Mon Sep 17 00:00:00 2001 From: Alf Eaton <alf.eaton@overleaf.com> Date: Wed, 19 May 2021 20:22:02 +0100 Subject: [PATCH 324/349] Tidy and format --- services/docstore/config/settings.defaults.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 7f42154770..4f1340ec57 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -1,8 +1,3 @@ -/* - * decaffeinate suggestions: - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ const http = require('http') http.globalAgent.maxSockets = 300 @@ -46,18 +41,18 @@ const Settings = { parallelArchiveJobs: parseInt(process.env.PARALLEL_ARCHIVE_JOBS, 10) || 5 } -if (process.env.MONGO_CONNECTION_STRING != null) { +if (process.env.MONGO_CONNECTION_STRING) { Settings.mongo.url = process.env.MONGO_CONNECTION_STRING -} else if (process.env.MONGO_HOST != null) { +} else if (process.env.MONGO_HOST) { Settings.mongo.url = `mongodb://${process.env.MONGO_HOST}/sharelatex` } else { Settings.mongo.url = 'mongodb://127.0.0.1/sharelatex' } if ( - process.env.AWS_ACCESS_KEY_ID != null && - process.env.AWS_SECRET_ACCESS_KEY != null && - process.env.AWS_BUCKET != null + process.env.AWS_ACCESS_KEY_ID && + process.env.AWS_SECRET_ACCESS_KEY && + process.env.AWS_BUCKET ) { Settings.docstore.s3 = { key: process.env.AWS_ACCESS_KEY_ID, From 91c19e1f88eb7ee5d06514fbc1bfb39836191e51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 27 May 2021 15:43:37 +0000 Subject: [PATCH 325/349] Bump underscore from 1.10.2 to 1.13.1 Bumps [underscore](https://github.com/jashkenas/underscore) from 1.10.2 to 1.13.1. - [Release notes](https://github.com/jashkenas/underscore/releases) - [Commits](https://github.com/jashkenas/underscore/compare/1.10.2...1.13.1) Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 6 +++--- services/docstore/package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 0e3d901d2f..3a77082289 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -7066,9 +7066,9 @@ "dev": true }, "underscore": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.10.2.tgz", - "integrity": "sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg==" + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", + "integrity": "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw==" }, "unique-string": { "version": "2.0.0", diff --git a/services/docstore/package.json b/services/docstore/package.json index b919a100e9..f85c21673f 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -32,7 +32,7 @@ "request": "^2.88.2", "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", - "underscore": "~1.10.2" + "underscore": "~1.12.1" }, "devDependencies": { "@google-cloud/storage": "^5.1.2", From 4996f8bbcd6df543c509a51e77cb1d0c4ed3d34a Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 8 Jun 2021 12:59:13 +0100 Subject: [PATCH 326/349] [DocArchiveManager] (un-)archive docs in batches and let db filter docs Also drop the broken 404 logic after switching to db-side filtering. --- services/docstore/app/js/DocArchiveManager.js | 55 +++++++++++-------- services/docstore/app/js/MongoManager.js | 16 ++++-- services/docstore/config/settings.defaults.js | 2 + .../test/unit/js/DocArchiveManagerTests.js | 30 +++++----- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 13bf8db6cd..7b4bf4611f 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -10,6 +10,8 @@ const PersistorManager = require('./PersistorManager') const pMap = require('p-map') const PARALLEL_JOBS = settings.parallelArchiveJobs +const ARCHIVE_BATCH_SIZE = settings.archiveBatchSize +const UN_ARCHIVE_BATCH_SIZE = settings.unArchiveBatchSize const DESTROY_BATCH_SIZE = settings.destroyBatchSize const DESTROY_RETRY_COUNT = settings.destroyRetryCount @@ -33,20 +35,19 @@ module.exports = { } async function archiveAllDocs(projectId) { - const docs = await MongoManager.getProjectsDocs( - projectId, - { include_deleted: true }, - { lines: true, ranges: true, rev: true, inS3: true } - ) + while (true) { + const docs = await MongoManager.getNNonArchivedProjectDocs( + projectId, + ARCHIVE_BATCH_SIZE + ) + if (!docs || docs.length === 0) { + break + } - if (!docs) { - throw new Errors.NotFoundError(`No docs for project ${projectId}`) + await pMap(docs, (doc) => archiveDoc(projectId, doc), { + concurrency: PARALLEL_JOBS + }) } - - const docsToArchive = docs.filter((doc) => !doc.inS3) - await pMap(docsToArchive, (doc) => archiveDoc(projectId, doc), { - concurrency: PARALLEL_JOBS - }) } async function archiveDocById(projectId, docId) { @@ -102,18 +103,26 @@ async function archiveDoc(projectId, doc) { } async function unArchiveAllDocs(projectId) { - let docs - if (settings.docstore.keepSoftDeletedDocsArchived) { - docs = await MongoManager.getNonDeletedArchivedProjectDocs(projectId) - } else { - docs = await MongoManager.getArchivedProjectDocs(projectId) + while (true) { + let docs + if (settings.docstore.keepSoftDeletedDocsArchived) { + docs = await MongoManager.getNNonDeletedArchivedProjectDocs( + projectId, + UN_ARCHIVE_BATCH_SIZE + ) + } else { + docs = await MongoManager.getNArchivedProjectDocs( + projectId, + UN_ARCHIVE_BATCH_SIZE + ) + } + if (!docs || docs.length === 0) { + break + } + await pMap(docs, (doc) => unarchiveDoc(projectId, doc._id), { + concurrency: PARALLEL_JOBS + }) } - if (!docs) { - throw new Errors.NotFoundError(`No docs for project ${projectId}`) - } - await pMap(docs, (doc) => unarchiveDoc(projectId, doc._id), { - concurrency: PARALLEL_JOBS - }) } async function unarchiveDoc(projectId, docId) { diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 7bfdf82aef..e62f7e6eaf 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -64,21 +64,29 @@ module.exports = MongoManager = { db.docs.find(query, queryOptions).toArray(callback) }, - getArchivedProjectDocs(project_id, callback) { + getNArchivedProjectDocs(project_id, n, callback) { const query = { project_id: ObjectId(project_id.toString()), inS3: true } - db.docs.find(query).toArray(callback) + db.docs.find(query, { projection: { _id: 1 }, limit: n }).toArray(callback) }, - getNonDeletedArchivedProjectDocs(project_id, callback) { + getNNonArchivedProjectDocs(project_id, n, callback) { + const query = { + project_id: ObjectId(project_id.toString()), + inS3: { $ne: true } + } + db.docs.find(query, { limit: n }).toArray(callback) + }, + + getNNonDeletedArchivedProjectDocs(project_id, n, callback) { const query = { project_id: ObjectId(project_id.toString()), deleted: { $ne: true }, inS3: true } - db.docs.find(query).toArray(callback) + db.docs.find(query, { projection: { _id: 1 }, limit: n }).toArray(callback) }, upsertIntoDocCollection(project_id, doc_id, updates, callback) { diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 8d3ecdc9f1..0f1c1ab42b 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -37,6 +37,8 @@ const Settings = { max_doc_length: parseInt(process.env.MAX_DOC_LENGTH) || 2 * 1024 * 1024, // 2mb + archiveBatchSize: parseInt(process.env.ARCHIVE_BATCH_SIZE, 10) || 50, + unArchiveBatchSize: parseInt(process.env.UN_ARCHIVE_BATCH_SIZE, 10) || 50, destroyBatchSize: parseInt(process.env.DESTROY_BATCH_SIZE, 10) || 2000, destroyRetryCount: parseInt(process.env.DESTROY_RETRY_COUNT || '3', 10), parallelArchiveJobs: parseInt(process.env.PARALLEL_ARCHIVE_JOBS, 10) || 5 diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index a324cfe916..e902622db1 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -116,12 +116,24 @@ describe('DocArchiveManager', function () { deleteObject: sinon.stub().resolves() } + const getNNonArchivedProjectDocs = sinon.stub() + getNNonArchivedProjectDocs + .onCall(0) + .resolves(mongoDocs.filter((doc) => !doc.inS3)) + getNNonArchivedProjectDocs.onCall(1).resolves([]) + + const getNArchivedProjectDocs = sinon.stub() + getNArchivedProjectDocs.onCall(0).resolves(archivedDocs) + getNArchivedProjectDocs.onCall(1).resolves([]) + MongoManager = { promises: { markDocAsArchived: sinon.stub().resolves(), upsertIntoDocCollection: sinon.stub().resolves(), getProjectsDocs: sinon.stub().resolves(mongoDocs), - getArchivedProjectDocs: sinon.stub().resolves(archivedDocs), + getNNonDeletedArchivedProjectDocs: getNArchivedProjectDocs, + getNNonArchivedProjectDocs, + getNArchivedProjectDocs, findDoc: sinon.stub().rejects(new Errors.NotFoundError()), destroyDoc: sinon.stub().resolves() } @@ -519,14 +531,6 @@ describe('DocArchiveManager', function () { MongoManager.promises.markDocAsArchived ).not.to.have.been.calledWith(mongoDocs[3]._id) }) - - it('should return error if the project has no docs', async function () { - MongoManager.promises.getProjectsDocs.resolves(null) - - await expect( - DocArchiveManager.promises.archiveAllDocs(projectId) - ).to.eventually.be.rejected.and.be.instanceof(Errors.NotFoundError) - }) }) describe('unArchiveAllDocs', function () { @@ -545,14 +549,6 @@ describe('DocArchiveManager', function () { ) } }) - - it('should return error if the project has no docs', async function () { - MongoManager.promises.getArchivedProjectDocs.resolves(null) - - await expect( - DocArchiveManager.promises.unArchiveAllDocs(projectId) - ).to.eventually.be.rejected.and.be.instanceof(Errors.NotFoundError) - }) }) describe('destroyAllDocs', function () { From d69c29e4dcef97774fe955358612b2ec8504e31a Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 8 Jun 2021 19:29:10 +0100 Subject: [PATCH 327/349] [misc] apply review feedback on naming functions and parameters Co-Authored-By: Simon Detheridge <s@sd.ai> --- services/docstore/app/js/DocArchiveManager.js | 6 +++--- services/docstore/app/js/MongoManager.js | 16 ++++++++++------ .../test/unit/js/DocArchiveManagerTests.js | 18 +++++++++--------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 7b4bf4611f..7a062bc739 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -36,7 +36,7 @@ module.exports = { async function archiveAllDocs(projectId) { while (true) { - const docs = await MongoManager.getNNonArchivedProjectDocs( + const docs = await MongoManager.getNonArchivedProjectDocs( projectId, ARCHIVE_BATCH_SIZE ) @@ -106,12 +106,12 @@ async function unArchiveAllDocs(projectId) { while (true) { let docs if (settings.docstore.keepSoftDeletedDocsArchived) { - docs = await MongoManager.getNNonDeletedArchivedProjectDocs( + docs = await MongoManager.getNonDeletedArchivedProjectDocs( projectId, UN_ARCHIVE_BATCH_SIZE ) } else { - docs = await MongoManager.getNArchivedProjectDocs( + docs = await MongoManager.getArchivedProjectDocs( projectId, UN_ARCHIVE_BATCH_SIZE ) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index e62f7e6eaf..385245c9e3 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -64,29 +64,33 @@ module.exports = MongoManager = { db.docs.find(query, queryOptions).toArray(callback) }, - getNArchivedProjectDocs(project_id, n, callback) { + getArchivedProjectDocs(project_id, maxResults, callback) { const query = { project_id: ObjectId(project_id.toString()), inS3: true } - db.docs.find(query, { projection: { _id: 1 }, limit: n }).toArray(callback) + db.docs + .find(query, { projection: { _id: 1 }, limit: maxResults }) + .toArray(callback) }, - getNNonArchivedProjectDocs(project_id, n, callback) { + getNonArchivedProjectDocs(project_id, maxResults, callback) { const query = { project_id: ObjectId(project_id.toString()), inS3: { $ne: true } } - db.docs.find(query, { limit: n }).toArray(callback) + db.docs.find(query, { limit: maxResults }).toArray(callback) }, - getNNonDeletedArchivedProjectDocs(project_id, n, callback) { + getNonDeletedArchivedProjectDocs(project_id, maxResults, callback) { const query = { project_id: ObjectId(project_id.toString()), deleted: { $ne: true }, inS3: true } - db.docs.find(query, { projection: { _id: 1 }, limit: n }).toArray(callback) + db.docs + .find(query, { projection: { _id: 1 }, limit: maxResults }) + .toArray(callback) }, upsertIntoDocCollection(project_id, doc_id, updates, callback) { diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index e902622db1..41fe75a8df 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -116,24 +116,24 @@ describe('DocArchiveManager', function () { deleteObject: sinon.stub().resolves() } - const getNNonArchivedProjectDocs = sinon.stub() - getNNonArchivedProjectDocs + const getNonArchivedProjectDocs = sinon.stub() + getNonArchivedProjectDocs .onCall(0) .resolves(mongoDocs.filter((doc) => !doc.inS3)) - getNNonArchivedProjectDocs.onCall(1).resolves([]) + getNonArchivedProjectDocs.onCall(1).resolves([]) - const getNArchivedProjectDocs = sinon.stub() - getNArchivedProjectDocs.onCall(0).resolves(archivedDocs) - getNArchivedProjectDocs.onCall(1).resolves([]) + const getArchivedProjectDocs = sinon.stub() + getArchivedProjectDocs.onCall(0).resolves(archivedDocs) + getArchivedProjectDocs.onCall(1).resolves([]) MongoManager = { promises: { markDocAsArchived: sinon.stub().resolves(), upsertIntoDocCollection: sinon.stub().resolves(), getProjectsDocs: sinon.stub().resolves(mongoDocs), - getNNonDeletedArchivedProjectDocs: getNArchivedProjectDocs, - getNNonArchivedProjectDocs, - getNArchivedProjectDocs, + getNonDeletedArchivedProjectDocs: getArchivedProjectDocs, + getNonArchivedProjectDocs, + getArchivedProjectDocs, findDoc: sinon.stub().rejects(new Errors.NotFoundError()), destroyDoc: sinon.stub().resolves() } From 302576b386c065dd7bafeb96c1e69788d7d01d7b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 10 Jun 2021 09:11:02 +0000 Subject: [PATCH 328/349] Bump glob-parent from 5.1.1 to 5.1.2 Bumps [glob-parent](https://github.com/gulpjs/glob-parent) from 5.1.1 to 5.1.2. - [Release notes](https://github.com/gulpjs/glob-parent/releases) - [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md) - [Commits](https://github.com/gulpjs/glob-parent/compare/v5.1.1...v5.1.2) --- updated-dependencies: - dependency-name: glob-parent dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- services/docstore/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 868ea78aaa..d8e76d0a5a 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -3362,9 +3362,9 @@ } }, "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" From 5239f6c327873e3127f81031760b58463a4e8817 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 12 Jul 2021 17:35:50 +0100 Subject: [PATCH 329/349] [misc] install bunyan as production dependency ``` Error: Cannot find module 'bunyan' Require stack: - .../node_modules/@google-cloud/logging-bunyan/build/src/middleware/express.js - .../node_modules/@google-cloud/logging-bunyan/build/src/index.js - .../node_modules/logger-sharelatex/logging-manager.js - .../node_modules/logger-sharelatex/index.js - .../app.js ``` --- services/docstore/package-lock.json | 20 ++++++++++---------- services/docstore/package.json | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index d8e76d0a5a..8d7e7c9040 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1794,9 +1794,9 @@ "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==" }, "bunyan": { - "version": "1.8.14", - "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.14.tgz", - "integrity": "sha512-LlahJUxXzZLuw/hetUQJmRgZ1LF6+cr5TPpRj6jf327AsiIq2jhYEH4oqUUkVKTor+9w2BT3oxVwhzE5lw9tcg==", + "version": "1.8.15", + "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.15.tgz", + "integrity": "sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig==", "requires": { "dtrace-provider": "~0.8", "moment": "^2.19.3", @@ -3351,7 +3351,7 @@ "glob": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", "optional": true, "requires": { "inflight": "^1.0.4", @@ -4638,9 +4638,9 @@ "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", "optional": true }, "mongodb": { @@ -4670,7 +4670,7 @@ "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", - "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", "optional": true, "requires": { "mkdirp": "~0.5.1", @@ -4692,7 +4692,7 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", "optional": true }, "needle": { @@ -6288,7 +6288,7 @@ "rimraf": { "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", - "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", "optional": true, "requires": { "glob": "^6.0.1" diff --git a/services/docstore/package.json b/services/docstore/package.json index f85c21673f..f979fce529 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -24,6 +24,7 @@ "@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/4ca62157a2beb747e9a56da3ce1569124b90378a.tar.gz", "async": "^2.6.3", "body-parser": "^1.19.0", + "bunyan": "^1.8.15", "celebrate": "^13.0.4", "express": "^4.17.1", "logger-sharelatex": "^2.2.0", @@ -37,7 +38,6 @@ "devDependencies": { "@google-cloud/storage": "^5.1.2", "babel-eslint": "^10.1.0", - "bunyan": "~1.8.14", "chai": "~4.2.0", "chai-as-promised": "^7.1.1", "eslint": "^6.8.0", From 2c35adaf489ec7d7cdd14620dee8f91b2e1440d8 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 12 Jul 2021 17:47:20 +0100 Subject: [PATCH 330/349] [misc] switch from settings-sharelatex to @overleaf/settings --- services/docstore/app.js | 2 +- services/docstore/app/js/DocArchiveManager.js | 2 +- services/docstore/app/js/DocManager.js | 2 +- services/docstore/app/js/HealthChecker.js | 2 +- services/docstore/app/js/HttpController.js | 2 +- services/docstore/app/js/MongoManager.js | 2 +- services/docstore/app/js/PersistorManager.js | 2 +- services/docstore/app/js/mongodb.js | 2 +- services/docstore/package-lock.json | 20 +++++-------------- services/docstore/package.json | 2 +- .../test/acceptance/js/ArchiveDocsTests.js | 2 +- .../test/acceptance/js/DeletingDocsTests.js | 2 +- .../test/acceptance/js/helpers/DocstoreApp.js | 2 +- .../acceptance/js/helpers/DocstoreClient.js | 2 +- .../test/unit/js/DocArchiveManagerTests.js | 2 +- .../docstore/test/unit/js/DocManagerTests.js | 2 +- .../test/unit/js/HttpControllerTests.js | 2 +- .../test/unit/js/MongoManagerTests.js | 2 +- 18 files changed, 22 insertions(+), 32 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index c6d2df480c..e31775e943 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -6,7 +6,7 @@ */ const Metrics = require('@overleaf/metrics') Metrics.initialize('docstore') -const Settings = require('settings-sharelatex') +const Settings = require('@overleaf/settings') const logger = require('logger-sharelatex') const express = require('express') const bodyParser = require('body-parser') diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 7a062bc739..807ae8b3d7 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -2,7 +2,7 @@ const { callbackify } = require('util') const MongoManager = require('./MongoManager').promises const Errors = require('./Errors') const logger = require('logger-sharelatex') -const settings = require('settings-sharelatex') +const settings = require('@overleaf/settings') const crypto = require('crypto') const Streamifier = require('streamifier') const RangeManager = require('./RangeManager') diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 39e95f7961..2951377743 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -20,7 +20,7 @@ const logger = require('logger-sharelatex') const _ = require('underscore') const DocArchive = require('./DocArchiveManager') const RangeManager = require('./RangeManager') -const Settings = require('settings-sharelatex') +const Settings = require('@overleaf/settings') module.exports = DocManager = { // TODO: For historical reasons, the doc version is currently stored in the docOps diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 567774af3e..30d82ee8a3 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -15,7 +15,7 @@ const request = require('request') const async = require('async') const _ = require('underscore') const crypto = require('crypto') -const settings = require('settings-sharelatex') +const settings = require('@overleaf/settings') const { port } = settings.internal.docstore const logger = require('logger-sharelatex') diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 885c241f39..593dcc6a2f 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -17,7 +17,7 @@ const DocManager = require('./DocManager') const logger = require('logger-sharelatex') const DocArchive = require('./DocArchiveManager') const HealthChecker = require('./HealthChecker') -const Settings = require('settings-sharelatex') +const Settings = require('@overleaf/settings') module.exports = HttpController = { getDoc(req, res, next) { diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 385245c9e3..4e3f71eac8 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -14,7 +14,7 @@ let MongoManager const { db, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') const metrics = require('@overleaf/metrics') -const Settings = require('settings-sharelatex') +const Settings = require('@overleaf/settings') const { promisify } = require('util') module.exports = MongoManager = { diff --git a/services/docstore/app/js/PersistorManager.js b/services/docstore/app/js/PersistorManager.js index aae716e7ab..241b29c4f6 100644 --- a/services/docstore/app/js/PersistorManager.js +++ b/services/docstore/app/js/PersistorManager.js @@ -1,4 +1,4 @@ -const settings = require('settings-sharelatex') +const settings = require('@overleaf/settings') const persistorSettings = settings.docstore persistorSettings.Metrics = require('@overleaf/metrics') diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js index 566b9a07e9..245f7ed8f7 100644 --- a/services/docstore/app/js/mongodb.js +++ b/services/docstore/app/js/mongodb.js @@ -1,4 +1,4 @@ -const Settings = require('settings-sharelatex') +const Settings = require('@overleaf/settings') const { MongoClient, ObjectId } = require('mongodb') const clientPromise = MongoClient.connect( diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 8d7e7c9040..756b05775b 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1131,6 +1131,11 @@ } } }, + "@overleaf/settings": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@overleaf/settings/-/settings-2.1.1.tgz", + "integrity": "sha512-vcJwqCGFKmQxTP/syUqCeMaSRjHmBcQgKOACR9He2uJcErg2GZPa1go+nGvszMbkElM4HfRKm/MfxvqHhoN4TQ==" + }, "@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -6410,21 +6415,6 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, - "settings-sharelatex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", - "integrity": "sha512-f7D+0lnlohoteSn6IKTH72NE+JnAdMWTKwQglAuimZWTID2FRRItZSGeYMTRpvEnaQApkoVwRp//WRMsiddnqw==", - "requires": { - "coffee-script": "1.6.0" - }, - "dependencies": { - "coffee-script": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/coffee-script/-/coffee-script-1.6.0.tgz", - "integrity": "sha512-Tx8itEfCsQp8RbLDFt7qwjqXycAx2g6SI7//4PPUR2j6meLmNifYm6zKrNDcU1+Q/GWRhjhEZk7DaLG1TfIzGA==" - } - } - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", diff --git a/services/docstore/package.json b/services/docstore/package.json index f979fce529..5ebda01024 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -22,6 +22,7 @@ "@overleaf/metrics": "^3.5.1", "@overleaf/o-error": "^3.0.0", "@overleaf/object-persistor": "https://github.com/overleaf/object-persistor/archive/4ca62157a2beb747e9a56da3ce1569124b90378a.tar.gz", + "@overleaf/settings": "^2.1.1", "async": "^2.6.3", "body-parser": "^1.19.0", "bunyan": "^1.8.15", @@ -31,7 +32,6 @@ "mongodb": "^3.6.0", "p-map": "^4.0.0", "request": "^2.88.2", - "settings-sharelatex": "^1.1.0", "streamifier": "^0.1.1", "underscore": "~1.12.1" }, diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 61ed52ad99..2a4948ba5d 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -13,7 +13,7 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ process.env.BACKEND = 'gcs' -const Settings = require('settings-sharelatex') +const Settings = require('@overleaf/settings') const { expect } = require('chai') const { db, ObjectId } = require('../../../app/js/mongodb') const async = require('async') diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index 0d4e1942dc..bc38f3fad8 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -15,7 +15,7 @@ const { db, ObjectId } = require('../../../app/js/mongodb') const { expect } = require('chai') const DocstoreApp = require('./helpers/DocstoreApp') const Errors = require('../../../app/js/Errors') -const Settings = require('settings-sharelatex') +const Settings = require('@overleaf/settings') const DocstoreClient = require('./helpers/DocstoreClient') diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 351a744b13..d541a8f454 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -14,7 +14,7 @@ const app = require('../../../../app') const { waitForDb } = require('../../../../app/js/mongodb') require('logger-sharelatex').logger.level('error') -const settings = require('settings-sharelatex') +const settings = require('@overleaf/settings') module.exports = { running: false, diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 390a1a0931..49b50907bb 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -13,7 +13,7 @@ */ let DocstoreClient const request = require('request').defaults({ jar: false }) -const settings = require('settings-sharelatex') +const settings = require('@overleaf/settings') const Persistor = require('../../../../app/js/PersistorManager') async function streamToString(stream) { diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 41fe75a8df..0316343c0f 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -146,7 +146,7 @@ describe('DocArchiveManager', function () { DocArchiveManager = SandboxedModule.require(modulePath, { requires: { - 'settings-sharelatex': Settings, + '@overleaf/settings': Settings, crypto: Crypto, streamifier: Streamifier, './MongoManager': MongoManager, diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 1656cd2a6e..60b3a20885 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -31,7 +31,7 @@ describe('DocManager', function () { }, shouldUpdateRanges: sinon.stub().returns(false) }), - 'settings-sharelatex': (this.settings = { docstore: {} }), + '@overleaf/settings': (this.settings = { docstore: {} }), './Errors': Errors } }) diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index d0686cda42..16b7baf5b0 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -27,7 +27,7 @@ describe('HttpController', function () { requires: { './DocManager': (this.DocManager = {}), './DocArchiveManager': (this.DocArchiveManager = {}), - 'settings-sharelatex': settings, + '@overleaf/settings': settings, './HealthChecker': {} } }) diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 4e54a56586..1e80fd1f21 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -27,7 +27,7 @@ describe('MongoManager', function () { ObjectId }, '@overleaf/metrics': { timeAsyncMethod: sinon.stub() }, - 'settings-sharelatex': { max_deleted_docs: 42 } + '@overleaf/settings': { max_deleted_docs: 42 } } }) this.project_id = ObjectId().toString() From 74f049fc4a1a3d30617e739f42c0bfef38919be6 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Mon, 12 Jul 2021 17:51:06 +0100 Subject: [PATCH 331/349] [misc] run npm dedupe --- services/docstore/package-lock.json | 121 +++++++--------------------- 1 file changed, 30 insertions(+), 91 deletions(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 756b05775b..f1dd2c1087 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -1555,6 +1555,14 @@ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==" }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -1886,12 +1894,6 @@ "supports-color": "^5.3.0" }, "dependencies": { - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2113,29 +2115,9 @@ "xdg-basedir": "^4.0.0" }, "dependencies": { - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "requires": { - "semver": "^6.0.0" - } - }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "version": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } } } }, @@ -2244,13 +2226,6 @@ "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", "requires": { "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - } } }, "date-and-time": { @@ -3344,13 +3319,6 @@ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", "requires": { "assert-plus": "^1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - } } }, "glob": { @@ -4088,13 +4056,6 @@ "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - } } }, "jsx-ast-utils": { @@ -4338,6 +4299,11 @@ "yallist": "^3.0.2" } }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==" + }, "make-plural": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", @@ -4345,15 +4311,6 @@ "dev": true, "requires": { "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true, - "optional": true - } } }, "map-obj": { @@ -4481,13 +4438,6 @@ "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==", "requires": { "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" - } } }, "mocha": { @@ -5863,6 +5813,11 @@ "parse-ms": "^2.1.0" } }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -6095,11 +6050,6 @@ "util-deprecate": "~1.0.1" }, "dependencies": { - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" - }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -6620,21 +6570,6 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" - }, - "dependencies": { - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - } } }, "stack-trace": { @@ -7141,13 +7076,6 @@ "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==" - } } }, "vue-eslint-parser": { @@ -7337,6 +7265,17 @@ "mkdirp": "^0.5.1" } }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", From c4cfb0bd78e5ccb73b2e963b1f3baf3ecb23b74b Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 13 Jul 2021 10:07:04 +0100 Subject: [PATCH 332/349] [misc] goodbye coffee-script --- services/docstore/package-lock.json | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index f1dd2c1087..77540447d7 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -4302,7 +4302,17 @@ "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==" + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } }, "make-plural": { "version": "4.3.0", From 679ea1616c8ba00d9025833ca30bd89600914566 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 13 Jul 2021 11:55:18 +0100 Subject: [PATCH 333/349] [misc] upgrade build scripts to version 3.11.0 and cleanup packages ``` npm uninstall prettier-eslint-cli eslint-plugin-standard eslint-plugin-jsx-a11y eslint-plugin-react eslint-config-standard-jsx eslint-config-standard-react babel-eslint npm dedupe ``` --- services/docstore/.eslintrc | 2 +- services/docstore/.github/dependabot.yml | 2 +- services/docstore/.prettierrc | 6 +- services/docstore/buildscript.txt | 2 +- services/docstore/package-lock.json | 3377 +++++++--------------- services/docstore/package.json | 36 +- 6 files changed, 1015 insertions(+), 2410 deletions(-) diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc index 321353f971..1c14f50efe 100644 --- a/services/docstore/.eslintrc +++ b/services/docstore/.eslintrc @@ -3,9 +3,9 @@ // https://github.com/sharelatex/sharelatex-dev-environment { "extends": [ + "eslint:recommended", "standard", "prettier", - "prettier/standard" ], "parserOptions": { "ecmaVersion": 2018 diff --git a/services/docstore/.github/dependabot.yml b/services/docstore/.github/dependabot.yml index e2c64a3351..c856753655 100644 --- a/services/docstore/.github/dependabot.yml +++ b/services/docstore/.github/dependabot.yml @@ -20,4 +20,4 @@ updates: # future if we reorganise teams labels: - "dependencies" - - "Team-Magma" + - "type:maintenance" diff --git a/services/docstore/.prettierrc b/services/docstore/.prettierrc index 24f9ec526f..c92c3526e7 100644 --- a/services/docstore/.prettierrc +++ b/services/docstore/.prettierrc @@ -2,6 +2,10 @@ # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment { + "arrowParens": "avoid", "semi": false, - "singleQuote": true + "singleQuote": true, + "trailingComma": "es5", + "tabWidth": 2, + "useTabs": false } diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index 84b47af18d..a87ee7a694 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -5,4 +5,4 @@ docstore --env-pass-through= --node-version=12.21.0 --public-repo=True ---script-version=3.8.0 +--script-version=3.11.0 diff --git a/services/docstore/package-lock.json b/services/docstore/package-lock.json index 77540447d7..534f4cfb20 100644 --- a/services/docstore/package-lock.json +++ b/services/docstore/package-lock.json @@ -5,142 +5,75 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/generator": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.3.tgz", - "integrity": "sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "dev": true, - "requires": { - "@babel/types": "^7.8.3" + "@babel/highlight": "^7.10.4" } }, "@babel/helper-validator-identifier": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", - "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", + "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", "dev": true }, "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@babel/parser": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.3.tgz", - "integrity": "sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==", - "dev": true - }, - "@babel/runtime": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.5.tgz", - "integrity": "sha512-otddXKhdNn7d0ptoFRHtMLa8LqDxLYwTjB4nYgM1yy5N6gU/MUf8zqyyLltCH3yAVitBzmwK4us+DD0l/MauAg==", + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/runtime-corejs3": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.10.5.tgz", - "integrity": "sha512-RMafpmrNB5E/bwdSphLr8a8++9TosnyJp98RZzI6VOx2R2CCMpsXXXRvmI700O9oEKpXdZat6oEK68/F0zjd4A==", - "dev": true, - "requires": { - "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/traverse": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", - "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.0", - "@babel/types": "^7.9.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "ms": "^2.1.1" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -149,17 +82,6 @@ } } }, - "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "@google-cloud/common": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.4.0.tgz", @@ -238,11 +160,6 @@ "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==" }, - "acorn": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.5.tgz", - "integrity": "sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg==" - }, "bignumber.js": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", @@ -335,14 +252,6 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -731,14 +640,6 @@ "node-fetch": "^2.3.0" } }, - "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", - "requires": { - "p-try": "^2.0.0" - } - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -1036,6 +937,40 @@ "@hapi/hoek": "^9.0.0" } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "@opencensus/core": { "version": "0.0.20", "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.20.tgz", @@ -1258,23 +1193,11 @@ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, "@types/console-log-level": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz", "integrity": "sha512-x+OscEQwcx5Biair4enH7ov9W+clcqUWaZRaxn5IkT4yNWWjRr2oiYDkY/x1uXSTVZOQ2xlbFQySaQGB+VdXGQ==" }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, "@types/fs-extra": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.1.tgz", @@ -1283,18 +1206,6 @@ "@types/node": "*" } }, - "@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, "@types/long": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", @@ -1310,50 +1221,11 @@ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.4.tgz", "integrity": "sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ==" }, - "@typescript-eslint/experimental-utils": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz", - "integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "1.13.0", - "eslint-scope": "^4.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - } - } - }, - "@typescript-eslint/parser": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.13.0.tgz", - "integrity": "sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ==", - "dev": true, - "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "1.13.0", - "@typescript-eslint/typescript-estree": "1.13.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz", - "integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" - } + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true }, "abbrev": { "version": "1.1.1", @@ -1378,15 +1250,14 @@ } }, "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.0.5.tgz", + "integrity": "sha512-v+DieK/HJkJOpFBETDJioequtc3PfxsWMaxIdIwujtF7FEV/MAyDQLlm6/zPvr7Mix07mLh6ccVwIsloceodlg==" }, "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", - "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true }, "agent-base": { @@ -1433,28 +1304,11 @@ } }, "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "requires": { - "type-fest": "^0.11.0" - }, - "dependencies": { - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true - } - } - }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -1471,9 +1325,9 @@ } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -1503,51 +1357,50 @@ "sprintf-js": "~1.0.2" } }, - "aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - } - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" } }, "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "array.prototype.flatmap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", - "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1" + "es-abstract": "^1.18.0-next.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==" + } } }, "arrify": { @@ -1574,16 +1427,10 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==", - "dev": true - }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async": { @@ -1641,43 +1488,6 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" }, - "axe-core": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-3.5.5.tgz", - "integrity": "sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==", - "dev": true - }, - "axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", - "dev": true - }, - "babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "dependencies": { - "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -1702,9 +1512,9 @@ "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" }, "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, "bindings": { @@ -1746,12 +1556,6 @@ "type-is": "~1.6.17" } }, - "boolify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/boolify/-/boolify-1.0.1.tgz", - "integrity": "sha512-ma2q0Tc760dW54CdOyJjhrg/a54317o1zYADQJFgperNGKIKgAUGIcKnuMiff8z57+yGlrGNEt4lPgZfCgTJgA==", - "dev": true - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1822,6 +1626,16 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1829,22 +1643,11 @@ "dev": true }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, - "camelcase-keys": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.1.2.tgz", - "integrity": "sha512-QfFrU0CIw2oltVvpndW32kuJ/9YOJwUnmWrjlXt1nnJZHCaS9i6bfOpg9R4Lw8aZjStkJWM+jc0cdXjWBgVJSw==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - } - }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", @@ -1892,25 +1695,8 @@ "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "charenc": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", @@ -1923,19 +1709,18 @@ "dev": true }, "chokidar": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", - "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.2.0" + "readdirp": "~3.5.0" } }, "chownr": { @@ -1948,55 +1733,15 @@ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha512-EJLbKSuvHTrVRynOXCYFTbQKZOFXWNe3/6DN1yrEH3TuuZT1x4dMQnCHnfCrBUUiGjO63enEIfaB17VaRl2d4A==", - "dev": true - }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, "code-point-at": { @@ -2032,12 +1777,6 @@ "delayed-stream": "~1.0.0" } }, - "common-tags": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", - "dev": true - }, "compressible": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", @@ -2131,12 +1870,6 @@ "resolved": "https://registry.npmjs.org/console-log-level/-/console-log-level-1.4.1.tgz", "integrity": "sha512-VZzbIORbP+PPcN/gg3DXClTLPLg5Slwd5fL2MIc+o1qZ4BXBvWyc6QxPk6T/Mkr6IVjRpoAGf32XxP3ZWMVRcQ==" }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha512-OKZnPGeMQy2RPaUIBPFFd71iNf4791H12MCRuVQDnzGRwCYNYmTDy5pdafo2SLAcEMKzTOQnLWG4QdcjeJUMEg==", - "dev": true - }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -2169,34 +1902,20 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "core-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", - "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", - "dev": true - }, - "core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", - "dev": true - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "crypt": { @@ -2214,12 +1933,6 @@ "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" }, - "damerau-levenshtein": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.6.tgz", - "integrity": "sha512-JVrozIeElnj3QzfUIt8tB8YMluBJom4Vw9qTPpjGYQ9fYlB3D/rb6OordUxf3xeFB35LKWs0xqcO5U6ySvBtug==", - "dev": true - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -2242,9 +1955,9 @@ } }, "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", "dev": true }, "deep-eql": { @@ -2312,15 +2025,9 @@ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", "dev": true }, "doctrine": { @@ -2409,6 +2116,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "ent": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", @@ -2424,22 +2140,24 @@ } }, "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.3.tgz", + "integrity": "sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "object-inspect": "^1.10.3", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -2453,6 +2171,12 @@ "is-symbol": "^1.0.2" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -2461,70 +2185,165 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.30.0.tgz", + "integrity": "sha512-VLqz80i3as3NdloY44BQSJpFw534L9Oh+6zJOUaViV4JPd+DaHwutqP7tcpkW3YiXbK6s05RZl7yl7cQn+lijg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", + "@humanwhocodes/config-array": "^0.5.0", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "debug": { + "chalk": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { - "ms": "^2.1.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" } }, "ms": { @@ -2533,44 +2352,43 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "requires": { + "glob": "^7.1.3" + } + }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "eslint-config-prettier": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", - "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", - "dev": true, - "requires": { - "get-stdin": "^6.0.0" - } + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", + "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "dev": true }, "eslint-config-standard": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.1.tgz", - "integrity": "sha512-Z9B+VR+JIXRxz21udPTL9HpFMyoMUEeX1G251EQ6e05WD9aPVtVBn09XUmZ259wCMlCDmYDSZG62Hhm+ZTJcUg==", + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.3.tgz", + "integrity": "sha512-x4fmJL5hGqNJKGHSjnLdgA6U6h1YW/G2dW9fA+cyVur4SK6lyue8+UgNKWlZtUDTXvgKDD/Oa3GQjmB5kjtVvg==", "dev": true }, - "eslint-config-standard-jsx": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-8.1.0.tgz", - "integrity": "sha512-ULVC8qH8qCqbU792ZOO6DaiaZyHNS/5CZt3hKqHkEhVlhPEPN3nfBqqxJCyp59XrjIBZPu1chMYe9T2DXZ7TMw==", - "dev": true - }, - "eslint-config-standard-react": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/eslint-config-standard-react/-/eslint-config-standard-react-9.2.0.tgz", - "integrity": "sha512-u+KRP2uCtthZ/W4DlLWCC59GZNV/y9k9yicWWammgTs/Omh8ZUUPF3EnYm81MAcbkYQq2Wg0oxutAhi/FQ8mIw==", - "dev": true, - "requires": { - "eslint-config-standard-jsx": "^8.0.0" - } - }, "eslint-import-resolver-node": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", @@ -2582,24 +2400,42 @@ }, "dependencies": { "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } } } }, "eslint-module-utils": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", - "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.1.tgz", + "integrity": "sha512-ZXI9B8cxAJIH4nfkhTwcRTEAnrVfobYqwjWy/QMCZ8rHkZHFjf9yO4BzpiF9kCSfNlMG54eKigISHpX0+AaT4A==", "dev": true, "requires": { - "debug": "^2.6.9", + "debug": "^3.2.7", "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } } }, "eslint-plugin-chai-expect": { @@ -2609,9 +2445,9 @@ "dev": true }, "eslint-plugin-chai-friendly": { - "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==", + "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==", "dev": true }, "eslint-plugin-es": { @@ -2622,113 +2458,79 @@ "requires": { "eslint-utils": "^2.0.0", "regexpp": "^3.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", - "dev": true - } } }, "eslint-plugin-import": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz", - "integrity": "sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg==", + "version": "2.23.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.23.4.tgz", + "integrity": "sha512-6/wP8zZRsnQFiR3iaPFgh5ImVRM1WN5NUWfTIRqwOdeiGJlBcSk82o1FEVq8yXmy4lkIzTo7YhHCIxlU/2HyEQ==", "dev": true, "requires": { - "array-includes": "^3.1.1", - "array.prototype.flat": "^1.2.3", - "contains-path": "^0.1.0", + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.3", - "eslint-module-utils": "^2.6.0", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.1", + "find-up": "^2.0.0", "has": "^1.0.3", + "is-core-module": "^2.4.0", "minimatch": "^3.0.4", - "object.values": "^1.1.1", - "read-pkg-up": "^2.0.0", - "resolve": "^1.17.0", + "object.values": "^1.1.3", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", "tsconfig-paths": "^3.9.0" }, "dependencies": { "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha512-lsGyRuYr4/PIB0txi+Fy2xOMI2dGaTguCaotzFGkVZuKR5usKfcRWIFKNM3QNrU7hh/+w2bwTW+ZeXPK5l8uVg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "esutils": "^2.0.2" + } + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==" + }, + "is-core-module": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz", + "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==", + "dev": true, + "requires": { + "has": "^1.0.3" } }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dev": true, "requires": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } } } }, - "eslint-plugin-jsx-a11y": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.3.1.tgz", - "integrity": "sha512-i1S+P+c3HOlBJzMFORRbC58tHa65Kbo8b52/TwCwSKLohwvpfT5rm2GjGWzOHTEuq4xxf2aRlHHTtmExDQOP+g==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.2", - "aria-query": "^4.2.2", - "array-includes": "^3.1.1", - "ast-types-flow": "^0.0.7", - "axe-core": "^3.5.4", - "axobject-query": "^2.1.2", - "damerau-levenshtein": "^1.0.6", - "emoji-regex": "^9.0.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1", - "language-tags": "^1.0.5" - }, - "dependencies": { - "emoji-regex": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.0.0.tgz", - "integrity": "sha512-6p1NII1Vm62wni/VR/cUMauVQoxmLVb9csqQlvLz+hO2gk8U2UYDfXHQSUYIBKmZwAKz867IDqG7B+u0mj+M6w==", - "dev": true - } - } - }, "eslint-plugin-mocha": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-6.3.0.tgz", - "integrity": "sha512-Cd2roo8caAyG21oKaaNTj7cqeYRWW1I2B5SfpKRp0Ip1gkfwoR1Ow0IGlPWnNjzywdF4n+kHL8/9vM6zCJUxdg==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-8.2.0.tgz", + "integrity": "sha512-8oOR47Ejt+YJPNQzedbiklDqS1zurEaNrxXpRs+Uk4DMDPVmKNagShFeUaYsfvWP55AhI+P1non5QZAHV6K78A==", "dev": true, "requires": { - "eslint-utils": "^2.0.0", - "ramda": "^0.27.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - } + "eslint-utils": "^2.1.0", + "ramda": "^0.27.1" } }, "eslint-plugin-node": { @@ -2745,15 +2547,6 @@ "semver": "^6.1.0" }, "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, "ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", @@ -2783,65 +2576,20 @@ "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", "dev": true }, - "eslint-plugin-react": { - "version": "7.20.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.3.tgz", - "integrity": "sha512-txbo090buDeyV0ugF3YMWrzLIUqpYTsWSDZV9xLSmExE1P/Kmgg9++PD931r+KEWS66O1c9R4srLVVHmeHpoAg==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "array.prototype.flatmap": "^1.2.3", - "doctrine": "^2.1.0", - "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1", - "object.entries": "^1.1.2", - "object.fromentries": "^2.0.2", - "object.values": "^1.1.1", - "prop-types": "^15.7.2", - "resolve": "^1.17.0", - "string.prototype.matchall": "^4.0.2" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } - } - }, - "eslint-plugin-standard": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", - "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", - "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.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -2854,26 +2602,26 @@ "dev": true }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, "dependencies": { "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, - "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true } } @@ -2885,21 +2633,26 @@ "dev": true }, "esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { @@ -2980,17 +2733,6 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -3031,22 +2773,13 @@ "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.1.tgz", "integrity": "sha512-x4FEgaz3zNRtJfLFqJmHWxkMDDvXVtaznj2V9jiP8ACUJrUgist4bP9FmDL2Vew2Y9mEQI/tG4GqabaitYp9CQ==" }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-uri-to-path": { @@ -3080,7 +2813,7 @@ "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" @@ -3092,54 +2825,24 @@ "integrity": "sha1-WKRmaX34piBc39vzlVNri9d3pfY=" }, "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "flatted": "^3.1.0" } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.1.tgz", + "integrity": "sha512-OMQjaErSFHmHqZe+PSidH5n8j3O0F2DdnVh8JB4j4eUQ2k6KvB0qGfrKIhapvez5JerBbmWkaLYUYWISaESoXg==", "dev": true }, "forever-agent": { @@ -3180,13 +2883,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -3307,11 +3003,16 @@ "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, - "get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } }, "getpass": { "version": "0.1.7", @@ -3344,10 +3045,13 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.10.0.tgz", + "integrity": "sha512-piHC3blgLGFjvOuMmWZX60f+na1lXFDhQXBf1UYp2fXPXqvEUbOhNwi6BsQ0bQishwedgnjkwv1d9zKf+MWw3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } }, "google-auth-library": { "version": "6.0.3", @@ -3504,22 +3208,11 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - } - } + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true }, "has-flag": { "version": "3.0.0", @@ -3719,108 +3412,6 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", - "dev": true, - "requires": { - "es-abstract": "^1.17.0-next.1", - "has": "^1.0.3", - "side-channel": "^1.0.2" - } - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -3834,7 +3425,13 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", "dev": true }, "is-binary-path": { @@ -3846,11 +3443,19 @@ "binary-extensions": "^2.0.0" } }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-callable": { "version": "1.2.0", @@ -3875,7 +3480,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-fullwidth-code-point": { @@ -3893,30 +3498,42 @@ "is-extglob": "^2.1.1" } }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" }, - "is-promise": { + "is-plain-obj": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha512-NECAi6wp6CgMesHuVUEK8JwjCvm/tvnn5pCbB42JOHp3mgUizN0nagXu4HEqQZBkieGEQ+jVcMKWqoVd6CDbLQ==", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", - "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "call-bind": "^1.0.2" } }, "is-stream": { @@ -4003,12 +3620,6 @@ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, "json-bigint": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", @@ -4017,6 +3628,12 @@ "bignumber.js": "^7.0.0" } }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -4039,12 +3656,12 @@ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" }, "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" } }, "jsprim": { @@ -4058,16 +3675,6 @@ "verror": "1.10.0" } }, - "jsx-ast-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", - "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", - "dev": true, - "requires": { - "array-includes": "^3.1.1", - "object.assign": "^4.1.0" - } - }, "just-extend": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", @@ -4093,47 +3700,32 @@ "safe-buffer": "^5.0.1" } }, - "language-subtag-registry": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.20.tgz", - "integrity": "sha512-KPMwROklF4tEx283Xw0pNKtfTj1gZ4UByp4EsIFWLgBavJltF4TiYPc39k06zSTsLzxTVXXDSpbwaQXaFB4Qeg==", - "dev": true - }, - "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==", - "dev": true, - "requires": { - "language-subtag-registry": "~0.3.2" - } - }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", + "parse-json": "^4.0.0", + "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "dependencies": { "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } @@ -4141,7 +3733,7 @@ "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", @@ -4163,6 +3755,12 @@ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -4174,22 +3772,16 @@ "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=" }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==", + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, "log-driver": { @@ -4198,12 +3790,63 @@ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" }, "log-symbols": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", - "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", "dev": true, "requires": { - "chalk": "^2.4.2" + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "logger-sharelatex": { @@ -4219,78 +3862,11 @@ "yn": "^4.0.0" } }, - "loglevel": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", - "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==", - "dev": true - }, - "loglevel-colored-level-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/loglevel-colored-level-prefix/-/loglevel-colored-level-prefix-1.0.0.tgz", - "integrity": "sha512-u45Wcxxc+SdAlh4yeF/uKlC1SPUPCy0gullSNKXod5I4bmifzk+Q4lSLExNEVn19tGaJipbZ4V4jbFn79/6mVA==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "loglevel": "^1.4.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true - } - } - }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4314,15 +3890,6 @@ } } }, - "make-plural": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, "map-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", @@ -4336,13 +3903,6 @@ "charenc": "0.0.2", "crypt": "0.0.2", "is-buffer": "~1.1.6" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - } } }, "media-typer": { @@ -4361,29 +3921,6 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, - "messageformat": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", - "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", - "dev": true, - "requires": { - "make-plural": "^4.3.0", - "messageformat-formatters": "^2.0.1", - "messageformat-parser": "^4.1.2" - } - }, - "messageformat-formatters": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", - "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==", - "dev": true - }, - "messageformat-parser": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.2.tgz", - "integrity": "sha512-7dWuifeyldz7vhEuL96Kwq1fhZXBW+TUfbnHN4UCrCxoXQTYjHnR78eI66Gk9LaLLsAvzPNVJBaa66DRfFNaiA==", - "dev": true - }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -4451,65 +3988,102 @@ } }, "mocha": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.2.0.tgz", - "integrity": "sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", "dev": true, "requires": { - "ansi-colors": "3.2.3", + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", "browser-stdout": "1.3.1", - "chokidar": "3.3.0", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", "growl": "1.10.5", "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "3.0.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.5", - "ms": "2.1.1", - "node-environment-flags": "1.0.6", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", "wide-align": "1.1.3", - "yargs": "13.3.2", - "yargs-parser": "13.1.2", - "yargs-unparser": "1.6.0" + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" }, "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "ms": "^2.1.1" + "color-convert": "^2.0.1" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -4520,79 +4094,58 @@ "path-is-absolute": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "argparse": "^2.0.1" } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "minimist": "^1.2.5" + "p-locate": "^5.0.0" } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "^3.0.2" } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" + "has-flag": "^4.0.0" } } } @@ -4626,12 +4179,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "mv": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", @@ -4648,6 +4195,12 @@ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4695,12 +4248,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "nise": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", @@ -4737,24 +4284,6 @@ "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", "optional": true }, - "node-environment-flags": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", - "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", @@ -4882,9 +4411,9 @@ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true }, "object-keys": { @@ -4894,60 +4423,26 @@ "dev": true }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.entries": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", - "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5", - "has": "^1.0.3" - } - }, - "object.fromentries": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", - "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "on-finished": { @@ -4980,17 +4475,17 @@ } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "os-homedir": { @@ -5013,18 +4508,17 @@ } }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" @@ -5042,7 +4536,7 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true } } @@ -5055,11 +4549,6 @@ "aggregate-error": "^3.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5075,12 +4564,13 @@ "integrity": "sha512-KbAJuYGUhZkB9gotDiKLnZ7Z3VTacK3fgwmDdB6ZVDtJbMBT6MfLga0WJaYpPDu0mzqT0NgHtHDt5PY4l0nidg==" }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parse-ms": { @@ -5104,16 +4594,10 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", - "dev": true - }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { @@ -5127,18 +4611,18 @@ "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "pify": "^2.0.0" + "pify": "^3.0.0" }, "dependencies": { "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } @@ -5155,9 +4639,9 @@ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pify": { @@ -5168,7 +4652,16 @@ "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha512-ojakdnUgL5pzJYWw2AIDEupaQCX5OPbM688ZevubICjdIX01PRSYKqm33fJoCOJBRseYCTUlQRnBNX+Pchaejw==", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, "requires": { "find-up": "^2.1.0" @@ -5191,14 +4684,6 @@ "split": "^1.0.1" }, "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -5207,587 +4692,17 @@ } }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true }, - "prettier-eslint": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-9.0.1.tgz", - "integrity": "sha512-KZT65QTosSAqBBqmrC+RpXbsMRe7Os2YSR9cAfFbDlyPAopzA/S5bioiZ3rpziNQNSJaOxmtXSx07EQ+o2Dlug==", - "dev": true, - "requires": { - "@typescript-eslint/parser": "^1.10.2", - "common-tags": "^1.4.0", - "core-js": "^3.1.4", - "dlv": "^1.1.0", - "eslint": "^5.0.0", - "indent-string": "^4.0.0", - "lodash.merge": "^4.6.0", - "loglevel-colored-level-prefix": "^1.0.0", - "prettier": "^1.7.0", - "pretty-format": "^23.0.1", - "require-relative": "^0.8.7", - "typescript": "^3.2.1", - "vue-eslint-parser": "^2.0.2" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - } - } - }, - "prettier-eslint-cli": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-5.0.0.tgz", - "integrity": "sha512-cei9UbN1aTrz3sQs88CWpvY/10PYTevzd76zoG1tdJ164OhmNTFRKPTOZrutVvscoQWzbnLKkviS3gu5JXwvZg==", - "dev": true, - "requires": { - "arrify": "^2.0.1", - "boolify": "^1.0.0", - "camelcase-keys": "^6.0.0", - "chalk": "^2.4.2", - "common-tags": "^1.8.0", - "core-js": "^3.1.4", - "eslint": "^5.0.0", - "find-up": "^4.1.0", - "get-stdin": "^7.0.0", - "glob": "^7.1.4", - "ignore": "^5.1.2", - "lodash.memoize": "^4.1.2", - "loglevel-colored-level-prefix": "^1.0.0", - "messageformat": "^2.2.1", - "prettier-eslint": "^9.0.0", - "rxjs": "^6.5.2", - "yargs": "^13.2.4" - }, - "dependencies": { - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", - "dev": true - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "dev": true - } - } - }, "prettier-linter-helpers": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", @@ -5797,24 +4712,6 @@ "fast-diff": "^1.1.2" } }, - "pretty-format": { - "version": "23.6.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", - "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0", - "ansi-styles": "^3.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha512-wFUFA5bg5dviipbQQ32yOQhl6gcJaJXiHE7dvR8VYPG97+J/GNC5FKGepKdEDUFeXRzDxPF1X/Btc8L+v7oqIQ==", - "dev": true - } - } - }, "pretty-ms": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", @@ -5842,17 +4739,6 @@ "tdigest": "^0.1.1" } }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, "protobufjs": { "version": "6.10.1", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.1.tgz", @@ -5944,17 +4830,20 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "ramda": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", "dev": true }, - "ramda": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.0.tgz", - "integrity": "sha512-pVzZdDpWwWqEVVLshWUHjNwuVP7SfcmPraYuqocJp1yo2U1R7P+5QAfDhdItkuoGqIBnBYrtPp7rEPqDn9HlZA==", - "dev": true + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } }, "range-parser": { "version": "1.2.1", @@ -6019,31 +4908,25 @@ } } }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { - "load-json-file": "^2.0.0", + "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "path-type": "^3.0.0" } }, "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "read-pkg": "^3.0.0" } }, "readable-stream": { @@ -6071,34 +4954,18 @@ } }, "readdirp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", - "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "requires": { - "picomatch": "^2.0.4" - } - }, - "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "picomatch": "^2.2.1" } }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "request": { @@ -6141,6 +5008,12 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-in-the-middle": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", @@ -6181,18 +5054,6 @@ "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "require-relative": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/require-relative/-/require-relative-0.8.7.tgz", - "integrity": "sha512-AKGr4qvHiryxRb19m3PsLRGuKVAbJLUD7E6eOaHkfKhwc+vSgVOCY5xNvm9EkolBKTOf0GrQAZKLimOCz81Khg==", - "dev": true - }, "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", @@ -6216,16 +5077,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "retry-request": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz", @@ -6259,24 +5110,6 @@ "glob": "^6.0.1" } }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha512-Fx+QT3fGtS0jk8OvKyKgAB2YHPsrmqBRcMeTC5AZ+lp4vzXKPPrFSY3iLdgvjA3HVBkIvJeM6J80LRjx8bQwhA==", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -6354,6 +5187,15 @@ } } }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, "serve-static": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", @@ -6376,18 +5218,18 @@ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shimmer": { @@ -6395,16 +5237,6 @@ "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" }, - "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", - "dev": true, - "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" - } - }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", @@ -6455,20 +5287,20 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true } } @@ -6511,9 +5343,9 @@ } }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -6521,15 +5353,15 @@ } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -6537,9 +5369,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.9.tgz", + "integrity": "sha512-Ki212dKK4ogX+xDo4CtOZBVIwhsKBEfsEEcwmJfLQzirgc2jIWdzg40Unxz/HzEUqM1WFzVlQSMF9kZZ2HboLQ==", "dev": true }, "split": { @@ -6612,59 +5444,34 @@ "integrity": "sha512-zDgl+muIlWzXNsXeyUfOk9dChMjlpkq0DRsxujtYPgyJ676yQ8jEm6zzaaWHFDg5BNcLuif0eD2MTyJdZqXpdg==" }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "string.prototype.matchall": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", - "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "has-symbols": "^1.0.1", - "internal-slot": "^1.0.2", - "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.2" } }, "string.prototype.trimend": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", - "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "string.prototype.trimstart": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", - "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "string_decoder": { @@ -6683,32 +5490,24 @@ } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } + "ansi-regex": "^5.0.0" } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "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": { @@ -6717,66 +5516,37 @@ "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=" }, "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { "ajv": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", - "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.1.tgz", + "integrity": "sha512-42VLtQUOLefAvKFAQIxIZDaThq6om/PrfP0CYk3/vn+y4BMNkKnbli8ON2QCiHov4KkzOSJ/xSoBJdayiiYvVQ==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } } } }, @@ -6854,21 +5624,6 @@ "yaassertion": "^1.0.0" } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, "to-no-case": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz", @@ -6921,23 +5676,16 @@ } }, "tsconfig-paths": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", - "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", "dev": true, "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^2.2.0", "minimist": "^1.2.0", "strip-bom": "^3.0.0" } }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -6952,12 +5700,12 @@ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -6967,9 +5715,9 @@ "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==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "type-is": { @@ -6994,11 +5742,25 @@ "is-typedarray": "^1.0.0" } }, - "typescript": { - "version": "3.7.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", - "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", - "dev": true + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + } + } }, "underscore": { "version": "1.12.1", @@ -7058,9 +5820,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.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "validate-npm-package-license": { @@ -7088,99 +5850,32 @@ "extsprintf": "^1.2.0" } }, - "vue-eslint-parser": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz", - "integrity": "sha512-ZezcU71Owm84xVF6gfurBQUGg8WQ+WZGxgDEQu1IHFBZNx7BFZg3L1yHxrCBNNwbwFtE1GuvfJKMtb6Xuwc/Bw==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "eslint-scope": "^3.7.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^3.5.2", - "esquery": "^1.0.0", - "lodash": "^4.17.4" - }, - "dependencies": { - "acorn": { - "version": "5.7.4", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", - "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", - "dev": true, - "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", - "dev": true - } - } - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", - "dev": true, - "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, "walkdir": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } }, "wide-align": { "version": "1.1.3", @@ -7225,40 +5920,20 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, "wrappy": { @@ -7266,15 +5941,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -7311,9 +5977,9 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yaassertion": { @@ -7327,95 +5993,36 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" - }, - "dependencies": { - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - } + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true }, "yargs-unparser": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", - "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.15", - "yargs": "^13.3.0" + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" } }, "yn": { diff --git a/services/docstore/package.json b/services/docstore/package.json index 5ebda01024..53b36cd868 100644 --- a/services/docstore/package.json +++ b/services/docstore/package.json @@ -14,9 +14,10 @@ "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 --max-warnings 0 .", - "format": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --list-different", - "format:fix": "node_modules/.bin/prettier-eslint $PWD'/**/*.js' --write" + "lint": "eslint --max-warnings 0 --format unix .", + "format": "prettier --list-different $PWD/'**/*.js'", + "format:fix": "prettier --write $PWD/'**/*.js'", + "lint:fix": "eslint --fix ." }, "dependencies": { "@overleaf/metrics": "^3.5.1", @@ -37,27 +38,20 @@ }, "devDependencies": { "@google-cloud/storage": "^5.1.2", - "babel-eslint": "^10.1.0", - "chai": "~4.2.0", + "chai": "^4.2.0", "chai-as-promised": "^7.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.5.0", - "eslint-plugin-import": "^2.20.1", - "eslint-plugin-jsx-a11y": "^6.3.1", - "eslint-plugin-mocha": "^6.3.0", - "eslint-plugin-node": "^11.0.0", + "eslint": "^7.21.0", + "eslint-config-prettier": "^8.1.0", + "eslint-config-standard": "^16.0.2", + "eslint-plugin-chai-expect": "^2.2.0", + "eslint-plugin-chai-friendly": "^0.6.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-mocha": "^8.0.0", + "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^3.1.2", "eslint-plugin-promise": "^4.2.1", - "eslint-plugin-react": "^7.20.3", - "eslint-plugin-standard": "^4.0.1", - "mocha": "^7.2.0", - "prettier": "^2.0.0", - "prettier-eslint-cli": "^5.0.0", + "mocha": "^8.3.2", + "prettier": "^2.2.1", "sandboxed-module": "~2.0.4", "sinon": "~9.0.2", "sinon-chai": "^3.5.0" From 540b52c128bafd38f8d4f820a507c2099b340bd1 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 13 Jul 2021 12:04:48 +0100 Subject: [PATCH 334/349] [misc] run format_fix and lint:fix --- services/docstore/app.js | 8 +- services/docstore/app/js/DocArchiveManager.js | 28 ++--- services/docstore/app/js/DocManager.js | 103 ++++++++++-------- services/docstore/app/js/Errors.js | 2 +- services/docstore/app/js/HealthChecker.js | 10 +- services/docstore/app/js/HttpController.js | 29 ++--- services/docstore/app/js/MongoManager.js | 46 ++++---- services/docstore/app/js/RangeManager.js | 2 +- services/docstore/app/js/mongodb.js | 2 +- services/docstore/config/settings.defaults.js | 22 ++-- .../test/acceptance/js/ArchiveDocsTests.js | 85 ++++++++------- .../test/acceptance/js/DeletingDocsTests.js | 14 +-- .../test/acceptance/js/GettingAllDocsTests.js | 22 ++-- .../test/acceptance/js/GettingDocsTests.js | 12 +- .../test/acceptance/js/UpdatingDocsTests.js | 18 +-- .../test/acceptance/js/helpers/DocstoreApp.js | 30 +++-- .../acceptance/js/helpers/DocstoreClient.js | 28 ++--- services/docstore/test/setup.js | 10 +- .../test/unit/js/DocArchiveManagerTests.js | 64 +++++------ .../docstore/test/unit/js/DocManagerTests.js | 50 ++++----- .../test/unit/js/HttpControllerTests.js | 70 ++++++------ .../test/unit/js/MongoManagerTests.js | 48 ++++---- .../test/unit/js/RangeManagerTests.js | 78 ++++++------- 23 files changed, 394 insertions(+), 387 deletions(-) diff --git a/services/docstore/app.js b/services/docstore/app.js index e31775e943..7cb774b9f8 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -13,7 +13,7 @@ const bodyParser = require('body-parser') const { celebrate: validate, Joi, - errors: handleValidationErrors + errors: handleValidationErrors, } = require('celebrate') const mongodb = require('./app/js/mongodb') const Errors = require('./app/js/Errors') @@ -67,8 +67,8 @@ app.patch( body: { deleted: Joi.boolean(), name: Joi.string().when('deleted', { is: true, then: Joi.required() }), - deletedAt: Joi.date().when('deleted', { is: true, then: Joi.required() }) - } + deletedAt: Joi.date().when('deleted', { is: true, then: Joi.required() }), + }, }), HttpController.patchDoc ) @@ -111,7 +111,7 @@ if (!module.parent) { return logger.info(`Docstore starting up, listening on ${host}:${port}`) }) }) - .catch((err) => { + .catch(err => { logger.fatal({ err }, 'Cannot connect to mongo. Exiting.') process.exit(1) }) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index 807ae8b3d7..dcd713eb62 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -30,8 +30,8 @@ module.exports = { unArchiveAllDocs, unarchiveDoc, destroyAllDocs, - destroyDoc - } + destroyDoc, + }, } async function archiveAllDocs(projectId) { @@ -44,8 +44,8 @@ async function archiveAllDocs(projectId) { break } - await pMap(docs, (doc) => archiveDoc(projectId, doc), { - concurrency: PARALLEL_JOBS + await pMap(docs, doc => archiveDoc(projectId, doc), { + concurrency: PARALLEL_JOBS, }) } } @@ -55,7 +55,7 @@ async function archiveDocById(projectId, docId) { lines: true, ranges: true, rev: true, - inS3: true + inS3: true, }) if (!doc) { @@ -83,7 +83,7 @@ async function archiveDoc(projectId, doc) { const json = JSON.stringify({ lines: doc.lines, ranges: doc.ranges, - schema_v: 1 + schema_v: 1, }) // this should never happen, but protects against memory-corruption errors that @@ -97,7 +97,7 @@ async function archiveDoc(projectId, doc) { const md5 = crypto.createHash('md5').update(json).digest('hex') const stream = Streamifier.createReadStream(json) await PersistorManager.sendStream(settings.docstore.bucket, key, stream, { - sourceMd5: md5 + sourceMd5: md5, }) await MongoManager.markDocAsArchived(doc._id, doc.rev) } @@ -119,8 +119,8 @@ async function unArchiveAllDocs(projectId) { if (!docs || docs.length === 0) { break } - await pMap(docs, (doc) => unarchiveDoc(projectId, doc._id), { - concurrency: PARALLEL_JOBS + await pMap(docs, doc => unarchiveDoc(projectId, doc._id), { + concurrency: PARALLEL_JOBS, }) } } @@ -164,7 +164,7 @@ async function unarchiveDoc(projectId, docId) { throw new Errors.Md5MismatchError('md5 mismatch when downloading doc', { key, sourceMd5, - md5 + md5, }) } @@ -195,8 +195,8 @@ async function destroyAllDocs(projectId) { if (!docs || docs.length === 0) { break } - await pMap(docs, (doc) => destroyDoc(projectId, doc._id), { - concurrency: PARALLEL_JOBS + await pMap(docs, doc => destroyDoc(projectId, doc._id), { + concurrency: PARALLEL_JOBS, }) } } @@ -207,7 +207,7 @@ async function destroyDoc(projectId, docId) { 'removing doc from mongo and persistor' ) const doc = await MongoManager.findDoc(projectId, docId, { - inS3: 1 + inS3: 1, }) if (!doc) { throw new Errors.NotFoundError('Doc not found in Mongo') @@ -243,7 +243,7 @@ async function destroyArchiveWithRetry(projectId, docId) { async function _streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { - stream.on('data', (chunk) => chunks.push(chunk)) + stream.on('data', chunk => chunks.push(chunk)) stream.on('error', reject) stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))) }) diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 2951377743..0f00ce79cf 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -38,58 +38,67 @@ module.exports = DocManager = { return callback('must include inS3 when getting doc') } - return MongoManager.findDoc(project_id, doc_id, filter, function ( - err, - doc - ) { - if (err != null) { - return callback(err) - } else if (doc == null) { - return callback( - new Errors.NotFoundError( - `No such doc: ${doc_id} in project ${project_id}` + return MongoManager.findDoc( + project_id, + doc_id, + filter, + function (err, doc) { + if (err != null) { + return callback(err) + } else if (doc == null) { + return callback( + new Errors.NotFoundError( + `No such doc: ${doc_id} in project ${project_id}` + ) ) - ) - } else if (doc != null ? doc.inS3 : undefined) { - return DocArchive.unarchiveDoc(project_id, doc_id, function (err) { - if (err != null) { - logger.err({ err, project_id, doc_id }, 'error unarchiving doc') - return callback(err) - } - return DocManager._getDoc(project_id, doc_id, filter, callback) - }) - } else { - if (filter.version) { - return MongoManager.getDocVersion(doc_id, function (error, version) { - if (error != null) { - return callback(error) + } else if (doc != null ? doc.inS3 : undefined) { + return DocArchive.unarchiveDoc(project_id, doc_id, function (err) { + if (err != null) { + logger.err({ err, project_id, doc_id }, 'error unarchiving doc') + return callback(err) } - doc.version = version - return callback(err, doc) + return DocManager._getDoc(project_id, doc_id, filter, callback) }) } else { - return callback(err, doc) + if (filter.version) { + return MongoManager.getDocVersion( + doc_id, + function (error, version) { + if (error != null) { + return callback(error) + } + doc.version = version + return callback(err, doc) + } + ) + } else { + return callback(err, doc) + } } } - }) + ) }, isDocDeleted(projectId, docId, callback) { - MongoManager.findDoc(projectId, docId, { deleted: true }, function ( - err, - doc - ) { - if (err) { - return callback(err) + MongoManager.findDoc( + projectId, + docId, + { deleted: true }, + function (err, doc) { + if (err) { + return callback(err) + } + if (!doc) { + return callback( + new Errors.NotFoundError( + `No such project/doc: ${projectId}/${docId}` + ) + ) + } + // `doc.deleted` is `undefined` for non deleted docs + callback(null, Boolean(doc.deleted)) } - if (!doc) { - return callback( - new Errors.NotFoundError(`No such project/doc: ${projectId}/${docId}`) - ) - } - // `doc.deleted` is `undefined` for non deleted docs - callback(null, Boolean(doc.deleted)) - }) + ) }, getFullDoc(project_id, doc_id, callback) { @@ -105,7 +114,7 @@ module.exports = DocManager = { deleted: true, version: true, ranges: true, - inS3: true + inS3: true, }, function (err, doc) { if (err != null) { @@ -181,7 +190,7 @@ module.exports = DocManager = { lines: true, version: true, ranges: true, - inS3: true + inS3: true, }, function (err, doc) { let updateLines, updateRanges, updateVersion @@ -244,7 +253,7 @@ module.exports = DocManager = { project_id, doc_id, oldVersion: doc != null ? doc.version : undefined, - newVersion: version + newVersion: version, }, 'updating doc version' ) @@ -290,7 +299,7 @@ module.exports = DocManager = { if (meta.deleted && Settings.docstore.archiveOnSoftDelete) { // The user will not read this doc anytime soon. Flush it out of mongo. - DocArchive.archiveDocById(project_id, doc_id, (err) => { + DocArchive.archiveDocById(project_id, doc_id, err => { if (err) { logger.warn( { project_id, doc_id, err }, @@ -302,5 +311,5 @@ module.exports = DocManager = { MongoManager.patchDoc(project_id, doc_id, meta, callback) }) - } + }, } diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index 6a74485494..4eaa5481d3 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -6,5 +6,5 @@ class Md5MismatchError extends OError {} module.exports = { Md5MismatchError, - ...Errors + ...Errors, } diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 30d82ee8a3..3271c40164 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -26,11 +26,11 @@ module.exports = { const url = `http://localhost:${port}/project/${project_id}/doc/${doc_id}` const lines = [ 'smoke test - delete me', - `${crypto.randomBytes(32).toString('hex')}` + `${crypto.randomBytes(32).toString('hex')}`, ] const getOpts = () => ({ url, - timeout: 3000 + timeout: 3000, }) logger.log({ lines, url, doc_id, project_id }, 'running health check') const jobs = [ @@ -60,9 +60,9 @@ module.exports = { } }) }, - (cb) => db.docs.deleteOne({ _id: doc_id, project_id }, cb), - (cb) => db.docOps.deleteOne({ doc_id }, cb) + cb => db.docs.deleteOne({ _id: doc_id, project_id }, cb), + cb => db.docOps.deleteOne({ doc_id }, cb), ] return async.series(jobs, callback) - } + }, } diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 593dcc6a2f..f53c9068bc 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -98,19 +98,20 @@ module.exports = HttpController = { getAllDeletedDocs(req, res, next) { const { project_id } = req.params logger.log({ project_id }, 'getting all deleted docs') - DocManager.getAllDeletedDocs(project_id, { name: true }, function ( - error, - docs - ) { - if (error) { - return next(error) + DocManager.getAllDeletedDocs( + project_id, + { name: true }, + function (error, docs) { + if (error) { + return next(error) + } + res.json( + docs.map(doc => { + return { _id: doc._id.toString(), name: doc.name } + }) + ) } - res.json( - docs.map((doc) => { - return { _id: doc._id.toString(), name: doc.name } - }) - ) - }) + ) }, getAllRanges(req, res, next) { @@ -185,7 +186,7 @@ module.exports = HttpController = { } return res.json({ modified, - rev + rev, }) } ) @@ -304,5 +305,5 @@ module.exports = HttpController = { return res.sendStatus(200) } }) - } + }, } diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 4e3f71eac8..5434db581d 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -25,10 +25,10 @@ module.exports = MongoManager = { db.docs.findOne( { _id: ObjectId(doc_id.toString()), - project_id: ObjectId(project_id.toString()) + project_id: ObjectId(project_id.toString()), }, { - projection: filter + projection: filter, }, callback ) @@ -39,12 +39,12 @@ module.exports = MongoManager = { .find( { project_id: ObjectId(project_id.toString()), - deleted: true + deleted: true, }, { projection: filter, sort: { deletedAt: -1 }, - limit: Settings.max_deleted_docs + limit: Settings.max_deleted_docs, } ) .toArray(callback) @@ -56,7 +56,7 @@ module.exports = MongoManager = { query.deleted = { $ne: true } } const queryOptions = { - projection: filter + projection: filter, } if (options.limit) { queryOptions.limit = options.limit @@ -67,7 +67,7 @@ module.exports = MongoManager = { getArchivedProjectDocs(project_id, maxResults, callback) { const query = { project_id: ObjectId(project_id.toString()), - inS3: true + inS3: true, } db.docs .find(query, { projection: { _id: 1 }, limit: maxResults }) @@ -77,7 +77,7 @@ module.exports = MongoManager = { getNonArchivedProjectDocs(project_id, maxResults, callback) { const query = { project_id: ObjectId(project_id.toString()), - inS3: { $ne: true } + inS3: { $ne: true }, } db.docs.find(query, { limit: maxResults }).toArray(callback) }, @@ -86,7 +86,7 @@ module.exports = MongoManager = { const query = { project_id: ObjectId(project_id.toString()), deleted: { $ne: true }, - inS3: true + inS3: true, } db.docs .find(query, { projection: { _id: 1 }, limit: maxResults }) @@ -97,11 +97,11 @@ module.exports = MongoManager = { const update = { $set: updates, $inc: { - rev: 1 + rev: 1, }, $unset: { - inS3: true - } + inS3: true, + }, } update.$set.project_id = ObjectId(project_id) db.docs.updateOne( @@ -116,7 +116,7 @@ module.exports = MongoManager = { db.docs.updateOne( { _id: ObjectId(doc_id), - project_id: ObjectId(project_id) + project_id: ObjectId(project_id), }, { $set: meta }, callback @@ -126,14 +126,14 @@ module.exports = MongoManager = { markDocAsArchived(doc_id, rev, callback) { const update = { $set: {}, - $unset: {} + $unset: {}, } update.$set.inS3 = true update.$unset.lines = true update.$unset.ranges = true const query = { _id: doc_id, - rev + rev, } db.docs.updateOne(query, update, callback) }, @@ -144,12 +144,12 @@ module.exports = MongoManager = { } db.docOps.findOne( { - doc_id: ObjectId(doc_id) + doc_id: ObjectId(doc_id), }, { projection: { - version: 1 - } + version: 1, + }, }, function (error, doc) { if (error != null) { @@ -166,13 +166,13 @@ module.exports = MongoManager = { } db.docOps.updateOne( { - doc_id: ObjectId(doc_id) + doc_id: ObjectId(doc_id), }, { - $set: { version } + $set: { version }, }, { - upsert: true + upsert: true, }, callback ) @@ -181,7 +181,7 @@ module.exports = MongoManager = { destroyDoc(doc_id, callback) { db.docs.deleteOne( { - _id: ObjectId(doc_id) + _id: ObjectId(doc_id), }, function (err) { if (err != null) { @@ -189,13 +189,13 @@ module.exports = MongoManager = { } db.docOps.deleteOne( { - doc_id: ObjectId(doc_id) + doc_id: ObjectId(doc_id), }, callback ) } ) - } + }, } const methods = Object.getOwnPropertyNames(MongoManager) diff --git a/services/docstore/app/js/RangeManager.js b/services/docstore/app/js/RangeManager.js index fd719e5b15..78ef59abd3 100644 --- a/services/docstore/app/js/RangeManager.js +++ b/services/docstore/app/js/RangeManager.js @@ -65,5 +65,5 @@ module.exports = RangeManager = { } catch (error) { return data } - } + }, } diff --git a/services/docstore/app/js/mongodb.js b/services/docstore/app/js/mongodb.js index 245f7ed8f7..b49eb7b80b 100644 --- a/services/docstore/app/js/mongodb.js +++ b/services/docstore/app/js/mongodb.js @@ -32,5 +32,5 @@ module.exports = { db, ObjectId, addCollection, - waitForDb + waitForDb, } diff --git a/services/docstore/config/settings.defaults.js b/services/docstore/config/settings.defaults.js index 0f1c1ab42b..391739368e 100644 --- a/services/docstore/config/settings.defaults.js +++ b/services/docstore/config/settings.defaults.js @@ -5,15 +5,15 @@ const Settings = { internal: { docstore: { port: 3016, - host: process.env.LISTEN_ADDRESS || 'localhost' - } + host: process.env.LISTEN_ADDRESS || 'localhost', + }, }, mongo: { options: { useUnifiedTopology: - (process.env.MONGO_USE_UNIFIED_TOPOLOGY || 'true') === 'true' - } + (process.env.MONGO_USE_UNIFIED_TOPOLOGY || 'true') === 'true', + }, }, docstore: { @@ -23,14 +23,14 @@ const Settings = { backend: process.env.BACKEND || 's3', healthCheck: { - project_id: process.env.HEALTH_CHECK_PROJECT_ID + project_id: process.env.HEALTH_CHECK_PROJECT_ID, }, bucket: process.env.BUCKET_NAME || process.env.AWS_BUCKET || 'bucket', gcs: { unlockBeforeDelete: process.env.GCS_UNLOCK_BEFORE_DELETE === 'true', deletedBucketSuffix: process.env.GCS_DELETED_BUCKET_SUFFIX, - deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50 - } + deleteConcurrency: parseInt(process.env.GCS_DELETE_CONCURRENCY) || 50, + }, }, max_deleted_docs: parseInt(process.env.MAX_DELETED_DOCS, 10) || 2000, @@ -41,7 +41,7 @@ const Settings = { unArchiveBatchSize: parseInt(process.env.UN_ARCHIVE_BATCH_SIZE, 10) || 50, destroyBatchSize: parseInt(process.env.DESTROY_BATCH_SIZE, 10) || 2000, destroyRetryCount: parseInt(process.env.DESTROY_RETRY_COUNT || '3', 10), - parallelArchiveJobs: parseInt(process.env.PARALLEL_ARCHIVE_JOBS, 10) || 5 + parallelArchiveJobs: parseInt(process.env.PARALLEL_ARCHIVE_JOBS, 10) || 5, } if (process.env.MONGO_CONNECTION_STRING) { @@ -63,7 +63,7 @@ if ( bucket: process.env.AWS_BUCKET, endpoint: process.env.AWS_S3_ENDPOINT, pathStyle: process.env.AWS_S3_PATH_STYLE, - partSize: parseInt(process.env.AWS_S3_PARTSIZE) || 100 * 1024 * 1024 + partSize: parseInt(process.env.AWS_S3_PARTSIZE) || 100 * 1024 * 1024, } } @@ -71,7 +71,7 @@ if (process.env.GCS_API_ENDPOINT) { Settings.docstore.gcs.endpoint = { apiEndpoint: process.env.GCS_API_ENDPOINT, apiScheme: process.env.GCS_API_SCHEME, - projectId: process.env.GCS_PROJECT_ID + projectId: process.env.GCS_PROJECT_ID, } } @@ -81,7 +81,7 @@ if (process.env.FALLBACK_BACKEND) { // mapping of bucket names on the fallback, to bucket names on the primary. // e.g. { myS3UserFilesBucketName: 'myGoogleUserFilesBucketName' } buckets: JSON.parse(process.env.FALLBACK_BUCKET_MAPPING || '{}'), - copyOnMiss: process.env.COPY_ON_MISS === 'true' + copyOnMiss: process.env.COPY_ON_MISS === 'true', } } diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 2a4948ba5d..2dc02152d9 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -49,18 +49,18 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: {}, - version: 2 + version: 2, }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], ranges: {}, - version: 4 - } + version: 4, + }, ] - const jobs = Array.from(this.docs).map((doc) => - ((doc) => { - return (callback) => { + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { return DocstoreClient.createDoc( this.project_id, doc._id, @@ -73,7 +73,7 @@ describe('Archiving', function () { })(doc) ) - return async.series(jobs, (error) => { + return async.series(jobs, error => { if (error != null) { throw error } @@ -90,9 +90,9 @@ describe('Archiving', function () { }) it('should set inS3 and unset lines and ranges in each doc', function (done) { - const jobs = Array.from(this.docs).map((doc) => - ((doc) => { - return (callback) => { + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { return db.docs.findOne({ _id: doc._id }, (error, doc) => { expect(doc.lines).not.to.exist expect(doc.ranges).not.to.exist @@ -106,9 +106,9 @@ describe('Archiving', function () { }) it('should set the docs in s3 correctly', function (done) { - const jobs = Array.from(this.docs).map((doc) => - ((doc) => { - return (callback) => { + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { return DocstoreClient.getS3Doc( this.project_id, doc._id, @@ -149,7 +149,7 @@ describe('Archiving', function () { return it('should restore the docs to mongo', function (done) { const jobs = Array.from(this.docs).map((doc, i) => ((doc, i) => { - return (callback) => { + return callback => { return db.docs.findOne({ _id: doc._id }, (error, doc) => { doc.lines.should.deep.equal(this.docs[i].lines) doc.ranges.should.deep.equal(this.docs[i].ranges) @@ -171,7 +171,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -179,14 +179,14 @@ describe('Archiving', function () { this.doc.lines, this.doc.version, this.doc.ranges, - (error) => { + error => { if (error != null) { throw error } return DocstoreClient.deleteDoc( this.project_id, this.doc._id, - (error) => { + error => { if (error != null) { throw error } @@ -280,7 +280,8 @@ describe('Archiving', function () { Settings.docstore.keepSoftDeletedDocsArchived = true }) afterEach(function restoreSetting() { - Settings.docstore.keepSoftDeletedDocsArchived = keepSoftDeletedDocsArchived + Settings.docstore.keepSoftDeletedDocsArchived = + keepSoftDeletedDocsArchived }) describe('after unarchiving from a request for the project', function () { @@ -326,7 +327,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['foo', 'bar'], ranges: {}, - version: 2 + version: 2, } DocstoreClient.createDoc( this.project_id, @@ -334,7 +335,7 @@ describe('Archiving', function () { this.doc.lines, this.doc.version, this.doc.ranges, - (error) => { + error => { if (error) { return done(error) } @@ -398,7 +399,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: [big_line, big_line, big_line, big_line], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -406,7 +407,7 @@ describe('Archiving', function () { this.doc.lines, this.doc.version, this.doc.ranges, - (error) => { + error => { if (error != null) { throw error } @@ -869,10 +870,10 @@ describe('Archiving', function () { 'Roses are \u001b[0;31mred\u001b[0m, violets are \u001b[0;34mblue. Hope you enjoy terminal hue', 'But now...\u001b[20Cfor my greatest trick...\u001b[8m', 'The quic\b\b\b\b\b\bk brown fo\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007\u0007x... [Beeeep]', - 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗' + 'Powerلُلُصّبُلُلصّبُررً ॣ ॣh ॣ ॣ冗', ], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -880,7 +881,7 @@ describe('Archiving', function () { this.doc.lines, this.doc.version, this.doc.ranges, - (error) => { + error => { if (error != null) { throw error } @@ -968,17 +969,17 @@ describe('Archiving', function () { op: { i: 'foo', p: 24 }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-27T16:10:44.194Z') - } + ts: new Date('2017-01-27T16:10:44.194Z'), + }, }, { id: ObjectId(), op: { d: 'bar', p: 50 }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-27T18:10:44.194Z') - } - } + ts: new Date('2017-01-27T18:10:44.194Z'), + }, + }, ], comments: [ { @@ -986,12 +987,12 @@ describe('Archiving', function () { op: { c: 'comment', p: 284, t: ObjectId() }, metadata: { user_id: ObjectId(), - ts: new Date('2017-01-26T14:22:04.869Z') - } - } - ] + ts: new Date('2017-01-26T14:22:04.869Z'), + }, + }, + ], }, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -999,7 +1000,7 @@ describe('Archiving', function () { this.doc.lines, this.doc.version, this.doc.ranges, - (error) => { + error => { if (error != null) { throw error } @@ -1082,7 +1083,7 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['abc', 'def', 'ghi'], ranges: {}, - version: 2 + version: 2, } return DocstoreClient.createDoc( this.project_id, @@ -1090,7 +1091,7 @@ describe('Archiving', function () { this.doc.lines, this.doc.version, this.doc.ranges, - (error) => { + error => { if (error != null) { throw error } @@ -1178,21 +1179,21 @@ describe('Archiving', function () { _id: ObjectId(), lines: ['abc', 'def', 'ghi'], ranges: {}, - version: 2 + version: 2, } uploadContent( `${this.project_id}/${this.doc._id}`, this.doc.lines, - (error) => { + error => { expect(error).not.to.exist db.docs.insert( { project_id: this.project_id, _id: this.doc._id, rev: this.doc.version, - inS3: true + inS3: true, }, - (error) => { + error => { if (error != null) { throw error } diff --git a/services/docstore/test/acceptance/js/DeletingDocsTests.js b/services/docstore/test/acceptance/js/DeletingDocsTests.js index bc38f3fad8..4e9e987958 100644 --- a/services/docstore/test/acceptance/js/DeletingDocsTests.js +++ b/services/docstore/test/acceptance/js/DeletingDocsTests.js @@ -33,7 +33,7 @@ function deleteTestSuite(deleteDoc) { this.lines, this.version, this.ranges, - (error) => { + error => { if (error != null) { throw error } @@ -92,7 +92,7 @@ function deleteTestSuite(deleteDoc) { it('should not export the doc to s3', function (done) { setTimeout(() => { - DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error) => { + DocstoreClient.getS3Doc(this.project_id, this.doc_id, error => { expect(error).to.be.instanceOf(Errors.NotFoundError) done() }) @@ -311,7 +311,7 @@ describe('Delete via PATCH', function () { (error, deletedDocs) => { if (error) return done(error) expect(deletedDocs).to.deep.equal([ - { _id: this.doc_id.toString(), name: 'main.tex' } + { _id: this.doc_id.toString(), name: 'main.tex' }, ]) done() } @@ -366,7 +366,7 @@ describe('Delete via PATCH', function () { expect(deletedDocs).to.deep.equal([ { _id: this.doc_id3.toString(), name: 'three.tex' }, { _id: this.doc_id2.toString(), name: 'two.tex' }, - { _id: this.doc_id.toString(), name: 'main.tex' } + { _id: this.doc_id.toString(), name: 'main.tex' }, ]) done() } @@ -391,7 +391,7 @@ describe('Delete via PATCH', function () { expect(deletedDocs).to.deep.equal([ { _id: this.doc_id3.toString(), name: 'three.tex' }, - { _id: this.doc_id2.toString(), name: 'two.tex' } + { _id: this.doc_id2.toString(), name: 'two.tex' }, // dropped main.tex ]) done() @@ -436,7 +436,7 @@ describe("Destroying a project's documents", function () { return describe('when the doc is archived', function () { beforeEach(function (done) { - return DocstoreClient.archiveAllDoc(this.project_id, (err) => { + return DocstoreClient.archiveAllDoc(this.project_id, err => { if (err != null) { return done(err) } @@ -461,7 +461,7 @@ describe("Destroying a project's documents", function () { }) return it('should remove the doc contents from s3', function (done) { - return DocstoreClient.getS3Doc(this.project_id, this.doc_id, (error) => { + return DocstoreClient.getS3Doc(this.project_id, this.doc_id, error => { expect(error).to.be.instanceOf(Errors.NotFoundError) done() }) diff --git a/services/docstore/test/acceptance/js/GettingAllDocsTests.js b/services/docstore/test/acceptance/js/GettingAllDocsTests.js index 2d38ca5fba..76b3d70b78 100644 --- a/services/docstore/test/acceptance/js/GettingAllDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingAllDocsTests.js @@ -26,31 +26,31 @@ describe('Getting all docs', function () { _id: ObjectId(), lines: ['one', 'two', 'three'], ranges: { mock: 'one' }, - rev: 2 + rev: 2, }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], ranges: { mock: 'two' }, - rev: 4 + rev: 4, }, { _id: ObjectId(), lines: ['111', '222', '333'], ranges: { mock: 'three' }, - rev: 6 - } + rev: 6, + }, ] this.deleted_doc = { _id: ObjectId(), lines: ['deleted'], ranges: { mock: 'four' }, - rev: 8 + rev: 8, } const version = 42 - const jobs = Array.from(this.docs).map((doc) => - ((doc) => { - return (callback) => { + const jobs = Array.from(this.docs).map(doc => + (doc => { + return callback => { return DocstoreClient.createDoc( this.project_id, doc._id, @@ -62,14 +62,14 @@ describe('Getting all docs', function () { } })(doc) ) - jobs.push((cb) => { + jobs.push(cb => { return DocstoreClient.createDoc( this.project_id, this.deleted_doc._id, this.deleted_doc.lines, version, this.deleted_doc.ranges, - (err) => { + err => { return DocstoreClient.deleteDoc( this.project_id, this.deleted_doc._id, @@ -78,7 +78,7 @@ describe('Getting all docs', function () { } ) }) - jobs.unshift((cb) => DocstoreApp.ensureRunning(cb)) + jobs.unshift(cb => DocstoreApp.ensureRunning(cb)) return async.series(jobs, done) }) diff --git a/services/docstore/test/acceptance/js/GettingDocsTests.js b/services/docstore/test/acceptance/js/GettingDocsTests.js index 7847abd84a..857e0cb3ae 100644 --- a/services/docstore/test/acceptance/js/GettingDocsTests.js +++ b/services/docstore/test/acceptance/js/GettingDocsTests.js @@ -30,10 +30,10 @@ describe('Getting a doc', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } return DocstoreApp.ensureRunning(() => { return DocstoreClient.createDoc( @@ -42,7 +42,7 @@ describe('Getting a doc', function () { this.lines, this.version, this.ranges, - (error) => { + error => { if (error != null) { throw error } @@ -92,7 +92,7 @@ describe('Getting a doc', function () { this.lines, this.version, this.ranges, - (error) => { + error => { if (error != null) { throw error } diff --git a/services/docstore/test/acceptance/js/UpdatingDocsTests.js b/services/docstore/test/acceptance/js/UpdatingDocsTests.js index 45d3cb9239..eda60ae1aa 100644 --- a/services/docstore/test/acceptance/js/UpdatingDocsTests.js +++ b/services/docstore/test/acceptance/js/UpdatingDocsTests.js @@ -29,10 +29,10 @@ describe('Applying updates to a doc', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.newRanges = { changes: [ @@ -41,10 +41,10 @@ describe('Applying updates to a doc', function () { op: { i: 'bar', p: 6 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.version = 42 return DocstoreApp.ensureRunning(() => { @@ -54,7 +54,7 @@ describe('Applying updates to a doc', function () { this.originalLines, this.version, this.originalRanges, - (error) => { + error => { if (error != null) { throw error } diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index d541a8f454..4a45a7e6d6 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -32,23 +32,19 @@ module.exports = { this.initing = true this.callbacks.push(callback) waitForDb().then(() => { - return app.listen( - settings.internal.docstore.port, - 'localhost', - (error) => { - if (error != null) { - throw error - } - this.running = true - return (() => { - const result = [] - for (callback of Array.from(this.callbacks)) { - result.push(callback()) - } - return result - })() + return app.listen(settings.internal.docstore.port, 'localhost', error => { + if (error != null) { + throw error } - ) + this.running = true + return (() => { + const result = [] + for (callback of Array.from(this.callbacks)) { + result.push(callback()) + } + return result + })() + }) }) - } + }, } diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 49b50907bb..1164540bd3 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -19,7 +19,7 @@ const Persistor = require('../../../../app/js/PersistorManager') async function streamToString(stream) { const chunks = [] return new Promise((resolve, reject) => { - stream.on('data', (chunk) => chunks.push(chunk)) + stream.on('data', chunk => chunks.push(chunk)) stream.on('error', reject) stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))) }) @@ -54,7 +54,7 @@ module.exports = DocstoreClient = { { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, json: true, - qs + qs, }, callback ) @@ -64,7 +64,7 @@ module.exports = DocstoreClient = { request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/deleted`, - json: true + json: true, }, callback ) @@ -77,7 +77,7 @@ module.exports = DocstoreClient = { return request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, - json: true + json: true, }, (req, res, body) => { callback(req, res, body) @@ -89,7 +89,7 @@ module.exports = DocstoreClient = { request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc-deleted`, - json: true + json: true, }, (error, res, body) => { if (error) return callback(error) @@ -108,7 +108,7 @@ module.exports = DocstoreClient = { return request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, - json: true + json: true, }, callback ) @@ -124,8 +124,8 @@ module.exports = DocstoreClient = { json: { lines, version, - ranges - } + ranges, + }, }, callback ) @@ -165,7 +165,7 @@ module.exports = DocstoreClient = { request.patch( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, - json: { name, deleted: true, deletedAt } + json: { name, deleted: true, deletedAt }, }, callback ) @@ -177,7 +177,7 @@ module.exports = DocstoreClient = { } return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive` + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive`, }, callback ) @@ -189,7 +189,7 @@ module.exports = DocstoreClient = { } return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/archive` + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/archive`, }, callback ) @@ -201,7 +201,7 @@ module.exports = DocstoreClient = { } return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy` + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy`, }, callback ) @@ -213,9 +213,9 @@ module.exports = DocstoreClient = { settings.docstore.bucket, `${project_id}/${doc_id}` ) - .then((data) => { + .then(data => { callback(null, JSON.parse(data)) }) .catch(callback) - } + }, } diff --git a/services/docstore/test/setup.js b/services/docstore/test/setup.js index f738f1c70f..fbf29a495b 100644 --- a/services/docstore/test/setup.js +++ b/services/docstore/test/setup.js @@ -17,16 +17,16 @@ const stubs = { warn: sandbox.stub(), err: sandbox.stub(), error: sandbox.stub(), - fatal: sandbox.stub() - } + fatal: sandbox.stub(), + }, } // SandboxedModule configuration SandboxedModule.configure({ requires: { - 'logger-sharelatex': stubs.logger + 'logger-sharelatex': stubs.logger, }, - globals: { Buffer, JSON, console, process } + globals: { Buffer, JSON, console, process }, }) exports.mochaHooks = { @@ -36,5 +36,5 @@ exports.mochaHooks = { afterEach() { sandbox.reset() - } + }, } diff --git a/services/docstore/test/unit/js/DocArchiveManagerTests.js b/services/docstore/test/unit/js/DocArchiveManagerTests.js index 0316343c0f..39369715d7 100644 --- a/services/docstore/test/unit/js/DocArchiveManagerTests.js +++ b/services/docstore/test/unit/js/DocArchiveManagerTests.js @@ -27,23 +27,23 @@ describe('DocArchiveManager', function () { md5Sum = 'decafbad' RangeManager = { - jsonRangesToMongo: sinon.stub().returns({ mongo: 'ranges' }) + jsonRangesToMongo: sinon.stub().returns({ mongo: 'ranges' }), } Settings = { docstore: { - bucket: 'wombat' + bucket: 'wombat', }, parallelArchiveJobs: 3, destroyBatchSize: 10, - destroyRetryCount: 3 + destroyRetryCount: 3, } HashDigest = sinon.stub().returns(md5Sum) HashUpdate = sinon.stub().returns({ digest: HashDigest }) Crypto = { - createHash: sinon.stub().returns({ update: HashUpdate }) + createHash: sinon.stub().returns({ update: HashUpdate }), } Streamifier = { - createReadStream: sinon.stub().returns({ stream: 'readStream' }) + createReadStream: sinon.stub().returns({ stream: 'readStream' }), } projectId = ObjectId() @@ -51,75 +51,75 @@ describe('DocArchiveManager', function () { { _id: ObjectId(), inS3: true, - rev: 2 + rev: 2, }, { _id: ObjectId(), inS3: true, - rev: 4 + rev: 4, }, { _id: ObjectId(), inS3: true, - rev: 6 - } + rev: 6, + }, ] mongoDocs = [ { _id: ObjectId(), lines: ['one', 'two', 'three'], - rev: 2 + rev: 2, }, { _id: ObjectId(), lines: ['aaa', 'bbb', 'ccc'], - rev: 4 + rev: 4, }, { _id: ObjectId(), inS3: true, - rev: 6 + rev: 6, }, { _id: ObjectId(), inS3: true, - rev: 6 + rev: 6, }, { _id: ObjectId(), lines: ['111', '222', '333'], - rev: 6 - } + rev: 6, + }, ] docJson = JSON.stringify({ lines: mongoDocs[0].lines, ranges: mongoDocs[0].ranges, - schema_v: 1 + schema_v: 1, }) stream = { on: sinon.stub(), - resume: sinon.stub() + resume: sinon.stub(), } stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) stream.on.withArgs('end').yields() readStream = { - stream: 'readStream' + stream: 'readStream', } PersistorManager = { getObjectStream: sinon.stub().resolves(stream), sendStream: sinon.stub().resolves(), getObjectMd5Hash: sinon.stub().resolves(md5Sum), - deleteObject: sinon.stub().resolves() + deleteObject: sinon.stub().resolves(), } const getNonArchivedProjectDocs = sinon.stub() getNonArchivedProjectDocs .onCall(0) - .resolves(mongoDocs.filter((doc) => !doc.inS3)) + .resolves(mongoDocs.filter(doc => !doc.inS3)) getNonArchivedProjectDocs.onCall(1).resolves([]) const getArchivedProjectDocs = sinon.stub() @@ -135,8 +135,8 @@ describe('DocArchiveManager', function () { getNonArchivedProjectDocs, getArchivedProjectDocs, findDoc: sinon.stub().rejects(new Errors.NotFoundError()), - destroyDoc: sinon.stub().resolves() - } + destroyDoc: sinon.stub().resolves(), + }, } for (const mongoDoc of mongoDocs.concat(archivedDocs)) { MongoManager.promises.findDoc @@ -152,8 +152,8 @@ describe('DocArchiveManager', function () { './MongoManager': MongoManager, './RangeManager': RangeManager, './PersistorManager': PersistorManager, - './Errors': Errors - } + './Errors': Errors, + }, }) }) @@ -184,7 +184,7 @@ describe('DocArchiveManager', function () { const json = JSON.stringify({ lines: mongoDocs[0].lines, ranges: mongoDocs[0].ranges, - schema_v: 1 + schema_v: 1, }) await DocArchiveManager.promises.archiveDoc(projectId, mongoDocs[0]) @@ -277,7 +277,7 @@ describe('DocArchiveManager', function () { expect( MongoManager.promises.upsertIntoDocCollection ).to.have.been.calledWith(projectId, docId, { - lines: mongoDocs[0].lines + lines: mongoDocs[0].lines, }) }) @@ -295,7 +295,7 @@ describe('DocArchiveManager', function () { describe('when the doc has the old schema', function () { beforeEach(function () { mongoDoc = { - lines: ['doc', 'lines'] + lines: ['doc', 'lines'], } s3Doc = ['doc', 'lines'] docJson = JSON.stringify(s3Doc) @@ -315,11 +315,11 @@ describe('DocArchiveManager', function () { s3Doc = { lines: ['doc', 'lines'], ranges: { json: 'ranges' }, - schema_v: 1 + schema_v: 1, } mongoDoc = { lines: ['doc', 'lines'], - ranges: { mongo: 'ranges' } + ranges: { mongo: 'ranges' }, } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) @@ -337,10 +337,10 @@ describe('DocArchiveManager', function () { beforeEach(function () { s3Doc = { lines: ['doc', 'lines'], - schema_v: 1 + schema_v: 1, } mongoDoc = { - lines: ['doc', 'lines'] + lines: ['doc', 'lines'], } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) @@ -358,7 +358,7 @@ describe('DocArchiveManager', function () { beforeEach(function () { s3Doc = { lines: ['doc', 'lines'], - schema_v: 2 + schema_v: 2, } docJson = JSON.stringify(s3Doc) stream.on.withArgs('data').yields(Buffer.from(docJson, 'utf8')) diff --git a/services/docstore/test/unit/js/DocManagerTests.js b/services/docstore/test/unit/js/DocManagerTests.js index 60b3a20885..f81cc6a241 100644 --- a/services/docstore/test/unit/js/DocManagerTests.js +++ b/services/docstore/test/unit/js/DocManagerTests.js @@ -29,11 +29,11 @@ describe('DocManager', function () { jsonRangesToMongo(r) { return r }, - shouldUpdateRanges: sinon.stub().returns(false) + shouldUpdateRanges: sinon.stub().returns(false), }), '@overleaf/settings': (this.settings = { docstore: {} }), - './Errors': Errors - } + './Errors': Errors, + }, }) this.doc_id = ObjectId().toString() this.project_id = ObjectId().toString() @@ -47,7 +47,7 @@ describe('DocManager', function () { this.DocManager._getDoc = sinon.stub() return (this.doc = { _id: this.doc_id, - lines: ['2134'] + lines: ['2134'], }) }) @@ -65,7 +65,7 @@ describe('DocManager', function () { deleted: true, version: true, ranges: true, - inS3: true + inS3: true, }) .should.equal(true) return done() @@ -102,7 +102,7 @@ describe('DocManager', function () { this.DocManager._getDoc .calledWith(this.project_id, this.doc_id, { lines: true, - inS3: true + inS3: true, }) .should.equal(true) return done() @@ -129,7 +129,7 @@ describe('DocManager', function () { this.doc = { _id: this.doc_id, project_id: this.project_id, - lines: ['mock-lines'] + lines: ['mock-lines'], } this.version = 42 this.MongoManager.findDoc = sinon.stub() @@ -148,7 +148,7 @@ describe('DocManager', function () { this.project_id, this.doc_id, { inS3: false }, - (err) => { + err => { expect(err).to.exist return done() } @@ -160,7 +160,7 @@ describe('DocManager', function () { this.project_id, this.doc_id, undefined, - (err) => { + err => { this.MongoManager.findDoc.called.should.equal(false) expect(err).to.exist return done() @@ -173,7 +173,7 @@ describe('DocManager', function () { this.project_id, this.doc_id, { inS3: true }, - (err) => { + err => { expect(err).to.not.exist return done() } @@ -250,7 +250,7 @@ describe('DocManager', function () { _id: this.doc_id, project_id: this.project_id, lines: ['mock-lines'], - inS3: true + inS3: true, } this.MongoManager.findDoc.yields(null, this.doc) this.DocArchiveManager.unarchiveDoc = ( @@ -316,8 +316,8 @@ describe('DocManager', function () { { _id: this.doc_id, project_id: this.project_id, - lines: ['mock-lines'] - } + lines: ['mock-lines'], + }, ] this.MongoManager.getProjectsDocs = sinon .stub() @@ -499,7 +499,7 @@ describe('DocManager', function () { sinon.match({ project_id: this.project_id, doc_id: this.doc_id, - err: this.err + err: this.err, }), 'archiving a single doc in the background failed' ) @@ -545,10 +545,10 @@ describe('DocManager', function () { op: { i: 'foo', p: 3 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.newRanges = { changes: [ @@ -557,10 +557,10 @@ describe('DocManager', function () { op: { i: 'bar', p: 6 }, meta: { user_id: ObjectId().toString(), - ts: new Date().toString() - } - } - ] + ts: new Date().toString(), + }, + }, + ], } this.version = 42 this.doc = { @@ -569,7 +569,7 @@ describe('DocManager', function () { lines: this.oldDocLines, rev: (this.rev = 5), version: this.version, - ranges: this.originalRanges + ranges: this.originalRanges, } this.MongoManager.upsertIntoDocCollection = sinon.stub().callsArg(3) @@ -598,7 +598,7 @@ describe('DocManager', function () { lines: true, version: true, ranges: true, - inS3: true + inS3: true, }) .should.equal(true) }) @@ -844,7 +844,7 @@ describe('DocManager', function () { return this.MongoManager.upsertIntoDocCollection .calledWith(this.project_id, this.doc_id, { lines: this.newDocLines, - ranges: this.originalRanges + ranges: this.originalRanges, }) .should.equal(true) }) diff --git a/services/docstore/test/unit/js/HttpControllerTests.js b/services/docstore/test/unit/js/HttpControllerTests.js index 16b7baf5b0..e60e0e705c 100644 --- a/services/docstore/test/unit/js/HttpControllerTests.js +++ b/services/docstore/test/unit/js/HttpControllerTests.js @@ -21,21 +21,21 @@ const { ObjectId } = require('mongodb') describe('HttpController', function () { beforeEach(function () { const settings = { - max_doc_length: 2 * 1024 * 1024 + max_doc_length: 2 * 1024 * 1024, } this.HttpController = SandboxedModule.require(modulePath, { requires: { './DocManager': (this.DocManager = {}), './DocArchiveManager': (this.DocArchiveManager = {}), '@overleaf/settings': settings, - './HealthChecker': {} - } + './HealthChecker': {}, + }, }) this.res = { send: sinon.stub(), sendStatus: sinon.stub(), json: sinon.stub(), - setHeader: sinon.stub() + setHeader: sinon.stub(), } this.res.status = sinon.stub().returns(this.res) this.req = { query: {} } @@ -46,14 +46,14 @@ describe('HttpController', function () { _id: this.doc_id, lines: ['mock', 'lines', ' here', '', '', ' spaces '], version: 42, - rev: 5 + rev: 5, } return (this.deletedDoc = { deleted: true, _id: this.doc_id, lines: ['mock', 'lines', ' here', '', '', ' spaces '], version: 42, - rev: 5 + rev: 5, }) }) @@ -62,7 +62,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } this.DocManager.getFullDoc = sinon .stub() @@ -82,7 +82,7 @@ describe('HttpController', function () { _id: this.doc_id, lines: this.doc.lines, rev: this.doc.rev, - version: this.doc.version + version: this.doc.version, }) .should.equal(true) }) @@ -92,7 +92,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } return (this.DocManager.getFullDoc = sinon .stub() @@ -120,7 +120,7 @@ describe('HttpController', function () { lines: this.doc.lines, rev: this.doc.rev, deleted: true, - version: this.doc.version + version: this.doc.version, }) .should.equal(true) }) @@ -131,7 +131,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } this.DocManager.getDocLines = sinon.stub().callsArgWith(2, null, this.doc) return this.HttpController.getRawDoc(this.req, this.res, this.next) @@ -165,13 +165,13 @@ describe('HttpController', function () { { _id: ObjectId(), lines: ['mock', 'lines', 'one'], - rev: 2 + rev: 2, }, { _id: ObjectId(), lines: ['mock', 'lines', 'two'], - rev: 4 - } + rev: 4, + }, ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -191,13 +191,13 @@ describe('HttpController', function () { { _id: this.docs[0]._id.toString(), lines: this.docs[0].lines, - rev: this.docs[0].rev + rev: this.docs[0].rev, }, { _id: this.docs[1]._id.toString(), lines: this.docs[1].lines, - rev: this.docs[1].rev - } + rev: this.docs[1].rev, + }, ]) .should.equal(true) }) @@ -210,14 +210,14 @@ describe('HttpController', function () { { _id: ObjectId(), lines: ['mock', 'lines', 'one'], - rev: 2 + rev: 2, }, null, { _id: ObjectId(), lines: ['mock', 'lines', 'two'], - rev: 4 - } + rev: 4, + }, ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -231,13 +231,13 @@ describe('HttpController', function () { { _id: this.docs[0]._id.toString(), lines: this.docs[0].lines, - rev: this.docs[0].rev + rev: this.docs[0].rev, }, { _id: this.docs[2]._id.toString(), lines: this.docs[2].lines, - rev: this.docs[2].rev - } + rev: this.docs[2].rev, + }, ]) .should.equal(true) }) @@ -247,7 +247,7 @@ describe('HttpController', function () { .calledWith( { err: sinon.match.has('message', 'null doc'), - project_id: this.project_id + project_id: this.project_id, }, 'encountered null doc' ) @@ -263,12 +263,12 @@ describe('HttpController', function () { this.docs = [ { _id: ObjectId(), - ranges: { mock_ranges: 'one' } + ranges: { mock_ranges: 'one' }, }, { _id: ObjectId(), - ranges: { mock_ranges: 'two' } - } + ranges: { mock_ranges: 'two' }, + }, ] this.DocManager.getAllNonDeletedDocs = sinon .stub() @@ -287,12 +287,12 @@ describe('HttpController', function () { .calledWith([ { _id: this.docs[0]._id.toString(), - ranges: this.docs[0].ranges + ranges: this.docs[0].ranges, }, { _id: this.docs[1]._id.toString(), - ranges: this.docs[1].ranges - } + ranges: this.docs[1].ranges, + }, ]) .should.equal(true) }) @@ -303,7 +303,7 @@ describe('HttpController', function () { beforeEach(function () { return (this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, }) }) @@ -312,7 +312,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), - ranges: (this.ranges = { changes: 'mock' }) + ranges: (this.ranges = { changes: 'mock' }), } this.DocManager.updateDoc = sinon .stub() @@ -344,7 +344,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = ['hello', 'world']), version: (this.version = 42), - ranges: {} + ranges: {}, } this.DocManager.updateDoc = sinon .stub() @@ -412,7 +412,7 @@ describe('HttpController', function () { this.req.body = { lines: (this.lines = Array(2049).fill('a'.repeat(1024))), version: (this.version = 42), - ranges: (this.ranges = { changes: 'mock' }) + ranges: (this.ranges = { changes: 'mock' }), } return this.HttpController.updateDoc(this.req, this.res, this.next) }) @@ -431,7 +431,7 @@ describe('HttpController', function () { beforeEach(function () { this.req.params = { project_id: this.project_id, - doc_id: this.doc_id + doc_id: this.doc_id, } this.req.body = { name: 'foo.tex' } this.DocManager.patchDoc = sinon.stub().yields(null) diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 1e80fd1f21..50cc8268c3 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -24,11 +24,11 @@ describe('MongoManager', function () { requires: { './mongodb': { db: (this.db = { docs: {}, docOps: {} }), - ObjectId + ObjectId, }, '@overleaf/metrics': { timeAsyncMethod: sinon.stub() }, - '@overleaf/settings': { max_deleted_docs: 42 } - } + '@overleaf/settings': { max_deleted_docs: 42 }, + }, }) this.project_id = ObjectId().toString() this.doc_id = ObjectId().toString() @@ -54,10 +54,10 @@ describe('MongoManager', function () { .calledWith( { _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id) + project_id: ObjectId(this.project_id), }, { - projection: this.filter + projection: this.filter, } ) .should.equal(true) @@ -85,10 +85,10 @@ describe('MongoManager', function () { this.db.docs.updateOne.should.have.been.calledWith( { _id: ObjectId(this.doc_id), - project_id: ObjectId(this.project_id) + project_id: ObjectId(this.project_id), }, { - $set: this.meta + $set: this.meta, }, this.callback ) @@ -105,7 +105,7 @@ describe('MongoManager', function () { this.db.docs.find = sinon.stub().returns({ toArray: sinon .stub() - .callsArgWith(0, null, [this.doc, this.doc3, this.doc4]) + .callsArgWith(0, null, [this.doc, this.doc3, this.doc4]), }) }) @@ -124,10 +124,10 @@ describe('MongoManager', function () { .calledWith( { project_id: ObjectId(this.project_id), - deleted: { $ne: true } + deleted: { $ne: true }, }, { - projection: this.filter + projection: this.filter, } ) .should.equal(true) @@ -154,10 +154,10 @@ describe('MongoManager', function () { return this.db.docs.find .calledWith( { - project_id: ObjectId(this.project_id) + project_id: ObjectId(this.project_id), }, { - projection: this.filter + projection: this.filter, } ) .should.equal(true) @@ -178,7 +178,7 @@ describe('MongoManager', function () { this.doc2 = { _id: '2', name: 'mock-doc2.tex' } this.doc3 = { _id: '3', name: 'mock-doc3.tex' } this.db.docs.find = sinon.stub().returns({ - toArray: sinon.stub().yields(null, [this.doc1, this.doc2, this.doc3]) + toArray: sinon.stub().yields(null, [this.doc1, this.doc2, this.doc3]), }) this.callback.callsFake(done) this.MongoManager.getProjectsDeletedDocs( @@ -192,7 +192,7 @@ describe('MongoManager', function () { this.db.docs.find .calledWith({ project_id: ObjectId(this.project_id), - deleted: true + deleted: true, }) .should.equal(true) }) @@ -202,7 +202,7 @@ describe('MongoManager', function () { .calledWith(sinon.match.any, { projection: this.filter, sort: { deletedAt: -1 }, - limit: 42 + limit: 42, }) .should.equal(true) }) @@ -225,7 +225,7 @@ describe('MongoManager', function () { this.project_id, this.doc_id, { lines: this.lines }, - (err) => { + err => { const args = this.db.docs.updateOne.args[0] assert.deepEqual(args[0], { _id: ObjectId(this.doc_id) }) assert.equal(args[1].$set.lines, this.lines) @@ -241,7 +241,7 @@ describe('MongoManager', function () { this.project_id, this.doc_id, { lines: this.lines }, - (err) => { + err => { err.should.equal(this.stubbedErr) return done() } @@ -258,13 +258,13 @@ describe('MongoManager', function () { it('should destroy the doc', function () { return sinon.assert.calledWith(this.db.docs.deleteOne, { - _id: ObjectId('123456789012') + _id: ObjectId('123456789012'), }) }) return it('should destroy the docOps', function () { return sinon.assert.calledWith(this.db.docOps.deleteOne, { - doc_id: ObjectId('123456789012') + doc_id: ObjectId('123456789012'), }) }) }) @@ -282,7 +282,7 @@ describe('MongoManager', function () { .calledWith( { doc_id: ObjectId(this.doc_id) }, { - projection: { version: 1 } + projection: { version: 1 }, } ) .should.equal(true) @@ -320,15 +320,15 @@ describe('MongoManager', function () { return this.db.docOps.updateOne .calledWith( { - doc_id: ObjectId(this.doc_id) + doc_id: ObjectId(this.doc_id), }, { $set: { - version: this.version - } + version: this.version, + }, }, { - upsert: true + upsert: true, } ) .should.equal(true) diff --git a/services/docstore/test/unit/js/RangeManagerTests.js b/services/docstore/test/unit/js/RangeManagerTests.js index afea8f04c6..271d9daa69 100644 --- a/services/docstore/test/unit/js/RangeManagerTests.js +++ b/services/docstore/test/unit/js/RangeManagerTests.js @@ -25,9 +25,9 @@ describe('RangeManager', function () { return (this.RangeManager = SandboxedModule.require(modulePath, { requires: { './mongodb': { - ObjectId - } - } + ObjectId, + }, + }, })) }) @@ -45,16 +45,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id, - ts - } - } + ts, + }, + }, ], comments: [ { id: comment_id, - op: { c: 'foo', p: 3, t: thread_id } - } - ] + op: { c: 'foo', p: 3, t: thread_id }, + }, + ], }).should.deep.equal({ changes: [ { @@ -62,16 +62,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id: ObjectId(user_id), - ts: new Date(ts) - } - } + ts: new Date(ts), + }, + }, ], comments: [ { id: ObjectId(comment_id), - op: { c: 'foo', p: 3, t: ObjectId(thread_id) } - } - ] + op: { c: 'foo', p: 3, t: ObjectId(thread_id) }, + }, + ], }) }) @@ -84,29 +84,29 @@ describe('RangeManager', function () { { id: change_id, metadata: { - user_id - } - } + user_id, + }, + }, ], comments: [ { - id: comment_id - } - ] + id: comment_id, + }, + ], }).should.deep.equal({ changes: [ { id: change_id, metadata: { - user_id - } - } + user_id, + }, + }, ], comments: [ { - id: comment_id - } - ] + id: comment_id, + }, + ], }) }) @@ -123,16 +123,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id, - ts - } - } + ts, + }, + }, ], comments: [ { id: comment_id, - op: { c: 'foo', p: 3, t: thread_id } - } - ] + op: { c: 'foo', p: 3, t: thread_id }, + }, + ], } const ranges1_copy = JSON.parse(JSON.stringify(ranges1)) // jsonRangesToMongo modifies in place const ranges2 = JSON.parse( @@ -151,16 +151,16 @@ describe('RangeManager', function () { op: { i: 'foo', p: 3 }, metadata: { user_id: ObjectId(), - ts: new Date() - } - } + ts: new Date(), + }, + }, ], comments: [ { id: ObjectId(), - op: { c: 'foo', p: 3, t: ObjectId() } - } - ] + op: { c: 'foo', p: 3, t: ObjectId() }, + }, + ], } return (this.ranges_copy = this.RangeManager.jsonRangesToMongo( JSON.parse(JSON.stringify(this.ranges)) From 22a5d5bd80a28f0ff94966faf981141e2197da0f Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 13 Jul 2021 12:21:13 +0100 Subject: [PATCH 335/349] [misc] temporary override a few new/changed eslint rules --- services/docstore/.eslintrc | 15 ++++++++++++++- services/docstore/app/js/DocManager.js | 1 - services/docstore/app/js/HealthChecker.js | 1 - 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/services/docstore/.eslintrc b/services/docstore/.eslintrc index 1c14f50efe..a97661b15f 100644 --- a/services/docstore/.eslintrc +++ b/services/docstore/.eslintrc @@ -5,7 +5,7 @@ "extends": [ "eslint:recommended", "standard", - "prettier", + "prettier" ], "parserOptions": { "ecmaVersion": 2018 @@ -20,6 +20,19 @@ "mocha": true }, "rules": { + // TODO(das7pad): remove overrides after fixing all the violations manually (https://github.com/overleaf/issues/issues/3882#issuecomment-878999671) + // START of temporary overrides + "array-callback-return": "off", + "no-dupe-else-if": "off", + "no-var": "off", + "no-empty": "off", + "node/handle-callback-err": "off", + "no-loss-of-precision": "off", + "node/no-callback-literal": "off", + "node/no-path-concat": "off", + "prefer-regex-literals": "off", + // END of temporary overrides + // Swap the no-unused-expressions rule with a more chai-friendly one "no-unused-expressions": 0, "chai-friendly/no-unused-expressions": "error", diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 0f00ce79cf..51a974d5a7 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -3,7 +3,6 @@ handle-callback-err, no-dupe-keys, no-undef, - standard/no-callback-literal, */ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. diff --git a/services/docstore/app/js/HealthChecker.js b/services/docstore/app/js/HealthChecker.js index 3271c40164..5578afff75 100644 --- a/services/docstore/app/js/HealthChecker.js +++ b/services/docstore/app/js/HealthChecker.js @@ -1,6 +1,5 @@ /* eslint-disable camelcase, - standard/no-callback-literal, */ // TODO: This file was created by bulk-decaffeinate. // Fix any style issues and re-enable lint. From 886d32ef4375c722d43c3e31aa0a647c2d274e15 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann <jakob.ackermann@overleaf.com> Date: Tue, 13 Jul 2021 12:26:35 +0100 Subject: [PATCH 336/349] [misc] upgrade node version to latest v12 LTS version 12.22.3 --- services/docstore/.nvmrc | 2 +- services/docstore/Dockerfile | 2 +- services/docstore/buildscript.txt | 2 +- services/docstore/docker-compose.yml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/services/docstore/.nvmrc b/services/docstore/.nvmrc index e68b860383..5a80a7e912 100644 --- a/services/docstore/.nvmrc +++ b/services/docstore/.nvmrc @@ -1 +1 @@ -12.21.0 +12.22.3 diff --git a/services/docstore/Dockerfile b/services/docstore/Dockerfile index 4f417a2a4b..6b286376dc 100644 --- a/services/docstore/Dockerfile +++ b/services/docstore/Dockerfile @@ -2,7 +2,7 @@ # Instead run bin/update_build_scripts from # https://github.com/sharelatex/sharelatex-dev-environment -FROM node:12.21.0 as base +FROM node:12.22.3 as base WORKDIR /app diff --git a/services/docstore/buildscript.txt b/services/docstore/buildscript.txt index a87ee7a694..994a0eae7d 100644 --- a/services/docstore/buildscript.txt +++ b/services/docstore/buildscript.txt @@ -3,6 +3,6 @@ docstore --docker-repos=gcr.io/overleaf-ops --env-add= --env-pass-through= ---node-version=12.21.0 +--node-version=12.22.3 --public-repo=True --script-version=3.11.0 diff --git a/services/docstore/docker-compose.yml b/services/docstore/docker-compose.yml index d4a91fff95..89e94ce7ce 100644 --- a/services/docstore/docker-compose.yml +++ b/services/docstore/docker-compose.yml @@ -6,7 +6,7 @@ version: "2.3" services: test_unit: - image: node:12.21.0 + image: node:12.22.3 volumes: - .:/app working_dir: /app @@ -18,7 +18,7 @@ services: user: node test_acceptance: - image: node:12.21.0 + image: node:12.22.3 volumes: - .:/app working_dir: /app From 0095a381b0bcfa4eb01ce30ec8d9010527c0587a Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Fri, 30 Jul 2021 16:03:43 +0100 Subject: [PATCH 337/349] refactor unarchiveDoc to use a separate getDoc helper --- services/docstore/app/js/DocArchiveManager.js | 73 +++++++++++-------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/services/docstore/app/js/DocArchiveManager.js b/services/docstore/app/js/DocArchiveManager.js index dcd713eb62..edd920833d 100644 --- a/services/docstore/app/js/DocArchiveManager.js +++ b/services/docstore/app/js/DocArchiveManager.js @@ -23,6 +23,7 @@ module.exports = { unarchiveDoc: callbackify(unarchiveDoc), destroyAllDocs: callbackify(destroyAllDocs), destroyDoc: callbackify(destroyDoc), + getDoc: callbackify(getDoc), promises: { archiveAllDocs, archiveDocById, @@ -31,6 +32,7 @@ module.exports = { unarchiveDoc, destroyAllDocs, destroyDoc, + getDoc, }, } @@ -125,38 +127,17 @@ async function unArchiveAllDocs(projectId) { } } -async function unarchiveDoc(projectId, docId) { - logger.log( - { project_id: projectId, doc_id: docId }, - 'getting doc from persistor' - ) - const originalDoc = await MongoManager.findDoc(projectId, docId, { inS3: 1 }) - if (!originalDoc.inS3) { - // return if it's not actually in S3 as there's nothing to do - return - } +// get the doc from the PersistorManager without storing it in mongo +async function getDoc(projectId, docId) { const key = `${projectId}/${docId}` - let stream, sourceMd5 - try { - sourceMd5 = await PersistorManager.getObjectMd5Hash( - settings.docstore.bucket, - key - ) - stream = await PersistorManager.getObjectStream( - settings.docstore.bucket, - key - ) - } catch (err) { - // if we get a 404, we could be in a race and something else has unarchived the doc already - if (err instanceof Errors.NotFoundError) { - const doc = await MongoManager.findDoc(projectId, docId, { inS3: 1 }) - if (!doc.inS3) { - // the doc has been archived while we were looking for it, so no error - return - } - } - throw err - } + const sourceMd5 = await PersistorManager.getObjectMd5Hash( + settings.docstore.bucket, + key + ) + const stream = await PersistorManager.getObjectStream( + settings.docstore.bucket, + key + ) stream.resume() const json = await _streamToString(stream) const md5 = crypto.createHash('md5').update(json).digest('hex') @@ -181,6 +162,36 @@ async function unarchiveDoc(projectId, docId) { } else { throw new Error("I don't understand the doc format in s3") } + + return mongoDoc +} + +// get the doc and unarchive it to mongo +async function unarchiveDoc(projectId, docId) { + logger.log( + { project_id: projectId, doc_id: docId }, + 'getting doc from persistor' + ) + const key = `${projectId}/${docId}` + const originalDoc = await MongoManager.findDoc(projectId, docId, { inS3: 1 }) + if (!originalDoc.inS3) { + // return if it's not actually in S3 as there's nothing to do + return + } + let mongoDoc + try { + mongoDoc = await getDoc(projectId, docId) + } catch (err) { + // if we get a 404, we could be in a race and something else has unarchived the doc already + if (err instanceof Errors.NotFoundError) { + const doc = await MongoManager.findDoc(projectId, docId, { inS3: 1 }) + if (!doc.inS3) { + // the doc has been archived while we were looking for it, so no error + return + } + } + throw err + } await MongoManager.upsertIntoDocCollection(projectId, docId, mongoDoc) await PersistorManager.deleteObject(settings.docstore.bucket, key) } From 6ce28271eb57c190a9825d240e0693da3ddce816 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Fri, 30 Jul 2021 16:06:16 +0100 Subject: [PATCH 338/349] peek at docs without unarchiving --- services/docstore/app.js | 1 + services/docstore/app/js/DocManager.js | 64 ++++++++++++ services/docstore/app/js/Errors.js | 3 + services/docstore/app/js/HttpController.js | 16 +++ services/docstore/app/js/MongoManager.js | 40 ++++++++ .../js/GettingDocsFromArchiveTest.js | 99 +++++++++++++++++++ .../acceptance/js/helpers/DocstoreClient.js | 14 +++ .../test/unit/js/MongoManagerTests.js | 2 + 8 files changed, 239 insertions(+) create mode 100644 services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js diff --git a/services/docstore/app.js b/services/docstore/app.js index 7cb774b9f8..931914e0f5 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -54,6 +54,7 @@ app.get('/project/:project_id/ranges', HttpController.getAllRanges) app.get('/project/:project_id/doc/:doc_id', HttpController.getDoc) app.get('/project/:project_id/doc/:doc_id/deleted', HttpController.isDocDeleted) app.get('/project/:project_id/doc/:doc_id/raw', HttpController.getRawDoc) +app.get('/project/:project_id/doc/:doc_id/peek', HttpController.peekDoc) // Add 64kb overhead for the JSON encoding, and double the size to allow for ranges in the json payload app.post( '/project/:project_id/doc/:doc_id', diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 51a974d5a7..17aff5d989 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -124,6 +124,70 @@ module.exports = DocManager = { ) }, + // returns the doc without any version information + _peekRawDoc(project_id, doc_id, callback) { + MongoManager.findDoc( + project_id, + doc_id, + { + lines: true, + rev: true, + deleted: true, + version: true, + ranges: true, + inS3: true, + }, + (err, doc) => { + if (err) return callback(err) + if (doc == null) { + return callback( + new Errors.NotFoundError( + `No such doc: ${doc_id} in project ${project_id}` + ) + ) + } + if (doc && !doc.inS3) { + return callback(null, doc) + } + // skip the unarchiving to mongo when getting a doc + DocArchive.getDoc(project_id, doc_id, function (err, archivedDoc) { + if (err != null) { + logger.err( + { err, project_id, doc_id }, + 'error getting doc from archive' + ) + return callback(err) + } + doc = _.extend(doc, archivedDoc) + callback(null, doc) + }) + } + ) + }, + + // get the doc from mongo if possible, or from the persistent store otherwise, + // without unarchiving it (avoids unnecessary writes to mongo) + peekDoc(project_id, doc_id, callback) { + DocManager._peekRawDoc(project_id, doc_id, (err, doc) => { + if (err) { + return callback(err) + } + MongoManager.WithRevCheck( + doc, + MongoManager.getDocVersion, + function (error, version) { + // If the doc has been modified while we were retrieving it, we + // will get a DocModified error + if (error != null) { + return callback(error) + } + doc.version = version + return callback(err, doc) + } + ) + }) + }, + getDocLines(project_id, doc_id, callback) { if (callback == null) { callback = function (err, doc) {} diff --git a/services/docstore/app/js/Errors.js b/services/docstore/app/js/Errors.js index 4eaa5481d3..3cf5ad74a4 100644 --- a/services/docstore/app/js/Errors.js +++ b/services/docstore/app/js/Errors.js @@ -4,7 +4,10 @@ const { Errors } = require('@overleaf/object-persistor') class Md5MismatchError extends OError {} +class DocModifiedError extends OError {} + module.exports = { Md5MismatchError, + DocModifiedError, ...Errors, } diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index f53c9068bc..909836066b 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -44,6 +44,22 @@ module.exports = HttpController = { }) }, + peekDoc(req, res, next) { + const { project_id } = req.params + const { doc_id } = req.params + logger.log({ project_id, doc_id }, 'peeking doc') + DocManager.peekDoc(project_id, doc_id, function (error, doc) { + if (error) { + return next(error) + } + if (doc == null) { + return res.sendStatus(404) + } else { + return res.json(HttpController._buildDocView(doc)) + } + }) + }, + isDocDeleted(req, res, next) { const { doc_id: docId, project_id: projectId } = req.params DocManager.isDocDeleted(projectId, docId, function (error, deleted) { diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 5434db581d..ef90d966ff 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -15,6 +15,7 @@ const { db, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') const metrics = require('@overleaf/metrics') const Settings = require('@overleaf/settings') +const { DocModifiedError } = require('./Errors') const { promisify } = require('util') module.exports = MongoManager = { @@ -178,6 +179,45 @@ module.exports = MongoManager = { ) }, + getDocRev(doc_id, callback) { + db.docs.findOne( + { + _id: ObjectId(doc_id.toString()), + }, + { + projection: { rev: 1 }, + }, + function (err, doc) { + if (err != null) { + return callback(err) + } + callback(null, doc && doc.rev) + } + ) + }, + + // Helper method to support optimistic locking. Call the provided method for + // an existing doc and return the result if the rev in mongo is unchanged when + // checked afterwards. If the rev has changed, return a DocModifiedError. + WithRevCheck(doc, method, callback) { + method(doc._id, function (err, result) { + if (err) return callback(err) + MongoManager.getDocRev(doc._id, function (err, currentRev) { + if (err) return callback(err) + if (doc.rev !== currentRev) { + return callback( + new DocModifiedError('doc rev has changed', { + doc_id: doc._id, + rev: doc.rev, + currentRev, + }) + ) + } + return callback(null, result) + }) + }) + }, + destroyDoc(doc_id, callback) { db.docs.deleteOne( { diff --git a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js new file mode 100644 index 0000000000..714721e079 --- /dev/null +++ b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js @@ -0,0 +1,99 @@ +/* eslint-disable + camelcase, + handle-callback-err, + no-unused-vars, +*/ +// TODO: This file was created by bulk-decaffeinate. +// Fix any style issues and re-enable lint. +/* + * decaffeinate suggestions: + * DS101: Remove unnecessary use of Array.from + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +process.env.BACKEND = 'gcs' +const Settings = require('@overleaf/settings') +const { expect } = require('chai') +const { db, ObjectId } = require('../../../app/js/mongodb') +const async = require('async') +const DocstoreApp = require('./helpers/DocstoreApp') +const DocstoreClient = require('./helpers/DocstoreClient') +const { Storage } = require('@google-cloud/storage') +const Persistor = require('../../../app/js/PersistorManager') +const Streamifier = require('streamifier') + +function uploadContent(path, json, callback) { + const stream = Streamifier.createReadStream(JSON.stringify(json)) + Persistor.sendStream(Settings.docstore.bucket, path, stream) + .then(() => callback()) + .catch(callback) +} + +describe('Getting A Doc from Archive', function () { + before(function (done) { + return DocstoreApp.ensureRunning(done) + }) + + before(async function () { + const storage = new Storage(Settings.docstore.gcs.endpoint) + await storage.createBucket(Settings.docstore.bucket) + await storage.createBucket(`${Settings.docstore.bucket}-deleted`) + }) + + describe('archiving a single doc', function () { + before(function (done) { + this.project_id = ObjectId() + this.timeout(1000 * 30) + this.doc = { + _id: ObjectId(), + lines: ['foo', 'bar'], + ranges: {}, + version: 2, + } + DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + error => { + if (error) { + return done(error) + } + DocstoreClient.archiveDocById( + this.project_id, + this.doc._id, + (error, res) => { + this.res = res + if (error) { + return done(error) + } + done() + } + ) + } + ) + }) + + it('should successully archive the doc', function (done) { + this.res.statusCode.should.equal(204) + done() + }) + + it('should get the doc lines and version', function (done) { + return DocstoreClient.peekDoc( + this.project_id, + this.doc._id, + {}, + (error, res, doc) => { + res.statusCode.should.equal(200) + doc.lines.should.deep.equal(this.doc.lines) + doc.version.should.equal(this.doc.version) + doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) + }) +}) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 1164540bd3..4e80cc6c72 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -60,6 +60,20 @@ module.exports = DocstoreClient = { ) }, + peekDoc(project_id, doc_id, qs, callback) { + if (callback == null) { + callback = function (error, res, body) {} + } + return request.get( + { + url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/peek`, + json: true, + qs, + }, + callback + ) + }, + isDocDeleted(project_id, doc_id, callback) { request.get( { diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index 50cc8268c3..eb209a24c2 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -17,6 +17,7 @@ const modulePath = require('path').join( ) const { ObjectId } = require('mongodb') const { assert } = require('chai') +const Errors = require('../../../app/js/Errors') describe('MongoManager', function () { beforeEach(function () { @@ -28,6 +29,7 @@ describe('MongoManager', function () { }, '@overleaf/metrics': { timeAsyncMethod: sinon.stub() }, '@overleaf/settings': { max_deleted_docs: 42 }, + './Errors': { Errors }, }, }) this.project_id = ObjectId().toString() From 69339aeb9daa2b815e23ed9c1053e630d4f8e82a Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Mon, 2 Aug 2021 10:25:03 +0100 Subject: [PATCH 339/349] return the origin of peeked docs --- services/docstore/app/js/HttpController.js | 1 + .../js/GettingDocsFromArchiveTest.js | 57 ++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/js/HttpController.js b/services/docstore/app/js/HttpController.js index 909836066b..7e901c4357 100644 --- a/services/docstore/app/js/HttpController.js +++ b/services/docstore/app/js/HttpController.js @@ -55,6 +55,7 @@ module.exports = HttpController = { if (doc == null) { return res.sendStatus(404) } else { + res.setHeader('x-doc-status', doc.inS3 ? 'archived' : 'active') return res.json(HttpController._buildDocView(doc)) } }) diff --git a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js index 714721e079..2bf2605bec 100644 --- a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js +++ b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js @@ -41,7 +41,7 @@ describe('Getting A Doc from Archive', function () { await storage.createBucket(`${Settings.docstore.bucket}-deleted`) }) - describe('archiving a single doc', function () { + describe('for an archived doc', function () { before(function (done) { this.project_id = ObjectId() this.timeout(1000 * 30) @@ -81,13 +81,66 @@ describe('Getting A Doc from Archive', function () { done() }) - it('should get the doc lines and version', function (done) { + it('should return the doc lines and version from persistent storage', function (done) { return DocstoreClient.peekDoc( this.project_id, this.doc._id, {}, (error, res, doc) => { res.statusCode.should.equal(200) + res.headers['x-doc-status'].should.equal('archived') + doc.lines.should.deep.equal(this.doc.lines) + doc.version.should.equal(this.doc.version) + doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) + + it('should return the doc lines and version from persistent storage on subsequent requests', function (done) { + return DocstoreClient.peekDoc( + this.project_id, + this.doc._id, + {}, + (error, res, doc) => { + res.statusCode.should.equal(200) + res.headers['x-doc-status'].should.equal('archived') + doc.lines.should.deep.equal(this.doc.lines) + doc.version.should.equal(this.doc.version) + doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) + + describe('for an non-archived doc', function () { + before(function (done) { + this.project_id = ObjectId() + this.timeout(1000 * 30) + this.doc = { + _id: ObjectId(), + lines: ['foo', 'bar'], + ranges: {}, + version: 2, + } + DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + done + ) + }) + + it('should return the doc lines and version from mongo', function (done) { + return DocstoreClient.peekDoc( + this.project_id, + this.doc._id, + {}, + (error, res, doc) => { + res.statusCode.should.equal(200) + res.headers['x-doc-status'].should.equal('active') doc.lines.should.deep.equal(this.doc.lines) doc.version.should.equal(this.doc.version) doc.ranges.should.deep.equal(this.doc.ranges) From dd082ad345e963e1b558ee4872fee7ccd8fdbc58 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Mon, 2 Aug 2021 10:25:18 +0100 Subject: [PATCH 340/349] return a 409 for DocModified errors --- services/docstore/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/docstore/app.js b/services/docstore/app.js index 931914e0f5..75154471be 100644 --- a/services/docstore/app.js +++ b/services/docstore/app.js @@ -91,6 +91,8 @@ app.use(function (error, req, res, next) { logger.error({ err: error, req }, 'request errored') if (error instanceof Errors.NotFoundError) { return res.sendStatus(404) + } else if (error instanceof Errors.DocModifiedError) { + return res.sendStatus(409) } else { return res.status(500).send('Oops, something went wrong') } From 50fa9609a3783e83760a7fb445b20c4b19c68486 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Mon, 2 Aug 2021 11:01:30 +0100 Subject: [PATCH 341/349] add test of archive status --- .../js/GettingDocsFromArchiveTest.js | 67 ++++++++++--------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js index 2bf2605bec..4f3465c698 100644 --- a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js +++ b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js @@ -113,40 +113,41 @@ describe('Getting A Doc from Archive', function () { ) }) - describe('for an non-archived doc', function () { - before(function (done) { - this.project_id = ObjectId() - this.timeout(1000 * 30) - this.doc = { - _id: ObjectId(), - lines: ['foo', 'bar'], - ranges: {}, - version: 2, - } - DocstoreClient.createDoc( - this.project_id, - this.doc._id, - this.doc.lines, - this.doc.version, - this.doc.ranges, - done - ) - }) - - it('should return the doc lines and version from mongo', function (done) { - return DocstoreClient.peekDoc( - this.project_id, - this.doc._id, - {}, - (error, res, doc) => { - res.statusCode.should.equal(200) - res.headers['x-doc-status'].should.equal('active') - doc.lines.should.deep.equal(this.doc.lines) - doc.version.should.equal(this.doc.version) - doc.ranges.should.deep.equal(this.doc.ranges) - return done() + describe('for an non-archived doc', function () { + before(function (done) { + this.project_id = ObjectId() + this.timeout(1000 * 30) + this.doc = { + _id: ObjectId(), + lines: ['foo', 'bar'], + ranges: {}, + version: 2, } - ) + DocstoreClient.createDoc( + this.project_id, + this.doc._id, + this.doc.lines, + this.doc.version, + this.doc.ranges, + done + ) + }) + + it('should return the doc lines and version from mongo', function (done) { + return DocstoreClient.peekDoc( + this.project_id, + this.doc._id, + {}, + (error, res, doc) => { + res.statusCode.should.equal(200) + res.headers['x-doc-status'].should.equal('active') + doc.lines.should.deep.equal(this.doc.lines) + doc.version.should.equal(this.doc.version) + doc.ranges.should.deep.equal(this.doc.ranges) + return done() + } + ) + }) }) }) }) From 7b904d9a9d2feb42d7357062c82883b0fe7b5cd2 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Mon, 2 Aug 2021 11:02:12 +0100 Subject: [PATCH 342/349] fix case of WithRevCheck method --- services/docstore/app/js/DocManager.js | 2 +- services/docstore/app/js/MongoManager.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/services/docstore/app/js/DocManager.js b/services/docstore/app/js/DocManager.js index 17aff5d989..51e3beaf27 100644 --- a/services/docstore/app/js/DocManager.js +++ b/services/docstore/app/js/DocManager.js @@ -172,7 +172,7 @@ module.exports = DocManager = { if (err) { return callback(err) } - MongoManager.WithRevCheck( + MongoManager.withRevCheck( doc, MongoManager.getDocVersion, function (error, version) { diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index ef90d966ff..456d8c7334 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -199,7 +199,7 @@ module.exports = MongoManager = { // Helper method to support optimistic locking. Call the provided method for // an existing doc and return the result if the rev in mongo is unchanged when // checked afterwards. If the rev has changed, return a DocModifiedError. - WithRevCheck(doc, method, callback) { + withRevCheck(doc, method, callback) { method(doc._id, function (err, result) { if (err) return callback(err) MongoManager.getDocRev(doc._id, function (err, currentRev) { From 8afdc8cbd4fb325fc53301e6d71a5529457ac008 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Mon, 2 Aug 2021 11:36:43 +0100 Subject: [PATCH 343/349] add unit test for withRevCheck method --- services/docstore/app/js/MongoManager.js | 4 +-- .../test/unit/js/MongoManagerTests.js | 36 +++++++++++++++++-- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/services/docstore/app/js/MongoManager.js b/services/docstore/app/js/MongoManager.js index 456d8c7334..263a162516 100644 --- a/services/docstore/app/js/MongoManager.js +++ b/services/docstore/app/js/MongoManager.js @@ -15,7 +15,7 @@ const { db, ObjectId } = require('./mongodb') const logger = require('logger-sharelatex') const metrics = require('@overleaf/metrics') const Settings = require('@overleaf/settings') -const { DocModifiedError } = require('./Errors') +const Errors = require('./Errors') const { promisify } = require('util') module.exports = MongoManager = { @@ -206,7 +206,7 @@ module.exports = MongoManager = { if (err) return callback(err) if (doc.rev !== currentRev) { return callback( - new DocModifiedError('doc rev has changed', { + new Errors.DocModifiedError('doc rev has changed', { doc_id: doc._id, rev: doc.rev, currentRev, diff --git a/services/docstore/test/unit/js/MongoManagerTests.js b/services/docstore/test/unit/js/MongoManagerTests.js index eb209a24c2..5bfcb3c179 100644 --- a/services/docstore/test/unit/js/MongoManagerTests.js +++ b/services/docstore/test/unit/js/MongoManagerTests.js @@ -29,7 +29,7 @@ describe('MongoManager', function () { }, '@overleaf/metrics': { timeAsyncMethod: sinon.stub() }, '@overleaf/settings': { max_deleted_docs: 42 }, - './Errors': { Errors }, + './Errors': Errors, }, }) this.project_id = ObjectId().toString() @@ -307,7 +307,7 @@ describe('MongoManager', function () { }) }) - return describe('setDocVersion', function () { + describe('setDocVersion', function () { beforeEach(function () { this.version = 42 this.db.docOps.updateOne = sinon.stub().callsArg(3) @@ -340,4 +340,36 @@ describe('MongoManager', function () { return this.callback.called.should.equal(true) }) }) + + describe('withRevCheck', function () { + this.beforeEach(function () { + this.doc = { _id: ObjectId(), name: 'mock-doc', rev: 1 } + this.testFunction = sinon.stub().yields(null, 'foo') + }) + + it('should call the callback when the rev has not changed', function (done) { + this.db.docs.findOne = sinon.stub().callsArgWith(2, null, { rev: 1 }) + this.MongoManager.withRevCheck( + this.doc, + this.testFunction, + (err, result) => { + result.should.equal('foo') + assert.isNull(err) + done() + } + ) + }) + + it('should return an error when the rev has changed', function (done) { + this.db.docs.findOne = sinon.stub().callsArgWith(2, null, { rev: 2 }) + this.MongoManager.withRevCheck( + this.doc, + this.testFunction, + (err, result) => { + err.should.be.instanceof(Errors.DocModifiedError) + done() + } + ) + }) + }) }) From 04ea24dfbc811ebf87306328fe246e222f16a6a1 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Tue, 3 Aug 2021 09:39:24 +0100 Subject: [PATCH 344/349] remove decaf header and fix lint issues --- .../js/GettingDocsFromArchiveTest.js | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js index 4f3465c698..4dddbb862d 100644 --- a/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js +++ b/services/docstore/test/acceptance/js/GettingDocsFromArchiveTest.js @@ -1,34 +1,8 @@ -/* eslint-disable - camelcase, - handle-callback-err, - no-unused-vars, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ -process.env.BACKEND = 'gcs' const Settings = require('@overleaf/settings') -const { expect } = require('chai') -const { db, ObjectId } = require('../../../app/js/mongodb') -const async = require('async') +const { ObjectId } = require('../../../app/js/mongodb') const DocstoreApp = require('./helpers/DocstoreApp') const DocstoreClient = require('./helpers/DocstoreClient') const { Storage } = require('@google-cloud/storage') -const Persistor = require('../../../app/js/PersistorManager') -const Streamifier = require('streamifier') - -function uploadContent(path, json, callback) { - const stream = Streamifier.createReadStream(JSON.stringify(json)) - Persistor.sendStream(Settings.docstore.bucket, path, stream) - .then(() => callback()) - .catch(callback) -} describe('Getting A Doc from Archive', function () { before(function (done) { From 942feb3011be9716b96c2cd30177086f8608c4de Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Tue, 3 Aug 2021 10:00:44 +0100 Subject: [PATCH 345/349] move process.env.BACKEND to setup.js --- services/docstore/test/acceptance/js/ArchiveDocsTests.js | 2 +- services/docstore/test/setup.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/services/docstore/test/acceptance/js/ArchiveDocsTests.js b/services/docstore/test/acceptance/js/ArchiveDocsTests.js index 2dc02152d9..381e90fabd 100644 --- a/services/docstore/test/acceptance/js/ArchiveDocsTests.js +++ b/services/docstore/test/acceptance/js/ArchiveDocsTests.js @@ -12,7 +12,7 @@ * DS207: Consider shorter variations of null checks * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ -process.env.BACKEND = 'gcs' + const Settings = require('@overleaf/settings') const { expect } = require('chai') const { db, ObjectId } = require('../../../app/js/mongodb') diff --git a/services/docstore/test/setup.js b/services/docstore/test/setup.js index fbf29a495b..e45df5834f 100644 --- a/services/docstore/test/setup.js +++ b/services/docstore/test/setup.js @@ -4,6 +4,8 @@ const sinonChai = require('sinon-chai') const chaiAsPromised = require('chai-as-promised') const SandboxedModule = require('sandboxed-module') +process.env.BACKEND = 'gcs' + // Chai configuration chai.should() chai.use(sinonChai) From 8c791b2938540d74bbd521f39ef713dd25f8e81a Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Tue, 3 Aug 2021 10:07:00 +0100 Subject: [PATCH 346/349] remove default callback --- .../docstore/test/acceptance/js/helpers/DocstoreClient.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 4e80cc6c72..1af9f10ce7 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -61,10 +61,7 @@ module.exports = DocstoreClient = { }, peekDoc(project_id, doc_id, qs, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.get( + request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/peek`, json: true, From 43cab1fddcce601b1011cb8a37743dd283bc1480 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Tue, 3 Aug 2021 10:08:17 +0100 Subject: [PATCH 347/349] remove unnecessary returns and callbacks --- .../acceptance/js/helpers/DocstoreClient.js | 46 +++---------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 1af9f10ce7..7bd6bd6618 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -1,16 +1,6 @@ /* eslint-disable camelcase, - handle-callback-err, - no-unused-vars, */ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS102: Remove unnecessary code created because of implicit returns - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ let DocstoreClient const request = require('request').defaults({ jar: false }) const settings = require('@overleaf/settings') @@ -33,9 +23,6 @@ async function getStringFromPersistor(persistor, bucket, key) { module.exports = DocstoreClient = { createDoc(project_id, doc_id, lines, version, ranges, callback) { - if (callback == null) { - callback = function (error) {} - } return DocstoreClient.updateDoc( project_id, doc_id, @@ -47,10 +34,7 @@ module.exports = DocstoreClient = { }, getDoc(project_id, doc_id, qs, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.get( + request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, json: true, @@ -82,10 +66,7 @@ module.exports = DocstoreClient = { }, getAllDocs(project_id, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.get( + request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, json: true, @@ -113,10 +94,7 @@ module.exports = DocstoreClient = { }, getAllRanges(project_id, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.get( + request.get( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, json: true, @@ -126,9 +104,6 @@ module.exports = DocstoreClient = { }, updateDoc(project_id, doc_id, lines, version, ranges, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } return request.post( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, @@ -183,10 +158,7 @@ module.exports = DocstoreClient = { }, archiveAllDoc(project_id, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.post( + request.post( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive`, }, @@ -195,10 +167,7 @@ module.exports = DocstoreClient = { }, archiveDocById(project_id, doc_id, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.post( + request.post( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/archive`, }, @@ -207,10 +176,7 @@ module.exports = DocstoreClient = { }, destroyAllDoc(project_id, callback) { - if (callback == null) { - callback = function (error, res, body) {} - } - return request.post( + request.post( { url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy`, }, From 9a14d015170e264710becdfebcbd20a85fca70ba Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Tue, 3 Aug 2021 10:12:00 +0100 Subject: [PATCH 348/349] remove decaff headers --- .../test/acceptance/js/helpers/DocstoreApp.js | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js index 4a45a7e6d6..dd63eeb211 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreApp.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreApp.js @@ -1,16 +1,3 @@ -/* eslint-disable - handle-callback-err, -*/ -// TODO: This file was created by bulk-decaffeinate. -// Fix any style issues and re-enable lint. -/* - * decaffeinate suggestions: - * DS101: Remove unnecessary use of Array.from - * DS102: Remove unnecessary code created because of implicit returns - * DS205: Consider reworking code to avoid use of IIFEs - * DS207: Consider shorter variations of null checks - * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md - */ const app = require('../../../../app') const { waitForDb } = require('../../../../app/js/mongodb') require('logger-sharelatex').logger.level('error') From 9c50a2488fdb5d1fb8cdc60d1a8f86331910f830 Mon Sep 17 00:00:00 2001 From: Brian Gough <brian.gough@overleaf.com> Date: Tue, 3 Aug 2021 10:12:16 +0100 Subject: [PATCH 349/349] remove decaff headers, fix camelcase --- .../acceptance/js/helpers/DocstoreClient.js | 75 +++++++++---------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js index 7bd6bd6618..e2c2706fbc 100644 --- a/services/docstore/test/acceptance/js/helpers/DocstoreClient.js +++ b/services/docstore/test/acceptance/js/helpers/DocstoreClient.js @@ -1,6 +1,3 @@ -/* eslint-disable - camelcase, -*/ let DocstoreClient const request = require('request').defaults({ jar: false }) const settings = require('@overleaf/settings') @@ -22,10 +19,10 @@ async function getStringFromPersistor(persistor, bucket, key) { } module.exports = DocstoreClient = { - createDoc(project_id, doc_id, lines, version, ranges, callback) { + createDoc(projectId, docId, lines, version, ranges, callback) { return DocstoreClient.updateDoc( - project_id, - doc_id, + projectId, + docId, lines, version, ranges, @@ -33,10 +30,10 @@ module.exports = DocstoreClient = { ) }, - getDoc(project_id, doc_id, qs, callback) { + getDoc(projectId, docId, qs, callback) { request.get( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, json: true, qs, }, @@ -44,10 +41,10 @@ module.exports = DocstoreClient = { ) }, - peekDoc(project_id, doc_id, qs, callback) { + peekDoc(projectId, docId, qs, callback) { request.get( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/peek`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/peek`, json: true, qs, }, @@ -55,20 +52,20 @@ module.exports = DocstoreClient = { ) }, - isDocDeleted(project_id, doc_id, callback) { + isDocDeleted(projectId, docId, callback) { request.get( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/deleted`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/deleted`, json: true, }, callback ) }, - getAllDocs(project_id, callback) { + getAllDocs(projectId, callback) { request.get( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc`, json: true, }, (req, res, body) => { @@ -77,10 +74,10 @@ module.exports = DocstoreClient = { ) }, - getAllDeletedDocs(project_id, callback) { + getAllDeletedDocs(projectId, callback) { request.get( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc-deleted`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc-deleted`, json: true, }, (error, res, body) => { @@ -93,20 +90,20 @@ module.exports = DocstoreClient = { ) }, - getAllRanges(project_id, callback) { + getAllRanges(projectId, callback) { request.get( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/ranges`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/ranges`, json: true, }, callback ) }, - updateDoc(project_id, doc_id, lines, version, ranges, callback) { + updateDoc(projectId, docId, lines, version, ranges, callback) { return request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, json: { lines, version, @@ -117,78 +114,78 @@ module.exports = DocstoreClient = { ) }, - deleteDoc(project_id, doc_id, callback) { + deleteDoc(projectId, docId, callback) { DocstoreClient.deleteDocWithDateAndName( - project_id, - doc_id, + projectId, + docId, new Date(), 'main.tex', callback ) }, - deleteDocWithDate(project_id, doc_id, date, callback) { + deleteDocWithDate(projectId, docId, date, callback) { DocstoreClient.deleteDocWithDateAndName( - project_id, - doc_id, + projectId, + docId, date, 'main.tex', callback ) }, - deleteDocWithName(project_id, doc_id, name, callback) { + deleteDocWithName(projectId, docId, name, callback) { DocstoreClient.deleteDocWithDateAndName( - project_id, - doc_id, + projectId, + docId, new Date(), name, callback ) }, - deleteDocWithDateAndName(project_id, doc_id, deletedAt, name, callback) { + deleteDocWithDateAndName(projectId, docId, deletedAt, name, callback) { request.patch( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}`, json: { name, deleted: true, deletedAt }, }, callback ) }, - archiveAllDoc(project_id, callback) { + archiveAllDoc(projectId, callback) { request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/archive`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/archive`, }, callback ) }, - archiveDocById(project_id, doc_id, callback) { + archiveDocById(projectId, docId, callback) { request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/doc/${doc_id}/archive`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/doc/${docId}/archive`, }, callback ) }, - destroyAllDoc(project_id, callback) { + destroyAllDoc(projectId, callback) { request.post( { - url: `http://localhost:${settings.internal.docstore.port}/project/${project_id}/destroy`, + url: `http://localhost:${settings.internal.docstore.port}/project/${projectId}/destroy`, }, callback ) }, - getS3Doc(project_id, doc_id, callback) { + getS3Doc(projectId, docId, callback) { getStringFromPersistor( Persistor, settings.docstore.bucket, - `${project_id}/${doc_id}` + `${projectId}/${docId}` ) .then(data => { callback(null, JSON.parse(data))