mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-14 20:40:17 -05:00
Merge pull request #6120 from overleaf/jpa-same-linting-packages
[misc] move the linting setup to the root of the monorepo GitOrigin-RevId: 1633e2a58598add0b727738cd3bfba0ab7bae781
This commit is contained in:
parent
c8f61e908c
commit
4b308553be
116 changed files with 1034 additions and 48479 deletions
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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": ["lib/**/*.js", "index.js"],
|
||||
"rules": {
|
||||
// don't allow console.log in backend code
|
||||
"no-console": "error",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
1253
libraries/access-token-encryptor/package-lock.json
generated
1253
libraries/access-token-encryptor/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -5,10 +5,10 @@
|
|||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "mocha test/**/*.js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"test:ci": "npm run test"
|
||||
},
|
||||
"author": "",
|
||||
|
@ -20,20 +20,9 @@
|
|||
"devDependencies": {
|
||||
"bunyan": "^1.8.15",
|
||||
"chai": "^4.3.4",
|
||||
"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",
|
||||
"@overleaf/logger": "^2.2.0",
|
||||
"mocha": "^6.2.2",
|
||||
"nock": "0.15.2",
|
||||
"prettier": "^2.2.1",
|
||||
"sandboxed-module": "^2.0.3",
|
||||
"sinon": "^7.5.0"
|
||||
}
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"standard",
|
||||
"prettier",
|
||||
"prettier/standard"
|
||||
],
|
||||
"plugins": [
|
||||
"mocha",
|
||||
"chai-expect",
|
||||
"chai-friendly"
|
||||
],
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"globals": {
|
||||
"expect": true,
|
||||
"define": true,
|
||||
},
|
||||
"settings": {
|
||||
},
|
||||
"rules": {
|
||||
// Add some 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",
|
||||
|
||||
// Add some chai specific rules
|
||||
"chai-expect/missing-assertion": "error",
|
||||
"chai-expect/terminating-properties": "error",
|
||||
// Swap the no-unused-expressions rule with a more chai-friendly one
|
||||
"no-unused-expressions": 0,
|
||||
"chai-friendly/no-unused-expressions": "error"
|
||||
}
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
|
@ -14,7 +14,7 @@ const ENTRY_FIELDS_TO_OMIT = [
|
|||
'msg',
|
||||
'err',
|
||||
'req',
|
||||
'res'
|
||||
'res',
|
||||
]
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,7 +26,7 @@ class LogLevelChecker {
|
|||
} else {
|
||||
this.logger.level(this.defaultLevel)
|
||||
}
|
||||
} catch {
|
||||
} catch (e) {
|
||||
this.logger.level(this.defaultLevel)
|
||||
}
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ class GCEMetadataLogLevelChecker extends LogLevelChecker {
|
|||
async getTracingEndTime() {
|
||||
const options = {
|
||||
headers: {
|
||||
'Metadata-Flavor': 'Google'
|
||||
}
|
||||
'Metadata-Flavor': 'Google',
|
||||
},
|
||||
}
|
||||
const uri = `http://metadata.google.internal/computeMetadata/v1/project/attributes/${this.logger.fields.name}-setLogLevelEndTime`
|
||||
const res = await fetch(uri, options)
|
||||
|
|
|
@ -6,7 +6,7 @@ const SentryManager = require('./sentry-manager')
|
|||
const Serializers = require('./serializers')
|
||||
const {
|
||||
FileLogLevelChecker,
|
||||
GCEMetadataLogLevelChecker
|
||||
GCEMetadataLogLevelChecker,
|
||||
} = require('./log-level-checker')
|
||||
|
||||
const LoggingManager = {
|
||||
|
@ -21,9 +21,9 @@ const LoggingManager = {
|
|||
serializers: {
|
||||
err: Serializers.err,
|
||||
req: Serializers.req,
|
||||
res: Serializers.res
|
||||
res: Serializers.res,
|
||||
},
|
||||
streams: [this._getOutputStreamConfig()]
|
||||
streams: [this._getOutputStreamConfig()],
|
||||
})
|
||||
this._setupRingBuffer()
|
||||
this._setupLogLevelChecker()
|
||||
|
@ -80,9 +80,10 @@ const LoggingManager = {
|
|||
objectMode: true,
|
||||
write(entry, encoding, callback) {
|
||||
const gcpEntry = GCPManager.convertLogEntry(entry)
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(JSON.stringify(gcpEntry, bunyan.safeCycles()))
|
||||
setImmediate(callback)
|
||||
}
|
||||
},
|
||||
})
|
||||
return { level: this.defaultLevel, type: 'raw', stream }
|
||||
} else {
|
||||
|
@ -97,7 +98,7 @@ const LoggingManager = {
|
|||
this.logger.addStream({
|
||||
level: 'trace',
|
||||
type: 'raw',
|
||||
stream: this.ringBuffer
|
||||
stream: this.ringBuffer,
|
||||
})
|
||||
} else {
|
||||
this.ringBuffer = null
|
||||
|
@ -125,13 +126,14 @@ const LoggingManager = {
|
|||
case 'none':
|
||||
break
|
||||
default:
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Unrecognised log level source: ${logLevelSource}`)
|
||||
}
|
||||
if (this.logLevelChecker) {
|
||||
this.logLevelChecker.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
LoggingManager.initialize('default-sharelatex')
|
||||
|
|
11880
libraries/logger/package-lock.json
generated
11880
libraries/logger/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -10,10 +10,10 @@
|
|||
"version": "3.1.0",
|
||||
"scripts": {
|
||||
"test": "mocha --grep=$MOCHA_GREP test/**/*.js",
|
||||
"format": "prettier-eslint $PWD'/**/*.js' --list-different",
|
||||
"format:fix": "prettier-eslint $PWD'/**/*.js' --write",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix .",
|
||||
"test:ci": "npm run test"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -25,19 +25,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^7.3.1",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-chai-expect": "^2.1.0",
|
||||
"eslint-plugin-chai-friendly": "^0.6.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-mocha": "^7.0.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"mocha": "^8.4.0",
|
||||
"prettier": "^2.0.5",
|
||||
"prettier-eslint-cli": "^5.0.0",
|
||||
"sandboxed-module": "^2.0.4",
|
||||
"sinon": "^9.0.2",
|
||||
"sinon-chai": "^3.5.0"
|
||||
|
|
|
@ -81,7 +81,7 @@ class SentryManager {
|
|||
url: req.originalUrl,
|
||||
query: req.query,
|
||||
headers: req.headers,
|
||||
ip: req.ip
|
||||
ip: req.ip,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ function errSerializer(err) {
|
|||
stack: err.stack && OError.getFullStack(err),
|
||||
info: OError.getFullInfo(err),
|
||||
code: err.code,
|
||||
signal: err.signal
|
||||
signal: err.signal,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ function reqSerializer(req) {
|
|||
headers: {
|
||||
referer: headers.referer || headers.referrer,
|
||||
'user-agent': headers['user-agent'],
|
||||
'content-length': headers['content-length']
|
||||
}
|
||||
'content-length': headers['content-length'],
|
||||
},
|
||||
}
|
||||
const projectId =
|
||||
req.params.projectId || req.params.project_id || req.params.Project_id
|
||||
|
@ -52,8 +52,8 @@ function resSerializer(res) {
|
|||
return {
|
||||
statusCode: res.statusCode,
|
||||
headers: {
|
||||
'content-length': res.getHeader && res.getHeader('content-length')
|
||||
}
|
||||
'content-length': res.getHeader && res.getHeader('content-length'),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,5 +7,5 @@ chai.should()
|
|||
chai.use(sinonChai)
|
||||
|
||||
SandboxedModule.configure({
|
||||
globals: { Buffer, JSON, console, process }
|
||||
globals: { Buffer, JSON, console, process },
|
||||
})
|
||||
|
|
|
@ -18,12 +18,12 @@ describe('LogLevelChecker', function () {
|
|||
beforeEach(function () {
|
||||
this.logger = {
|
||||
level: sinon.stub(),
|
||||
fields: { name: 'myapp' }
|
||||
fields: { name: 'myapp' },
|
||||
}
|
||||
this.fetchResponse = {
|
||||
text: sinon.stub().resolves(''),
|
||||
status: 200,
|
||||
ok: true
|
||||
ok: true,
|
||||
}
|
||||
this.fetch = sinon
|
||||
.stub()
|
||||
|
@ -35,8 +35,8 @@ describe('LogLevelChecker', function () {
|
|||
|
||||
this.fs = {
|
||||
promises: {
|
||||
readFile: sinon.stub()
|
||||
}
|
||||
readFile: sinon.stub(),
|
||||
},
|
||||
}
|
||||
|
||||
this.clock = sinon.useFakeTimers(NOW)
|
||||
|
@ -44,8 +44,8 @@ describe('LogLevelChecker', function () {
|
|||
this.module = SandboxedModule.require(MODULE_PATH, {
|
||||
requires: {
|
||||
'node-fetch': this.fetch,
|
||||
fs: this.fs
|
||||
}
|
||||
fs: this.fs,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -16,43 +16,43 @@ describe('LoggingManager', function () {
|
|||
fatal: sinon.stub(),
|
||||
info: sinon.stub(),
|
||||
level: sinon.stub(),
|
||||
warn: sinon.stub()
|
||||
warn: sinon.stub(),
|
||||
}
|
||||
this.Bunyan = {
|
||||
createLogger: sinon.stub().returns(this.bunyanLogger),
|
||||
RingBuffer: bunyan.RingBuffer
|
||||
RingBuffer: bunyan.RingBuffer,
|
||||
}
|
||||
this.stackdriverStreamConfig = { stream: 'stackdriver' }
|
||||
this.stackdriverClient = {
|
||||
stream: sinon.stub().returns(this.stackdriverStreamConfig)
|
||||
stream: sinon.stub().returns(this.stackdriverStreamConfig),
|
||||
}
|
||||
this.GCPLogging = {
|
||||
LoggingBunyan: sinon.stub().returns(this.stackdriverClient)
|
||||
LoggingBunyan: sinon.stub().returns(this.stackdriverClient),
|
||||
}
|
||||
this.FileLogLevelChecker = {
|
||||
start: sinon.stub(),
|
||||
stop: sinon.stub()
|
||||
stop: sinon.stub(),
|
||||
}
|
||||
this.GCEMetadataLogLevelChecker = {
|
||||
start: sinon.stub(),
|
||||
stop: sinon.stub()
|
||||
stop: sinon.stub(),
|
||||
}
|
||||
this.LogLevelChecker = {
|
||||
FileLogLevelChecker: sinon.stub().returns(this.FileLogLevelChecker),
|
||||
GCEMetadataLogLevelChecker: sinon
|
||||
.stub()
|
||||
.returns(this.GCEMetadataLogLevelChecker)
|
||||
.returns(this.GCEMetadataLogLevelChecker),
|
||||
}
|
||||
this.SentryManager = {
|
||||
captureException: sinon.stub(),
|
||||
captureExceptionRateLimited: sinon.stub()
|
||||
captureExceptionRateLimited: sinon.stub(),
|
||||
}
|
||||
this.LoggingManager = SandboxedModule.require(MODULE_PATH, {
|
||||
requires: {
|
||||
bunyan: this.Bunyan,
|
||||
'./log-level-checker': this.LogLevelChecker,
|
||||
'./sentry-manager': sinon.stub().returns(this.SentryManager)
|
||||
}
|
||||
'./sentry-manager': sinon.stub().returns(this.SentryManager),
|
||||
},
|
||||
})
|
||||
this.loggerName = 'test'
|
||||
this.logger = this.LoggingManager.initialize(this.loggerName)
|
||||
|
@ -86,7 +86,9 @@ describe('LoggingManager', function () {
|
|||
this.logger = this.LoggingManager.initialize(this.loggerName)
|
||||
})
|
||||
|
||||
afterEach(() => delete process.env.NODE_ENV)
|
||||
afterEach(function () {
|
||||
delete process.env.NODE_ENV
|
||||
})
|
||||
|
||||
it('should default to log level warn', function () {
|
||||
this.Bunyan.createLogger.firstCall.args[0].streams[0].level.should.equal(
|
||||
|
@ -106,7 +108,9 @@ describe('LoggingManager', function () {
|
|||
this.LoggingManager.initialize()
|
||||
})
|
||||
|
||||
afterEach(() => delete process.env.LOG_LEVEL)
|
||||
afterEach(function () {
|
||||
delete process.env.LOG_LEVEL
|
||||
})
|
||||
|
||||
it('should use custom log level', function () {
|
||||
this.Bunyan.createLogger.firstCall.args[0].streams[0].level.should.equal(
|
||||
|
@ -169,7 +173,7 @@ describe('LoggingManager', function () {
|
|||
this.logBufferMock = [
|
||||
{ msg: 'log 1' },
|
||||
{ msg: 'log 2' },
|
||||
{ level: 50, msg: 'error' }
|
||||
{ level: 50, msg: 'error' },
|
||||
]
|
||||
})
|
||||
|
||||
|
@ -188,7 +192,7 @@ describe('LoggingManager', function () {
|
|||
it('should include buffered logs in error log and filter out error logs in buffer', function () {
|
||||
this.bunyanLogger.error.lastCall.args[0].logBuffer.should.deep.equal([
|
||||
{ msg: 'log 1' },
|
||||
{ msg: 'log 2' }
|
||||
{ msg: 'log 2' },
|
||||
])
|
||||
})
|
||||
})
|
||||
|
|
|
@ -10,12 +10,12 @@ describe('SentryManager', function () {
|
|||
this.clock = sinon.useFakeTimers(Date.now())
|
||||
this.Sentry = {
|
||||
init: sinon.stub(),
|
||||
captureException: sinon.stub()
|
||||
captureException: sinon.stub(),
|
||||
}
|
||||
this.SentryManager = SandboxedModule.require(MODULE_PATH, {
|
||||
requires: {
|
||||
'@sentry/node': this.Sentry
|
||||
}
|
||||
'@sentry/node': this.Sentry,
|
||||
},
|
||||
})
|
||||
this.sentryManager = new this.SentryManager('test_dsn')
|
||||
})
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"standard",
|
||||
"prettier",
|
||||
"prettier/standard"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"plugins": [
|
||||
"mocha",
|
||||
"chai-expect",
|
||||
"chai-friendly"
|
||||
],
|
||||
"env": {
|
||||
"node": 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"],
|
||||
"env": {
|
||||
"mocha": true
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
|
@ -19,7 +19,7 @@ module.exports = {
|
|||
}
|
||||
// monitor delay in setInterval to detect event loop blocking
|
||||
let previous = Date.now()
|
||||
const intervalId = setInterval(function() {
|
||||
const intervalId = setInterval(function () {
|
||||
const now = Date.now()
|
||||
const offset = now - previous - interval
|
||||
if (offset > logThreshold) {
|
||||
|
@ -30,5 +30,5 @@ module.exports = {
|
|||
}, interval)
|
||||
|
||||
return Metrics.registerDestructor(() => clearInterval(intervalId))
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
const Metrics = require('./index')
|
||||
|
||||
module.exports.monitor = logger =>
|
||||
function(req, res, next) {
|
||||
function (req, res, next) {
|
||||
const startTime = Date.now()
|
||||
const { end } = res
|
||||
res.end = function(...args) {
|
||||
res.end = function (...args) {
|
||||
end.apply(this, args)
|
||||
const responseTimeMs = Date.now() - startTime
|
||||
const requestSize = parseInt(req.headers['content-length'], 10)
|
||||
|
@ -15,13 +15,13 @@ module.exports.monitor = logger =>
|
|||
Metrics.timing('http_request', responseTimeMs, null, {
|
||||
method: req.method,
|
||||
status_code: res.statusCode,
|
||||
path: routePath
|
||||
path: routePath,
|
||||
})
|
||||
if (requestSize) {
|
||||
Metrics.summary('http_request_size_bytes', requestSize, {
|
||||
method: req.method,
|
||||
status_code: res.statusCode,
|
||||
path: routePath
|
||||
path: routePath,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,8 +50,8 @@ function initialize(appName, opts = {}) {
|
|||
allowExpressions: true,
|
||||
serviceContext: {
|
||||
service: appName,
|
||||
version: process.env.BUILD_VERSION
|
||||
}
|
||||
version: process.env.BUILD_VERSION,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -62,8 +62,8 @@ function initialize(appName, opts = {}) {
|
|||
profiler.start({
|
||||
serviceContext: {
|
||||
service: appName,
|
||||
version: process.env.BUILD_VERSION
|
||||
}
|
||||
version: process.env.BUILD_VERSION,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -78,9 +78,9 @@ function injectMetricsRoute(app) {
|
|||
app.get(
|
||||
'/metrics',
|
||||
ExpressCompression({
|
||||
level: parseInt(process.env.METRICS_COMPRESSION_LEVEL || '1', 10)
|
||||
level: parseInt(process.env.METRICS_COMPRESSION_LEVEL || '1', 10),
|
||||
}),
|
||||
function(req, res) {
|
||||
function (req, res) {
|
||||
res.set('Content-Type', promWrapper.registry.contentType)
|
||||
res.end(promWrapper.registry.metrics())
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ let gcInterval = 1 // how many minutes between gc (parameter is dynamically adju
|
|||
let countSinceLastGc = 0 // how many minutes since last gc
|
||||
const MemoryChunkSize = 4 // how many megabytes we need to free to consider gc worth doing
|
||||
|
||||
const readyToGc = function() {
|
||||
const readyToGc = function () {
|
||||
// update allowed cpu time
|
||||
CpuTimeBucket = CpuTimeBucket + CpuTimeBucketRate
|
||||
CpuTimeBucket =
|
||||
|
@ -32,7 +32,7 @@ const readyToGc = function() {
|
|||
return countSinceLastGc > gcInterval && CpuTimeBucket > 0
|
||||
}
|
||||
|
||||
const executeAndTime = function(fn) {
|
||||
const executeAndTime = function (fn) {
|
||||
// time the execution of fn() and subtract from cpu allowance
|
||||
const t0 = process.hrtime()
|
||||
fn()
|
||||
|
@ -42,7 +42,7 @@ const executeAndTime = function(fn) {
|
|||
return timeTaken
|
||||
}
|
||||
|
||||
const inMegaBytes = function(obj) {
|
||||
const inMegaBytes = function (obj) {
|
||||
// convert process.memoryUsage hash {rss,heapTotal,heapFreed} into megabytes
|
||||
const result = {}
|
||||
for (const k in obj) {
|
||||
|
@ -52,7 +52,7 @@ const inMegaBytes = function(obj) {
|
|||
return result
|
||||
}
|
||||
|
||||
const updateMemoryStats = function(oldMem, newMem) {
|
||||
const updateMemoryStats = function (oldMem, newMem) {
|
||||
countSinceLastGc = 0
|
||||
const delta = {}
|
||||
for (const k in newMem) {
|
||||
|
@ -100,7 +100,7 @@ module.exports = MemoryMonitor = {
|
|||
memAfterGc,
|
||||
deltaMem,
|
||||
gcInterval,
|
||||
CpuTimeBucket
|
||||
CpuTimeBucket,
|
||||
},
|
||||
'global.gc() forced'
|
||||
)
|
||||
|
@ -109,5 +109,5 @@ module.exports = MemoryMonitor = {
|
|||
Metrics.gauge('memory.gc-heaptotal-freed', -deltaMem.heapTotal)
|
||||
return Metrics.gauge('memory.gc-heapused-freed', -deltaMem.heapUsed)
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ module.exports = {
|
|||
|
||||
const Metrics = require('./index')
|
||||
|
||||
const monitorMethod = function(base, method, type) {
|
||||
const monitorMethod = function (base, method, type) {
|
||||
let _method
|
||||
if (base == null) {
|
||||
return
|
||||
|
@ -32,7 +32,7 @@ module.exports = {
|
|||
}
|
||||
const arglen = _method.length
|
||||
|
||||
const mongoDriverV1Wrapper = function(dbCommand, options, callback) {
|
||||
const mongoDriverV1Wrapper = function (dbCommand, options, callback) {
|
||||
let query
|
||||
if (typeof callback === 'undefined') {
|
||||
callback = options
|
||||
|
@ -46,21 +46,19 @@ module.exports = {
|
|||
}
|
||||
|
||||
if (dbCommand.query != null) {
|
||||
query = Object.keys(dbCommand.query)
|
||||
.sort()
|
||||
.join('_')
|
||||
query = Object.keys(dbCommand.query).sort().join('_')
|
||||
}
|
||||
|
||||
const timer = new Metrics.Timer('mongo', { collection, query })
|
||||
const start = new Date()
|
||||
return _method.call(this, dbCommand, options, function() {
|
||||
return _method.call(this, dbCommand, options, function () {
|
||||
timer.done()
|
||||
logger.log(
|
||||
{
|
||||
query: dbCommand.query,
|
||||
query_type: type,
|
||||
collection,
|
||||
'response-time': new Date() - start
|
||||
'response-time': new Date() - start,
|
||||
},
|
||||
'mongo request'
|
||||
)
|
||||
|
@ -68,7 +66,7 @@ module.exports = {
|
|||
})
|
||||
}
|
||||
|
||||
const mongoDriverV2Wrapper = function(ns, ops, options, callback) {
|
||||
const mongoDriverV2Wrapper = function (ns, ops, options, callback) {
|
||||
let query
|
||||
if (typeof callback === 'undefined') {
|
||||
callback = options
|
||||
|
@ -83,22 +81,20 @@ module.exports = {
|
|||
let key = `mongo-requests.${ns}.${type}`
|
||||
if (ops[0].q != null) {
|
||||
// ops[0].q
|
||||
query = Object.keys(ops[0].q)
|
||||
.sort()
|
||||
.join('_')
|
||||
query = Object.keys(ops[0].q).sort().join('_')
|
||||
key += '.' + query
|
||||
}
|
||||
|
||||
const timer = new Metrics.Timer(key)
|
||||
const start = new Date()
|
||||
return _method.call(this, ns, ops, options, function() {
|
||||
return _method.call(this, ns, ops, options, function () {
|
||||
timer.done()
|
||||
logger.log(
|
||||
{
|
||||
query: ops[0].q,
|
||||
query_type: type,
|
||||
collection: ns,
|
||||
'response-time': new Date() - start
|
||||
'response-time': new Date() - start,
|
||||
},
|
||||
'mongo request'
|
||||
)
|
||||
|
@ -196,5 +192,5 @@ module.exports = {
|
|||
'update',
|
||||
'update'
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
|
@ -48,5 +48,5 @@ module.exports = OpenSocketsMonitor = {
|
|||
gaugeOpenSockets() {
|
||||
collectOpenConnections(SOCKETS_HTTP, SEEN_HOSTS_HTTP, 'http')
|
||||
collectOpenConnections(SOCKETS_HTTPS, SEEN_HOSTS_HTTPS, 'https')
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
9447
libraries/metrics/package-lock.json
generated
9447
libraries/metrics/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -17,29 +17,18 @@
|
|||
"devDependencies": {
|
||||
"bunyan": "^1.0.0",
|
||||
"chai": "^4.2.0",
|
||||
"eslint": "^7.8.1",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-chai-expect": "^2.2.0",
|
||||
"eslint-plugin-chai-friendly": "^0.6.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-mocha": "^8.0.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"mocha": "^8.0.1",
|
||||
"prettier-eslint-cli": "^5.0.0",
|
||||
"sandboxed-module": "^2.0.4",
|
||||
"sinon": "^9.0.2"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix .",
|
||||
"test:unit": "mocha --reporter spec --recursive --exit --grep=$MOCHA_GREP test/unit",
|
||||
"test:acceptance": "mocha --reporter spec --recursive --exit --grep=$MOCHA_GREP test/acceptance",
|
||||
"test": "npm run test:unit && npm run test:acceptance",
|
||||
"format": "prettier-eslint $PWD'/**/*.js' --list-different",
|
||||
"format:fix": "prettier-eslint $PWD'/**/*.js' --write",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"test:ci": "npm run test"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -9,7 +9,7 @@ const prom = require('prom-client')
|
|||
const registry = require('prom-client').register
|
||||
const metrics = new Map()
|
||||
|
||||
const optsKey = function(opts) {
|
||||
const optsKey = function (opts) {
|
||||
let keys = Object.keys(opts)
|
||||
if (keys.length === 0) {
|
||||
return ''
|
||||
|
@ -28,7 +28,7 @@ const optsKey = function(opts) {
|
|||
return hash
|
||||
}
|
||||
|
||||
const extendOpts = function(opts, labelNames) {
|
||||
const extendOpts = function (opts, labelNames) {
|
||||
for (const label of Array.from(labelNames)) {
|
||||
if (!opts[label]) {
|
||||
opts[label] = ''
|
||||
|
@ -37,7 +37,7 @@ const extendOpts = function(opts, labelNames) {
|
|||
return opts
|
||||
}
|
||||
|
||||
const optsAsArgs = function(opts, labelNames) {
|
||||
const optsAsArgs = function (opts, labelNames) {
|
||||
const args = []
|
||||
for (const label of Array.from(labelNames)) {
|
||||
args.push(opts[label] || '')
|
||||
|
@ -53,7 +53,7 @@ const PromWrapper = {
|
|||
return metrics.get(name) || new MetricWrapper(type, name)
|
||||
},
|
||||
|
||||
collectDefaultMetrics: prom.collectDefaultMetrics
|
||||
collectDefaultMetrics: prom.collectDefaultMetrics,
|
||||
}
|
||||
|
||||
class MetricWrapper {
|
||||
|
@ -68,7 +68,7 @@ class MetricWrapper {
|
|||
return new prom.Counter({
|
||||
name,
|
||||
help: name,
|
||||
labelNames: ['status', 'method', 'path']
|
||||
labelNames: ['status', 'method', 'path'],
|
||||
})
|
||||
case 'summary':
|
||||
return new prom.Summary({
|
||||
|
@ -76,13 +76,19 @@ class MetricWrapper {
|
|||
help: name,
|
||||
maxAgeSeconds: 60,
|
||||
ageBuckets: 10,
|
||||
labelNames: ['path', 'status_code', 'method', 'collection', 'query']
|
||||
labelNames: [
|
||||
'path',
|
||||
'status_code',
|
||||
'method',
|
||||
'collection',
|
||||
'query',
|
||||
],
|
||||
})
|
||||
case 'gauge':
|
||||
return new prom.Gauge({
|
||||
name,
|
||||
help: name,
|
||||
labelNames: ['host', 'status']
|
||||
labelNames: ['host', 'status'],
|
||||
})
|
||||
}
|
||||
})()
|
||||
|
@ -105,6 +111,7 @@ class MetricWrapper {
|
|||
this.instances.forEach((instance, key) => {
|
||||
if (thresh > instance.time) {
|
||||
if (process.env.DEBUG_METRICS) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(
|
||||
'Sweeping stale metric instance',
|
||||
this.name,
|
||||
|
@ -120,6 +127,7 @@ class MetricWrapper {
|
|||
|
||||
if (thresh > this.lastAccess) {
|
||||
if (process.env.DEBUG_METRICS) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Sweeping stale metric', this.name, thresh, this.lastAccess)
|
||||
}
|
||||
metrics.delete(this.name)
|
||||
|
@ -139,21 +147,24 @@ class MetricWrapper {
|
|||
}
|
||||
|
||||
let sweepingInterval
|
||||
PromWrapper.setupSweeping = function() {
|
||||
PromWrapper.setupSweeping = function () {
|
||||
if (sweepingInterval) {
|
||||
clearInterval(sweepingInterval)
|
||||
}
|
||||
if (!PromWrapper.ttlInMinutes) {
|
||||
if (process.env.DEBUG_METRICS) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Not registering sweep method -- empty ttl')
|
||||
}
|
||||
return
|
||||
}
|
||||
if (process.env.DEBUG_METRICS) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Registering sweep method')
|
||||
}
|
||||
sweepingInterval = setInterval(function() {
|
||||
sweepingInterval = setInterval(function () {
|
||||
if (process.env.DEBUG_METRICS) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Sweeping metrics')
|
||||
}
|
||||
return metrics.forEach((metric, key) => {
|
||||
|
|
|
@ -6,24 +6,24 @@ const Metrics = require('../..')
|
|||
const HOSTNAME = os.hostname()
|
||||
const APP_NAME = 'test-app'
|
||||
|
||||
describe('Metrics module', function() {
|
||||
before(function() {
|
||||
describe('Metrics module', function () {
|
||||
before(function () {
|
||||
Metrics.initialize(APP_NAME)
|
||||
})
|
||||
|
||||
describe('at startup', function() {
|
||||
it('increments the process_startup counter', async function() {
|
||||
describe('at startup', function () {
|
||||
it('increments the process_startup counter', async function () {
|
||||
await expectMetricValue('process_startup', 1)
|
||||
})
|
||||
|
||||
it('collects default metrics', async function() {
|
||||
it('collects default metrics', async function () {
|
||||
const metric = await getMetric('process_cpu_user_seconds_total')
|
||||
expect(metric).to.exist
|
||||
})
|
||||
})
|
||||
|
||||
describe('inc()', function() {
|
||||
it('increments counts by 1', async function() {
|
||||
describe('inc()', function () {
|
||||
it('increments counts by 1', async function () {
|
||||
Metrics.inc('duck_count')
|
||||
await expectMetricValue('duck_count', 1)
|
||||
Metrics.inc('duck_count')
|
||||
|
@ -31,14 +31,14 @@ describe('Metrics module', function() {
|
|||
await expectMetricValue('duck_count', 3)
|
||||
})
|
||||
|
||||
it('escapes special characters in the key', async function() {
|
||||
it('escapes special characters in the key', async function () {
|
||||
Metrics.inc('show.me the $!!')
|
||||
await expectMetricValue('show_me_the____', 1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('count()', function() {
|
||||
it('increments counts by the given count', async function() {
|
||||
describe('count()', function () {
|
||||
it('increments counts by the given count', async function () {
|
||||
Metrics.count('rabbit_count', 5)
|
||||
await expectMetricValue('rabbit_count', 5)
|
||||
Metrics.count('rabbit_count', 6)
|
||||
|
@ -47,8 +47,8 @@ describe('Metrics module', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('summary()', function() {
|
||||
it('collects observations', async function() {
|
||||
describe('summary()', function () {
|
||||
it('collects observations', async function () {
|
||||
Metrics.summary('oven_temp', 200)
|
||||
Metrics.summary('oven_temp', 300)
|
||||
Metrics.summary('oven_temp', 450)
|
||||
|
@ -57,8 +57,8 @@ describe('Metrics module', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('timing()', function() {
|
||||
it('collects timings', async function() {
|
||||
describe('timing()', function () {
|
||||
it('collects timings', async function () {
|
||||
Metrics.timing('sprint_100m', 10)
|
||||
Metrics.timing('sprint_100m', 20)
|
||||
Metrics.timing('sprint_100m', 30)
|
||||
|
@ -67,8 +67,8 @@ describe('Metrics module', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('gauge()', function() {
|
||||
it('records values', async function() {
|
||||
describe('gauge()', function () {
|
||||
it('records values', async function () {
|
||||
Metrics.gauge('water_level', 1.5)
|
||||
await expectMetricValue('water_level', 1.5)
|
||||
Metrics.gauge('water_level', 4.2)
|
||||
|
@ -76,8 +76,8 @@ describe('Metrics module', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('globalGauge()', function() {
|
||||
it('records values without a host label', async function() {
|
||||
describe('globalGauge()', function () {
|
||||
it('records values without a host label', async function () {
|
||||
Metrics.globalGauge('tire_pressure', 99.99)
|
||||
const { value, labels } = await getMetricValue('tire_pressure')
|
||||
expect(value).to.equal(99.99)
|
||||
|
@ -86,7 +86,7 @@ describe('Metrics module', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('open_sockets', function() {
|
||||
describe('open_sockets', function () {
|
||||
const keyServer1 = 'open_connections_http_127_42_42_1'
|
||||
const keyServer2 = 'open_connections_http_127_42_42_2'
|
||||
|
||||
|
@ -131,52 +131,52 @@ describe('Metrics module', function() {
|
|||
urlServer1 = `http://127.42.42.1:${server1.address().port}/`
|
||||
urlServer2 = `http://127.42.42.2:${server2.address().port}/`
|
||||
})
|
||||
describe('gaugeOpenSockets()', function() {
|
||||
describe('gaugeOpenSockets()', function () {
|
||||
beforeEach(function runGaugeOpenSockets() {
|
||||
Metrics.open_sockets.gaugeOpenSockets()
|
||||
})
|
||||
|
||||
describe('without pending connections', function() {
|
||||
it('emits no open_connections', async function() {
|
||||
describe('without pending connections', function () {
|
||||
it('emits no open_connections', async function () {
|
||||
await expectNoMetricValue(keyServer1)
|
||||
await expectNoMetricValue(keyServer2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with pending connections for server1', function() {
|
||||
before(function(done) {
|
||||
describe('with pending connections for server1', function () {
|
||||
before(function (done) {
|
||||
http.get(urlServer1)
|
||||
http.get(urlServer1)
|
||||
setTimeout(done, 10)
|
||||
})
|
||||
|
||||
it('emits 2 open_connections for server1', async function() {
|
||||
it('emits 2 open_connections for server1', async function () {
|
||||
await expectMetricValue(keyServer1, 2)
|
||||
})
|
||||
|
||||
it('emits no open_connections for server2', async function() {
|
||||
it('emits no open_connections for server2', async function () {
|
||||
await expectNoMetricValue(keyServer2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with pending connections for server1 and server2', function() {
|
||||
before(function(done) {
|
||||
describe('with pending connections for server1 and server2', function () {
|
||||
before(function (done) {
|
||||
http.get(urlServer2)
|
||||
http.get(urlServer2)
|
||||
setTimeout(done, 10)
|
||||
})
|
||||
|
||||
it('emits 2 open_connections for server1', async function() {
|
||||
it('emits 2 open_connections for server1', async function () {
|
||||
await expectMetricValue(keyServer1, 2)
|
||||
})
|
||||
|
||||
it('emits 2 open_connections for server2', async function() {
|
||||
it('emits 2 open_connections for server2', async function () {
|
||||
await expectMetricValue(keyServer2, 2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when requests finish for server1', function() {
|
||||
before(function(done) {
|
||||
describe('when requests finish for server1', function () {
|
||||
before(function (done) {
|
||||
finish1()
|
||||
resetEmitResponse1()
|
||||
http.get(urlServer1)
|
||||
|
@ -184,24 +184,24 @@ describe('Metrics module', function() {
|
|||
setTimeout(done, 10)
|
||||
})
|
||||
|
||||
it('emits 1 open_connections for server1', async function() {
|
||||
it('emits 1 open_connections for server1', async function () {
|
||||
await expectMetricValue(keyServer1, 1)
|
||||
})
|
||||
|
||||
it('emits 2 open_connections for server2', async function() {
|
||||
it('emits 2 open_connections for server2', async function () {
|
||||
await expectMetricValue(keyServer2, 2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when all requests complete', function() {
|
||||
before(function(done) {
|
||||
describe('when all requests complete', function () {
|
||||
before(function (done) {
|
||||
finish1()
|
||||
finish2()
|
||||
|
||||
setTimeout(done, 10)
|
||||
})
|
||||
|
||||
it('emits no open_connections', async function() {
|
||||
it('emits no open_connections', async function () {
|
||||
await expectNoMetricValue(keyServer1)
|
||||
await expectNoMetricValue(keyServer2)
|
||||
})
|
||||
|
|
|
@ -10,34 +10,34 @@ const modulePath = path.join(__dirname, '../../../event_loop.js')
|
|||
const SandboxedModule = require('sandboxed-module')
|
||||
const sinon = require('sinon')
|
||||
|
||||
describe('event_loop', function() {
|
||||
before(function() {
|
||||
describe('event_loop', function () {
|
||||
before(function () {
|
||||
this.metrics = {
|
||||
timing: sinon.stub(),
|
||||
registerDestructor: sinon.stub()
|
||||
registerDestructor: sinon.stub(),
|
||||
}
|
||||
this.logger = {
|
||||
warn: sinon.stub()
|
||||
warn: sinon.stub(),
|
||||
}
|
||||
return (this.event_loop = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
'./index': this.metrics
|
||||
}
|
||||
'./index': this.metrics,
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
describe('with a logger provided', function() {
|
||||
before(function() {
|
||||
describe('with a logger provided', function () {
|
||||
before(function () {
|
||||
return this.event_loop.monitor(this.logger)
|
||||
})
|
||||
|
||||
return it('should register a destructor with metrics', function() {
|
||||
return it('should register a destructor with metrics', function () {
|
||||
return expect(this.metrics.registerDestructor.called).to.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
return describe('without a logger provided', function() {
|
||||
return it('should throw an exception', function() {
|
||||
return describe('without a logger provided', function () {
|
||||
return it('should throw an exception', function () {
|
||||
return expect(this.event_loop.monitor).to.throw('logger is undefined')
|
||||
})
|
||||
})
|
||||
|
|
|
@ -11,28 +11,28 @@ const modulePath = path.join(__dirname, '../../../timeAsyncMethod.js')
|
|||
const SandboxedModule = require('sandboxed-module')
|
||||
const sinon = require('sinon')
|
||||
|
||||
describe('timeAsyncMethod', function() {
|
||||
beforeEach(function() {
|
||||
describe('timeAsyncMethod', function () {
|
||||
beforeEach(function () {
|
||||
this.Timer = { done: sinon.stub() }
|
||||
this.TimerConstructor = sinon.stub().returns(this.Timer)
|
||||
this.metrics = {
|
||||
Timer: this.TimerConstructor,
|
||||
inc: sinon.stub()
|
||||
inc: sinon.stub(),
|
||||
}
|
||||
this.timeAsyncMethod = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
'./index': this.metrics
|
||||
}
|
||||
'./index': this.metrics,
|
||||
},
|
||||
})
|
||||
|
||||
return (this.testObject = {
|
||||
nextNumber(n, callback) {
|
||||
return setTimeout(() => callback(null, n + 1), 100)
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
it('should have the testObject behave correctly before wrapping', function(done) {
|
||||
it('should have the testObject behave correctly before wrapping', function (done) {
|
||||
return this.testObject.nextNumber(2, (err, result) => {
|
||||
expect(err).to.not.exist
|
||||
expect(result).to.equal(3)
|
||||
|
@ -40,7 +40,7 @@ describe('timeAsyncMethod', function() {
|
|||
})
|
||||
})
|
||||
|
||||
it('should wrap method without error', function(done) {
|
||||
it('should wrap method without error', function (done) {
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
'nextNumber',
|
||||
|
@ -49,7 +49,7 @@ describe('timeAsyncMethod', function() {
|
|||
return done()
|
||||
})
|
||||
|
||||
it('should transparently wrap method invocation in timer', function(done) {
|
||||
it('should transparently wrap method invocation in timer', function (done) {
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
'nextNumber',
|
||||
|
@ -64,7 +64,7 @@ describe('timeAsyncMethod', function() {
|
|||
})
|
||||
})
|
||||
|
||||
it('should increment success count', function(done) {
|
||||
it('should increment success count', function (done) {
|
||||
this.metrics.inc = sinon.stub()
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
|
@ -79,22 +79,22 @@ describe('timeAsyncMethod', function() {
|
|||
expect(
|
||||
this.metrics.inc.calledWith('someContext_result', 1, {
|
||||
method: 'TestObject_nextNumber',
|
||||
status: 'success'
|
||||
status: 'success',
|
||||
})
|
||||
).to.equal(true)
|
||||
return done()
|
||||
})
|
||||
})
|
||||
|
||||
describe('when base method produces an error', function() {
|
||||
beforeEach(function() {
|
||||
describe('when base method produces an error', function () {
|
||||
beforeEach(function () {
|
||||
this.metrics.inc = sinon.stub()
|
||||
return (this.testObject.nextNumber = function(n, callback) {
|
||||
return (this.testObject.nextNumber = function (n, callback) {
|
||||
return setTimeout(() => callback(new Error('woops')), 100)
|
||||
})
|
||||
})
|
||||
|
||||
it('should propagate the error transparently', function(done) {
|
||||
it('should propagate the error transparently', function (done) {
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
'nextNumber',
|
||||
|
@ -108,7 +108,7 @@ describe('timeAsyncMethod', function() {
|
|||
})
|
||||
})
|
||||
|
||||
return it('should increment failure count', function(done) {
|
||||
return it('should increment failure count', function (done) {
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
'nextNumber',
|
||||
|
@ -120,7 +120,7 @@ describe('timeAsyncMethod', function() {
|
|||
expect(
|
||||
this.metrics.inc.calledWith('someContext_result', 1, {
|
||||
method: 'TestObject_nextNumber',
|
||||
status: 'failed'
|
||||
status: 'failed',
|
||||
})
|
||||
).to.equal(true)
|
||||
return done()
|
||||
|
@ -128,12 +128,12 @@ describe('timeAsyncMethod', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('when a logger is supplied', function() {
|
||||
beforeEach(function() {
|
||||
describe('when a logger is supplied', function () {
|
||||
beforeEach(function () {
|
||||
return (this.logger = { log: sinon.stub() })
|
||||
})
|
||||
|
||||
return it('should also call logger.log', function(done) {
|
||||
return it('should also call logger.log', function (done) {
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
'nextNumber',
|
||||
|
@ -151,10 +151,10 @@ describe('timeAsyncMethod', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('when the wrapper cannot be applied', function() {
|
||||
beforeEach(function() {})
|
||||
describe('when the wrapper cannot be applied', function () {
|
||||
beforeEach(function () {})
|
||||
|
||||
return it('should raise an error', function() {
|
||||
return it('should raise an error', function () {
|
||||
const badWrap = () => {
|
||||
return this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
|
@ -168,13 +168,13 @@ describe('timeAsyncMethod', function() {
|
|||
})
|
||||
})
|
||||
|
||||
return describe('when the wrapped function is not using a callback', function() {
|
||||
beforeEach(function() {
|
||||
return describe('when the wrapped function is not using a callback', function () {
|
||||
beforeEach(function () {
|
||||
this.realMethod = sinon.stub().returns(42)
|
||||
return (this.testObject.nextNumber = this.realMethod)
|
||||
})
|
||||
|
||||
it('should not throw an error', function() {
|
||||
it('should not throw an error', function () {
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
'nextNumber',
|
||||
|
@ -186,7 +186,7 @@ describe('timeAsyncMethod', function() {
|
|||
return expect(badCall).to.not.throw(Error)
|
||||
})
|
||||
|
||||
return it('should call the underlying method', function() {
|
||||
return it('should call the underlying method', function () {
|
||||
this.timeAsyncMethod(
|
||||
this.testObject,
|
||||
'nextNumber',
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
|
||||
module.exports = function(obj, methodName, prefix, logger) {
|
||||
module.exports = function (obj, methodName, prefix, logger) {
|
||||
let modifedMethodName
|
||||
const metrics = require('./index')
|
||||
|
||||
|
@ -29,7 +29,7 @@ module.exports = function(obj, methodName, prefix, logger) {
|
|||
} else {
|
||||
modifedMethodName = methodName
|
||||
}
|
||||
return (obj[methodName] = function(...originalArgs) {
|
||||
return (obj[methodName] = function (...originalArgs) {
|
||||
const adjustedLength = Math.max(originalArgs.length, 1)
|
||||
const firstArgs = originalArgs.slice(0, adjustedLength - 1)
|
||||
const callback = originalArgs[adjustedLength - 1]
|
||||
|
@ -44,41 +44,43 @@ module.exports = function(obj, methodName, prefix, logger) {
|
|||
}
|
||||
|
||||
const timer = new metrics.Timer(startPrefix, 1, {
|
||||
method: modifedMethodName
|
||||
method: modifedMethodName,
|
||||
})
|
||||
|
||||
return realMethod.call(this, ...Array.from(firstArgs), function(
|
||||
...callbackArgs
|
||||
) {
|
||||
const elapsedTime = timer.done()
|
||||
const possibleError = callbackArgs[0]
|
||||
if (possibleError != null) {
|
||||
metrics.inc(`${startPrefix}_result`, 1, {
|
||||
status: 'failed',
|
||||
method: modifedMethodName
|
||||
})
|
||||
} else {
|
||||
metrics.inc(`${startPrefix}_result`, 1, {
|
||||
status: 'success',
|
||||
method: modifedMethodName
|
||||
})
|
||||
}
|
||||
if (logger != null) {
|
||||
const loggableArgs = {}
|
||||
try {
|
||||
for (let idx = 0; idx < firstArgs.length; idx++) {
|
||||
const arg = firstArgs[idx]
|
||||
if (arg.toString().match(/^[0-9a-f]{24}$/)) {
|
||||
loggableArgs[`${idx}`] = arg
|
||||
return realMethod.call(
|
||||
this,
|
||||
...Array.from(firstArgs),
|
||||
function (...callbackArgs) {
|
||||
const elapsedTime = timer.done()
|
||||
const possibleError = callbackArgs[0]
|
||||
if (possibleError != null) {
|
||||
metrics.inc(`${startPrefix}_result`, 1, {
|
||||
status: 'failed',
|
||||
method: modifedMethodName,
|
||||
})
|
||||
} else {
|
||||
metrics.inc(`${startPrefix}_result`, 1, {
|
||||
status: 'success',
|
||||
method: modifedMethodName,
|
||||
})
|
||||
}
|
||||
if (logger != null) {
|
||||
const loggableArgs = {}
|
||||
try {
|
||||
for (let idx = 0; idx < firstArgs.length; idx++) {
|
||||
const arg = firstArgs[idx]
|
||||
if (arg.toString().match(/^[0-9a-f]{24}$/)) {
|
||||
loggableArgs[`${idx}`] = arg
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {}
|
||||
logger.log(
|
||||
{ key, args: loggableArgs, elapsedTime },
|
||||
'[Metrics] timed async method call'
|
||||
)
|
||||
} catch (error) {}
|
||||
logger.log(
|
||||
{ key, args: loggableArgs, elapsedTime },
|
||||
'[Metrics] timed async method call'
|
||||
)
|
||||
}
|
||||
return callback.apply(this, callbackArgs)
|
||||
}
|
||||
return callback.apply(this, callbackArgs)
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
if (!process.env.UV_THREADPOOL_SIZE) {
|
||||
process.env.UV_THREADPOOL_SIZE = 16
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Set UV_THREADPOOL_SIZE=${process.env.UV_THREADPOOL_SIZE}`)
|
||||
}
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"standard",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:mocha/recommended",
|
||||
"plugin:chai-expect/recommended",
|
||||
"plugin:chai-friendly/recommended"
|
||||
],
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["test/**/*.js"],
|
||||
"env": {
|
||||
"mocha": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
|
@ -140,7 +140,7 @@ class OError extends Error {
|
|||
let stack = oError.stack || '(no stack)'
|
||||
|
||||
if (Array.isArray(oError._oErrorTags) && oError._oErrorTags.length) {
|
||||
stack += `\n${oError._oErrorTags.map((tag) => tag.stack).join('\n')}`
|
||||
stack += `\n${oError._oErrorTags.map(tag => tag.stack).join('\n')}`
|
||||
}
|
||||
|
||||
const causeStack = oError.cause && OError.getFullStack(oError.cause)
|
||||
|
|
1368
libraries/o-error/package-lock.json
generated
1368
libraries/o-error/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -24,15 +24,15 @@
|
|||
"build:compile": "babel index.js --out-dir dist",
|
||||
"declaration:build": "rm -f dist/index.d.ts && tsc --allowJs --declaration --emitDeclarationOnly --outDir dist --moduleResolution node --target ES6 index.js",
|
||||
"declaration:check": "git diff --exit-code -- dist/index.d.ts",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix .",
|
||||
"prepublishOnly": "npm run --silent declaration:build && npm run --silent declaration:check",
|
||||
"test": "mocha",
|
||||
"test:coverage": "nyc --reporter=lcov --reporter=text-summary npm run test",
|
||||
"typecheck": "tsc --allowJs --checkJs --noEmit --moduleResolution node --strict --target ES6 *.js test/**/*.js",
|
||||
"update-readme": "doc/update-readme.js",
|
||||
"format": "prettier $PWD'/**/*.js' --list-different",
|
||||
"format:fix": "prettier $PWD'/**/*.js' --write",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"test:ci": "npm run typecheck && npm run test"
|
||||
},
|
||||
"author": "Overleaf (https://www.overleaf.com)",
|
||||
|
@ -45,22 +45,10 @@
|
|||
"@types/chai": "^4.2.12",
|
||||
"@types/node": "^13.13.2",
|
||||
"chai": "^3.3.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.1",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-chai-expect": "^2.1.0",
|
||||
"eslint-plugin-chai-friendly": "^0.5.0",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-mocha": "^6.3.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"jsdoc-to-markdown": "^5.0.3",
|
||||
"markdown-toc": "^1.2.0",
|
||||
"mocha": "^7.1.1",
|
||||
"nyc": "^15.0.1",
|
||||
"prettier": "^2.0.2",
|
||||
"typescript": "^3.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -8,400 +8,406 @@ const {
|
|||
expectFullStackWithoutStackFramesToEqual,
|
||||
} = require('./support')
|
||||
|
||||
describe('OError.tag', function () {
|
||||
it('tags errors thrown from an async function', async function () {
|
||||
const delay = promisify(setTimeout)
|
||||
describe('utils', function () {
|
||||
describe('OError.tag', function () {
|
||||
it('tags errors thrown from an async function', async function () {
|
||||
const delay = promisify(setTimeout)
|
||||
|
||||
async function foo() {
|
||||
await delay(10)
|
||||
throw new Error('foo error')
|
||||
}
|
||||
|
||||
async function bar() {
|
||||
try {
|
||||
await foo()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
||||
async function foo() {
|
||||
await delay(10)
|
||||
throw new Error('foo error')
|
||||
}
|
||||
}
|
||||
|
||||
async function baz() {
|
||||
try {
|
||||
await bar()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await baz()
|
||||
expect.fail('should have thrown')
|
||||
} catch (error) {
|
||||
expectError(error, {
|
||||
name: 'Error',
|
||||
klass: Error,
|
||||
message: 'Error: foo error',
|
||||
firstFrameRx: /at foo/,
|
||||
})
|
||||
expectFullStackWithoutStackFramesToEqual(error, [
|
||||
'Error: foo error',
|
||||
'TaggedError: failed to bar',
|
||||
'TaggedError: failed to baz',
|
||||
])
|
||||
expect(OError.getFullInfo(error)).to.eql({
|
||||
bar: 'baz',
|
||||
baz: 'bat',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('tags errors thrown from a promise rejection', async function () {
|
||||
function foo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(function () {
|
||||
reject(new Error('foo error'))
|
||||
}, 10)
|
||||
})
|
||||
}
|
||||
|
||||
async function bar() {
|
||||
try {
|
||||
await foo()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
||||
}
|
||||
}
|
||||
|
||||
async function baz() {
|
||||
try {
|
||||
await bar()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await baz()
|
||||
expect.fail('should have thrown')
|
||||
} catch (error) {
|
||||
expectError(error, {
|
||||
name: 'Error',
|
||||
klass: Error,
|
||||
message: 'Error: foo error',
|
||||
firstFrameRx: /_onTimeout/,
|
||||
})
|
||||
expectFullStackWithoutStackFramesToEqual(error, [
|
||||
'Error: foo error',
|
||||
'TaggedError: failed to bar',
|
||||
'TaggedError: failed to baz',
|
||||
])
|
||||
expect(OError.getFullInfo(error)).to.eql({
|
||||
bar: 'baz',
|
||||
baz: 'bat',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('tags errors yielded through callbacks', function (done) {
|
||||
function foo(cb) {
|
||||
setTimeout(function () {
|
||||
cb(new Error('foo error'))
|
||||
}, 10)
|
||||
}
|
||||
|
||||
function bar(cb) {
|
||||
foo(function (err) {
|
||||
if (err) {
|
||||
return cb(OError.tag(err, 'failed to bar', { bar: 'baz' }))
|
||||
async function bar() {
|
||||
try {
|
||||
await foo()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
||||
}
|
||||
cb()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function baz(cb) {
|
||||
bar(function (err) {
|
||||
if (err) {
|
||||
return cb(OError.tag(err, 'failed to baz', { baz: 'bat' }))
|
||||
async function baz() {
|
||||
try {
|
||||
await bar()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
||||
}
|
||||
cb()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
baz(function (err) {
|
||||
if (err) {
|
||||
expectError(err, {
|
||||
try {
|
||||
await baz()
|
||||
expect.fail('should have thrown')
|
||||
} catch (error) {
|
||||
expectError(error, {
|
||||
name: 'Error',
|
||||
klass: Error,
|
||||
message: 'Error: foo error',
|
||||
firstFrameRx: /at foo/,
|
||||
})
|
||||
expectFullStackWithoutStackFramesToEqual(error, [
|
||||
'Error: foo error',
|
||||
'TaggedError: failed to bar',
|
||||
'TaggedError: failed to baz',
|
||||
])
|
||||
expect(OError.getFullInfo(error)).to.eql({
|
||||
bar: 'baz',
|
||||
baz: 'bat',
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
it('tags errors thrown from a promise rejection', async function () {
|
||||
function foo() {
|
||||
return new Promise((resolve, reject) => {
|
||||
setTimeout(() => {
|
||||
reject(new Error('foo error'))
|
||||
}, 10)
|
||||
})
|
||||
}
|
||||
|
||||
async function bar() {
|
||||
try {
|
||||
await foo()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to bar', { bar: 'baz' })
|
||||
}
|
||||
}
|
||||
|
||||
async function baz() {
|
||||
try {
|
||||
await bar()
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to baz', { baz: 'bat' })
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await baz()
|
||||
expect.fail('should have thrown')
|
||||
} catch (error) {
|
||||
expectError(error, {
|
||||
name: 'Error',
|
||||
klass: Error,
|
||||
message: 'Error: foo error',
|
||||
firstFrameRx: /_onTimeout/,
|
||||
})
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
expectFullStackWithoutStackFramesToEqual(error, [
|
||||
'Error: foo error',
|
||||
'TaggedError: failed to bar',
|
||||
'TaggedError: failed to baz',
|
||||
])
|
||||
expect(OError.getFullInfo(err)).to.eql({
|
||||
expect(OError.getFullInfo(error)).to.eql({
|
||||
bar: 'baz',
|
||||
baz: 'bat',
|
||||
})
|
||||
return done()
|
||||
}
|
||||
expect.fail('should have yielded an error')
|
||||
})
|
||||
})
|
||||
|
||||
it('is not included in the stack trace if using capture', function () {
|
||||
if (!Error.captureStackTrace) return this.skip()
|
||||
const err = new Error('test error')
|
||||
OError.tag(err, 'test message')
|
||||
const stack = OError.getFullStack(err)
|
||||
expect(stack).to.match(/TaggedError: test message\n\s+at/)
|
||||
expect(stack).to.not.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
||||
})
|
||||
|
||||
describe('without Error.captureStackTrace', function () {
|
||||
/* eslint-disable mocha/no-hooks-for-single-case */
|
||||
before(function () {
|
||||
this.originalCaptureStackTrace = Error.captureStackTrace
|
||||
Error.captureStackTrace = null
|
||||
})
|
||||
after(function () {
|
||||
Error.captureStackTrace = this.originalCaptureStackTrace
|
||||
})
|
||||
|
||||
it('still captures a stack trace, albeit including itself', function () {
|
||||
it('tags errors yielded through callbacks', function (done) {
|
||||
function foo(cb) {
|
||||
setTimeout(() => {
|
||||
cb(new Error('foo error'))
|
||||
}, 10)
|
||||
}
|
||||
|
||||
function bar(cb) {
|
||||
foo(err => {
|
||||
if (err) {
|
||||
return cb(OError.tag(err, 'failed to bar', { bar: 'baz' }))
|
||||
}
|
||||
cb()
|
||||
})
|
||||
}
|
||||
|
||||
function baz(cb) {
|
||||
bar(err => {
|
||||
if (err) {
|
||||
return cb(OError.tag(err, 'failed to baz', { baz: 'bat' }))
|
||||
}
|
||||
cb()
|
||||
})
|
||||
}
|
||||
|
||||
baz(err => {
|
||||
if (err) {
|
||||
expectError(err, {
|
||||
name: 'Error',
|
||||
klass: Error,
|
||||
message: 'Error: foo error',
|
||||
firstFrameRx: /_onTimeout/,
|
||||
})
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
'Error: foo error',
|
||||
'TaggedError: failed to bar',
|
||||
'TaggedError: failed to baz',
|
||||
])
|
||||
expect(OError.getFullInfo(err)).to.eql({
|
||||
bar: 'baz',
|
||||
baz: 'bat',
|
||||
})
|
||||
return done()
|
||||
}
|
||||
expect.fail('should have yielded an error')
|
||||
})
|
||||
})
|
||||
|
||||
it('is not included in the stack trace if using capture', function () {
|
||||
if (!Error.captureStackTrace) return this.skip()
|
||||
const err = new Error('test error')
|
||||
OError.tag(err, 'test message')
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
'Error: test error',
|
||||
'TaggedError: test message',
|
||||
])
|
||||
const stack = OError.getFullStack(err)
|
||||
expect(stack).to.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('with limit on the number of tags', function () {
|
||||
before(function () {
|
||||
this.originalMaxTags = OError.maxTags
|
||||
OError.maxTags = 3
|
||||
})
|
||||
after(function () {
|
||||
OError.maxTags = this.originalMaxTags
|
||||
expect(stack).to.match(/TaggedError: test message\n\s+at/)
|
||||
expect(stack).to.not.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
||||
})
|
||||
|
||||
it('should not tag more than that', function () {
|
||||
const err = new Error('test error')
|
||||
OError.tag(err, 'test message 1')
|
||||
OError.tag(err, 'test message 2')
|
||||
OError.tag(err, 'test message 3')
|
||||
OError.tag(err, 'test message 4')
|
||||
OError.tag(err, 'test message 5')
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
'Error: test error',
|
||||
'TaggedError: test message 1',
|
||||
'TaggedError: ... dropped tags',
|
||||
'TaggedError: test message 4',
|
||||
'TaggedError: test message 5',
|
||||
])
|
||||
})
|
||||
describe('without Error.captureStackTrace', function () {
|
||||
/* eslint-disable mocha/no-hooks-for-single-case */
|
||||
before(function () {
|
||||
this.originalCaptureStackTrace = Error.captureStackTrace
|
||||
Error.captureStackTrace = null
|
||||
})
|
||||
after(function () {
|
||||
Error.captureStackTrace = this.originalCaptureStackTrace
|
||||
})
|
||||
|
||||
it('should handle deep recursion', async function () {
|
||||
async function recursiveAdd(n) {
|
||||
try {
|
||||
if (n === 0) throw new Error('deep error')
|
||||
const result = await recursiveAdd(n - 1)
|
||||
return result + 1
|
||||
} catch (err) {
|
||||
throw OError.tag(err, `at level ${n}`)
|
||||
}
|
||||
}
|
||||
try {
|
||||
await recursiveAdd(10)
|
||||
} catch (err) {
|
||||
it('still captures a stack trace, albeit including itself', function () {
|
||||
const err = new Error('test error')
|
||||
OError.tag(err, 'test message')
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
'Error: deep error',
|
||||
'TaggedError: at level 0',
|
||||
'TaggedError: ... dropped tags',
|
||||
'TaggedError: at level 9',
|
||||
'TaggedError: at level 10',
|
||||
'Error: test error',
|
||||
'TaggedError: test message',
|
||||
])
|
||||
}
|
||||
const stack = OError.getFullStack(err)
|
||||
expect(stack).to.match(/TaggedError: test message\n\s+at [\w.]*tag/)
|
||||
})
|
||||
})
|
||||
|
||||
it('should handle a singleton error', function (done) {
|
||||
const err = new Error('singleton error')
|
||||
function endpoint(callback) {
|
||||
helper((err) => callback(err && OError.tag(err, 'in endpoint')))
|
||||
}
|
||||
function helper(callback) {
|
||||
libraryFunction((err) => callback(err && OError.tag(err, 'in helper')))
|
||||
}
|
||||
function libraryFunction(callback) {
|
||||
callback(err)
|
||||
}
|
||||
describe('with limit on the number of tags', function () {
|
||||
before(function () {
|
||||
this.originalMaxTags = OError.maxTags
|
||||
OError.maxTags = 3
|
||||
})
|
||||
after(function () {
|
||||
OError.maxTags = this.originalMaxTags
|
||||
})
|
||||
|
||||
endpoint(() => {
|
||||
endpoint((err) => {
|
||||
expect(err).to.exist
|
||||
it('should not tag more than that', function () {
|
||||
const err = new Error('test error')
|
||||
OError.tag(err, 'test message 1')
|
||||
OError.tag(err, 'test message 2')
|
||||
OError.tag(err, 'test message 3')
|
||||
OError.tag(err, 'test message 4')
|
||||
OError.tag(err, 'test message 5')
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
'Error: test error',
|
||||
'TaggedError: test message 1',
|
||||
'TaggedError: ... dropped tags',
|
||||
'TaggedError: test message 4',
|
||||
'TaggedError: test message 5',
|
||||
])
|
||||
})
|
||||
|
||||
it('should handle deep recursion', async function () {
|
||||
async function recursiveAdd(n) {
|
||||
try {
|
||||
if (n === 0) throw new Error('deep error')
|
||||
const result = await recursiveAdd(n - 1)
|
||||
return result + 1
|
||||
} catch (err) {
|
||||
throw OError.tag(err, `at level ${n}`)
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await recursiveAdd(10)
|
||||
} catch (err) {
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
'Error: singleton error',
|
||||
'TaggedError: in helper',
|
||||
'Error: deep error',
|
||||
'TaggedError: at level 0',
|
||||
'TaggedError: ... dropped tags',
|
||||
'TaggedError: in helper',
|
||||
'TaggedError: in endpoint',
|
||||
'TaggedError: at level 9',
|
||||
'TaggedError: at level 10',
|
||||
])
|
||||
done()
|
||||
}
|
||||
})
|
||||
|
||||
it('should handle a singleton error', function (done) {
|
||||
const err = new Error('singleton error')
|
||||
|
||||
function endpoint(callback) {
|
||||
helper(err => callback(err && OError.tag(err, 'in endpoint')))
|
||||
}
|
||||
|
||||
function helper(callback) {
|
||||
libraryFunction(err => callback(err && OError.tag(err, 'in helper')))
|
||||
}
|
||||
|
||||
function libraryFunction(callback) {
|
||||
callback(err)
|
||||
}
|
||||
|
||||
endpoint(() => {
|
||||
endpoint(err => {
|
||||
expect(err).to.exist
|
||||
expectFullStackWithoutStackFramesToEqual(err, [
|
||||
'Error: singleton error',
|
||||
'TaggedError: in helper',
|
||||
'TaggedError: ... dropped tags',
|
||||
'TaggedError: in helper',
|
||||
'TaggedError: in endpoint',
|
||||
])
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('OError.getFullInfo', function () {
|
||||
it('works when given null', function () {
|
||||
expect(OError.getFullInfo(null)).to.deep.equal({})
|
||||
})
|
||||
|
||||
it('works on a normal error', function () {
|
||||
const err = new Error('foo')
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({})
|
||||
})
|
||||
|
||||
it('works on an error with tags', function () {
|
||||
const err = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({ userId: 123 })
|
||||
})
|
||||
|
||||
it('merges info from an error and its tags', function () {
|
||||
const err = new OError('foo').withInfo({ projectId: 456 })
|
||||
OError.tag(err, 'failed to foo', { userId: 123 })
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({
|
||||
projectId: 456,
|
||||
userId: 123,
|
||||
describe('OError.getFullInfo', function () {
|
||||
it('works when given null', function () {
|
||||
expect(OError.getFullInfo(null)).to.deep.equal({})
|
||||
})
|
||||
})
|
||||
|
||||
it('merges info from a cause', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
err1.cause = err2
|
||||
err2.info = { userId: 123 }
|
||||
expect(OError.getFullInfo(err1)).to.deep.equal({ userId: 123 })
|
||||
})
|
||||
|
||||
it('merges info from a nested cause', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
const err3 = new Error('baz')
|
||||
err1.cause = err2
|
||||
err2.info = { userId: 123 }
|
||||
err2.cause = err3
|
||||
err3.info = { foo: 42 }
|
||||
expect(OError.getFullInfo(err1)).to.deep.equal({
|
||||
userId: 123,
|
||||
foo: 42,
|
||||
it('works on a normal error', function () {
|
||||
const err = new Error('foo')
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({})
|
||||
})
|
||||
})
|
||||
|
||||
it('merges info from cause with duplicate keys', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
err1.info = { userId: 42, foo: 1337 }
|
||||
err1.cause = err2
|
||||
err2.info = { userId: 1 }
|
||||
expect(OError.getFullInfo(err1)).to.deep.equal({
|
||||
userId: 42,
|
||||
foo: 1337,
|
||||
it('works on an error with tags', function () {
|
||||
const err = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({ userId: 123 })
|
||||
})
|
||||
})
|
||||
|
||||
it('merges info from tags with duplicate keys', function () {
|
||||
const err1 = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
||||
const err2 = OError.tag(err1, 'bat', { userId: 456 })
|
||||
expect(OError.getFullInfo(err2)).to.deep.equal({ userId: 456 })
|
||||
})
|
||||
|
||||
it('works on an error with .info set to a string', function () {
|
||||
const err = new Error('foo')
|
||||
err.info = 'test'
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({})
|
||||
})
|
||||
})
|
||||
|
||||
describe('OError.getFullStack', function () {
|
||||
it('works when given null', function () {
|
||||
expect(OError.getFullStack(null)).to.equal('')
|
||||
})
|
||||
|
||||
it('works on a normal error', function () {
|
||||
const err = new Error('foo')
|
||||
const fullStack = OError.getFullStack(err)
|
||||
expect(fullStack).to.match(/^Error: foo$/m)
|
||||
expect(fullStack).to.match(/^\s+at /m)
|
||||
})
|
||||
|
||||
it('works on an error with a cause', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
err1.cause = err2
|
||||
|
||||
const fullStack = OError.getFullStack(err1)
|
||||
expect(fullStack).to.match(/^Error: foo$/m)
|
||||
expect(fullStack).to.match(/^\s+at /m)
|
||||
expect(fullStack).to.match(/^caused by:\n\s+Error: bar$/m)
|
||||
})
|
||||
|
||||
it('works on both tags and causes', async function () {
|
||||
// Here's the actual error.
|
||||
function tryToFoo() {
|
||||
try {
|
||||
throw Error('foo')
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to foo', { foo: 1 })
|
||||
}
|
||||
}
|
||||
|
||||
// Inside another function that wraps it.
|
||||
function tryToBar() {
|
||||
try {
|
||||
tryToFoo()
|
||||
} catch (error) {
|
||||
throw new OError('failed to bar').withCause(error)
|
||||
}
|
||||
}
|
||||
|
||||
// And it is in another try.
|
||||
try {
|
||||
try {
|
||||
tryToBar()
|
||||
expect.fail('should have thrown')
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to bat', { bat: 1 })
|
||||
}
|
||||
} catch (error) {
|
||||
// We catch the wrapping error.
|
||||
expectError(error, {
|
||||
name: 'OError',
|
||||
klass: OError,
|
||||
message: 'OError: failed to bar',
|
||||
firstFrameRx: /tryToBar/,
|
||||
it('merges info from an error and its tags', function () {
|
||||
const err = new OError('foo').withInfo({ projectId: 456 })
|
||||
OError.tag(err, 'failed to foo', { userId: 123 })
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({
|
||||
projectId: 456,
|
||||
userId: 123,
|
||||
})
|
||||
})
|
||||
|
||||
// But the stack contains all of the errors and tags.
|
||||
expectFullStackWithoutStackFramesToEqual(error, [
|
||||
'OError: failed to bar',
|
||||
'TaggedError: failed to bat',
|
||||
'caused by:',
|
||||
' Error: foo',
|
||||
' TaggedError: failed to foo',
|
||||
])
|
||||
it('merges info from a cause', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
err1.cause = err2
|
||||
err2.info = { userId: 123 }
|
||||
expect(OError.getFullInfo(err1)).to.deep.equal({ userId: 123 })
|
||||
})
|
||||
|
||||
// The info from the wrapped cause should be picked up for logging.
|
||||
expect(OError.getFullInfo(error)).to.eql({ bat: 1, foo: 1 })
|
||||
it('merges info from a nested cause', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
const err3 = new Error('baz')
|
||||
err1.cause = err2
|
||||
err2.info = { userId: 123 }
|
||||
err2.cause = err3
|
||||
err3.info = { foo: 42 }
|
||||
expect(OError.getFullInfo(err1)).to.deep.equal({
|
||||
userId: 123,
|
||||
foo: 42,
|
||||
})
|
||||
})
|
||||
|
||||
// But it should still be recorded.
|
||||
expect(OError.getFullInfo(error.cause)).to.eql({ foo: 1 })
|
||||
}
|
||||
it('merges info from cause with duplicate keys', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
err1.info = { userId: 42, foo: 1337 }
|
||||
err1.cause = err2
|
||||
err2.info = { userId: 1 }
|
||||
expect(OError.getFullInfo(err1)).to.deep.equal({
|
||||
userId: 42,
|
||||
foo: 1337,
|
||||
})
|
||||
})
|
||||
|
||||
it('merges info from tags with duplicate keys', function () {
|
||||
const err1 = OError.tag(new Error('foo'), 'bar', { userId: 123 })
|
||||
const err2 = OError.tag(err1, 'bat', { userId: 456 })
|
||||
expect(OError.getFullInfo(err2)).to.deep.equal({ userId: 456 })
|
||||
})
|
||||
|
||||
it('works on an error with .info set to a string', function () {
|
||||
const err = new Error('foo')
|
||||
err.info = 'test'
|
||||
expect(OError.getFullInfo(err)).to.deep.equal({})
|
||||
})
|
||||
})
|
||||
|
||||
describe('OError.getFullStack', function () {
|
||||
it('works when given null', function () {
|
||||
expect(OError.getFullStack(null)).to.equal('')
|
||||
})
|
||||
|
||||
it('works on a normal error', function () {
|
||||
const err = new Error('foo')
|
||||
const fullStack = OError.getFullStack(err)
|
||||
expect(fullStack).to.match(/^Error: foo$/m)
|
||||
expect(fullStack).to.match(/^\s+at /m)
|
||||
})
|
||||
|
||||
it('works on an error with a cause', function () {
|
||||
const err1 = new Error('foo')
|
||||
const err2 = new Error('bar')
|
||||
err1.cause = err2
|
||||
|
||||
const fullStack = OError.getFullStack(err1)
|
||||
expect(fullStack).to.match(/^Error: foo$/m)
|
||||
expect(fullStack).to.match(/^\s+at /m)
|
||||
expect(fullStack).to.match(/^caused by:\n\s+Error: bar$/m)
|
||||
})
|
||||
|
||||
it('works on both tags and causes', async function () {
|
||||
// Here's the actual error.
|
||||
function tryToFoo() {
|
||||
try {
|
||||
throw Error('foo')
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to foo', { foo: 1 })
|
||||
}
|
||||
}
|
||||
|
||||
// Inside another function that wraps it.
|
||||
function tryToBar() {
|
||||
try {
|
||||
tryToFoo()
|
||||
} catch (error) {
|
||||
throw new OError('failed to bar').withCause(error)
|
||||
}
|
||||
}
|
||||
|
||||
// And it is in another try.
|
||||
try {
|
||||
try {
|
||||
tryToBar()
|
||||
expect.fail('should have thrown')
|
||||
} catch (error) {
|
||||
throw OError.tag(error, 'failed to bat', { bat: 1 })
|
||||
}
|
||||
} catch (error) {
|
||||
// We catch the wrapping error.
|
||||
expectError(error, {
|
||||
name: 'OError',
|
||||
klass: OError,
|
||||
message: 'OError: failed to bar',
|
||||
firstFrameRx: /tryToBar/,
|
||||
})
|
||||
|
||||
// But the stack contains all of the errors and tags.
|
||||
expectFullStackWithoutStackFramesToEqual(error, [
|
||||
'OError: failed to bar',
|
||||
'TaggedError: failed to bat',
|
||||
'caused by:',
|
||||
' Error: foo',
|
||||
' TaggedError: failed to foo',
|
||||
])
|
||||
|
||||
// The info from the wrapped cause should be picked up for logging.
|
||||
expect(OError.getFullInfo(error)).to.eql({ bat: 1, foo: 1 })
|
||||
|
||||
// But it should still be recorded.
|
||||
expect(OError.getFullInfo(error.cause)).to.eql({ foo: 1 })
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -53,7 +53,7 @@ exports.expectFullStackWithoutStackFramesToEqual = function (error, expected) {
|
|||
const fullStack = OError.getFullStack(error)
|
||||
const fullStackWithoutFrames = fullStack
|
||||
.split('\n')
|
||||
.filter((line) => !/^\s+at\s/.test(line))
|
||||
.filter(line => !/^\s+at\s/.test(line))
|
||||
expect(
|
||||
fullStackWithoutFrames,
|
||||
'full stack without frames should equal'
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"standard",
|
||||
"prettier",
|
||||
"prettier/standard"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"plugins": [
|
||||
"mocha",
|
||||
"chai-expect",
|
||||
"chai-friendly"
|
||||
],
|
||||
"env": {
|
||||
"node": true,
|
||||
"mocha": true
|
||||
},
|
||||
"rules": {
|
||||
"no-unused-expressions": 0,
|
||||
"chai-friendly/no-unused-expressions": "error",
|
||||
"no-console": "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"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
2797
libraries/object-persistor/package-lock.json
generated
2797
libraries/object-persistor/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -6,10 +6,10 @@
|
|||
"scripts": {
|
||||
"test": "npm run lint && npm run format && npm run test:unit",
|
||||
"test:unit": "mocha",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"format": "prettier-eslint $PWD'/**/*.js' --list-different",
|
||||
"format:fix": "prettier-eslint $PWD'/**/*.js' --write",
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"test:ci": "npm run test:unit"
|
||||
},
|
||||
"repository": {
|
||||
|
@ -32,20 +32,8 @@
|
|||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-chai-expect": "^2.2.0",
|
||||
"eslint-plugin-chai-friendly": "^0.6.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-mocha": "^7.0.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"eslint-plugin-promise": "^4.2.1",
|
||||
"eslint-plugin-standard": "^4.0.1",
|
||||
"mocha": "^8.0.1",
|
||||
"mongodb": "^3.5.9",
|
||||
"prettier-eslint": "^11.0.0",
|
||||
"prettier-eslint-cli": "^5.0.0",
|
||||
"sandboxed-module": "^2.0.4",
|
||||
"sinon": "^9.0.2",
|
||||
"sinon-chai": "^3.5.0"
|
||||
|
|
|
@ -6,7 +6,7 @@ module.exports = class AbstractPersistor {
|
|||
method: 'sendFile',
|
||||
location,
|
||||
target,
|
||||
source
|
||||
source,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ module.exports = class AbstractPersistor {
|
|||
method: 'sendStream',
|
||||
location,
|
||||
target,
|
||||
opts
|
||||
opts,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ module.exports = class AbstractPersistor {
|
|||
method: 'getObjectStream',
|
||||
location,
|
||||
name,
|
||||
opts
|
||||
opts,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -33,7 +33,7 @@ module.exports = class AbstractPersistor {
|
|||
throw new NotImplementedError('method not implemented in persistor', {
|
||||
method: 'getRedirectUrl',
|
||||
location,
|
||||
name
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ module.exports = class AbstractPersistor {
|
|||
throw new NotImplementedError('method not implemented in persistor', {
|
||||
method: 'getObjectSize',
|
||||
location,
|
||||
name
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ module.exports = class AbstractPersistor {
|
|||
throw new NotImplementedError('method not implemented in persistor', {
|
||||
method: 'getObjectMd5Hash',
|
||||
location,
|
||||
name
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ module.exports = class AbstractPersistor {
|
|||
method: 'copyObject',
|
||||
location,
|
||||
fromName,
|
||||
toName
|
||||
toName,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -66,7 +66,7 @@ module.exports = class AbstractPersistor {
|
|||
throw new NotImplementedError('method not implemented in persistor', {
|
||||
method: 'deleteObject',
|
||||
location,
|
||||
name
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ module.exports = class AbstractPersistor {
|
|||
throw new NotImplementedError('method not implemented in persistor', {
|
||||
method: 'deleteDirectory',
|
||||
location,
|
||||
name
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ module.exports = class AbstractPersistor {
|
|||
throw new NotImplementedError('method not implemented in persistor', {
|
||||
method: 'checkIfObjectExists',
|
||||
location,
|
||||
name
|
||||
name,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ module.exports = class AbstractPersistor {
|
|||
throw new NotImplementedError('method not implemented in persistor', {
|
||||
method: 'directorySize',
|
||||
location,
|
||||
name
|
||||
name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,5 +11,5 @@ module.exports = {
|
|||
WriteError,
|
||||
ReadError,
|
||||
SettingsError,
|
||||
NotImplementedError
|
||||
NotImplementedError,
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ const fsOpen = promisify(fs.open)
|
|||
const fsStat = promisify(fs.stat)
|
||||
const fsGlob = promisify(glob)
|
||||
|
||||
const filterName = (key) => key.replace(/\//g, '_')
|
||||
const filterName = key => key.replace(/\//g, '_')
|
||||
|
||||
module.exports = class FSPersistor extends AbstractPersistor {
|
||||
constructor(settings) {
|
||||
|
@ -59,7 +59,7 @@ module.exports = class FSPersistor extends AbstractPersistor {
|
|||
sourceMd5,
|
||||
destMd5,
|
||||
location,
|
||||
target
|
||||
target,
|
||||
})
|
||||
}
|
||||
} finally {
|
||||
|
@ -165,7 +165,7 @@ module.exports = class FSPersistor extends AbstractPersistor {
|
|||
await Promise.all(
|
||||
(
|
||||
await fsGlob(`${location}/${filteredName}_*`)
|
||||
).map((file) => fsUnlink(file))
|
||||
).map(file => fsUnlink(file))
|
||||
)
|
||||
} catch (err) {
|
||||
throw PersistorHelper.wrapError(
|
||||
|
|
|
@ -22,7 +22,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
|
|||
// https://github.com/googleapis/nodejs-storage/issues/898
|
||||
if (this.settings.endpoint && this.settings.endpoint.apiEndpoint) {
|
||||
this.storage.interceptors.push({
|
||||
request: (reqOpts) => {
|
||||
request: reqOpts => {
|
||||
const url = new URL(reqOpts.uri)
|
||||
url.host = this.settings.endpoint.apiEndpoint
|
||||
if (this.settings.endpoint.apiScheme) {
|
||||
|
@ -30,7 +30,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
|
|||
}
|
||||
reqOpts.uri = url.toString()
|
||||
return reqOpts
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
|
|||
// egress from us to gcs
|
||||
const observeOptions = {
|
||||
metric: 'gcs.egress',
|
||||
Metrics: this.settings.Metrics
|
||||
Metrics: this.settings.Metrics,
|
||||
}
|
||||
|
||||
let sourceMd5 = opts.sourceMd5
|
||||
|
@ -57,7 +57,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
|
|||
|
||||
const writeOptions = {
|
||||
// disabling of resumable uploads is recommended by Google:
|
||||
resumable: false
|
||||
resumable: false,
|
||||
}
|
||||
|
||||
if (sourceMd5) {
|
||||
|
@ -107,7 +107,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
|
|||
// ingress to us from gcs
|
||||
const observer = new PersistorHelper.ObserverStream({
|
||||
metric: 'gcs.ingress',
|
||||
Metrics: this.settings.Metrics
|
||||
Metrics: this.settings.Metrics,
|
||||
})
|
||||
|
||||
try {
|
||||
|
@ -139,7 +139,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
|
|||
.file(key)
|
||||
.getSignedUrl({
|
||||
action: 'read',
|
||||
expires: Date.now() + this.settings.signedUrlExpiryInMs
|
||||
expires: Date.now() + this.settings.signedUrlExpiryInMs,
|
||||
})
|
||||
return url
|
||||
} catch (err) {
|
||||
|
@ -228,7 +228,7 @@ module.exports = class GcsPersistor extends AbstractPersistor {
|
|||
await asyncPool(
|
||||
this.settings.deleteConcurrency,
|
||||
files,
|
||||
async (file) => {
|
||||
async file => {
|
||||
await this.deleteObject(bucketName, file.name)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -81,13 +81,13 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
// start listening on both straight away so that we don't consume bytes
|
||||
// in one place before the other
|
||||
const returnStream = new Stream.PassThrough()
|
||||
pipeline(fallbackStream, returnStream).catch((error) => {
|
||||
pipeline(fallbackStream, returnStream).catch(error => {
|
||||
Logger.warn({ error }, 'failed to copy object from fallback')
|
||||
})
|
||||
|
||||
if (shouldCopy) {
|
||||
const copyStream = new Stream.PassThrough()
|
||||
pipeline(fallbackStream, copyStream).catch((error) => {
|
||||
pipeline(fallbackStream, copyStream).catch(error => {
|
||||
Logger.warn({ error }, 'failed to copy object from fallback')
|
||||
})
|
||||
|
||||
|
@ -97,7 +97,7 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
bucket,
|
||||
key,
|
||||
key
|
||||
).catch((error) => {
|
||||
).catch(error => {
|
||||
Logger.warn({ error }, 'failed to copy file from fallback')
|
||||
})
|
||||
}
|
||||
|
@ -120,13 +120,13 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
)
|
||||
|
||||
const copyStream = new Stream.PassThrough()
|
||||
pipeline(fallbackStream, copyStream).catch((error) => {
|
||||
pipeline(fallbackStream, copyStream).catch(error => {
|
||||
Logger.warn({ error }, 'failed to copy object from fallback')
|
||||
})
|
||||
|
||||
if (this.settings.copyOnMiss) {
|
||||
const missStream = new Stream.PassThrough()
|
||||
pipeline(fallbackStream, missStream).catch((error) => {
|
||||
pipeline(fallbackStream, missStream).catch(error => {
|
||||
Logger.warn({ error }, 'failed to copy object from fallback')
|
||||
})
|
||||
|
||||
|
@ -173,7 +173,7 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
}
|
||||
|
||||
await this.primaryPersistor.sendStream(destBucket, destKey, stream, {
|
||||
sourceMd5
|
||||
sourceMd5,
|
||||
})
|
||||
} catch (err) {
|
||||
const error = new WriteError(
|
||||
|
@ -182,7 +182,7 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
sourceBucket,
|
||||
destBucket,
|
||||
sourceKey,
|
||||
destKey
|
||||
destKey,
|
||||
},
|
||||
err
|
||||
)
|
||||
|
@ -197,7 +197,7 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
'unable to clean up destination copy artifact',
|
||||
{
|
||||
destBucket,
|
||||
destKey
|
||||
destKey,
|
||||
},
|
||||
err
|
||||
)
|
||||
|
@ -215,7 +215,7 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
|
||||
await Promise.all([
|
||||
this.primaryPersistor[methodName](bucket, ...moreArgs),
|
||||
this.fallbackPersistor[methodName](fallbackBucket, ...moreArgs)
|
||||
this.fallbackPersistor[methodName](fallbackBucket, ...moreArgs),
|
||||
])
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ module.exports = class MigrationPersistor extends AbstractPersistor {
|
|||
bucket,
|
||||
key,
|
||||
key
|
||||
).catch((err) => {
|
||||
).catch(err => {
|
||||
Logger.warn({ err }, 'failed to copy file from fallback')
|
||||
})
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ function getPersistor(backend, settings) {
|
|||
case 'fs':
|
||||
return new FSPersistor({
|
||||
paths: settings.paths,
|
||||
Metrics: settings.Metrics
|
||||
Metrics: settings.Metrics,
|
||||
})
|
||||
case 'gcs':
|
||||
return new GcsPersistor(
|
||||
|
@ -30,7 +30,7 @@ module.exports = function create(settings) {
|
|||
Logger.info(
|
||||
{
|
||||
backend: settings.backend,
|
||||
fallback: settings.fallback && settings.fallback.backend
|
||||
fallback: settings.fallback && settings.fallback.backend,
|
||||
},
|
||||
'Loading backend'
|
||||
)
|
||||
|
|
|
@ -52,7 +52,7 @@ module.exports = {
|
|||
getReadyPipeline,
|
||||
wrapError,
|
||||
hexToBase64,
|
||||
base64ToHex
|
||||
base64ToHex,
|
||||
}
|
||||
|
||||
// returns a promise which resolves with the md5 hash of the stream
|
||||
|
@ -84,7 +84,7 @@ async function verifyMd5(persistor, bucket, key, sourceMd5, destMd5 = null) {
|
|||
sourceMd5,
|
||||
destMd5,
|
||||
bucket,
|
||||
key
|
||||
key,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -133,8 +133,8 @@ function getReadyPipeline(...streams) {
|
|||
for (const stream of streams) {
|
||||
// when a stream receives a pipe, set up the drain handler to drain the
|
||||
// connection if an error occurs or the stream is closed
|
||||
stream.on('pipe', (previousStream) => {
|
||||
stream.on('error', (x) => {
|
||||
stream.on('pipe', previousStream => {
|
||||
stream.on('error', x => {
|
||||
drainPreviousStream(previousStream)
|
||||
})
|
||||
stream.on('close', () => {
|
||||
|
|
|
@ -17,7 +17,7 @@ const {
|
|||
WriteError,
|
||||
ReadError,
|
||||
NotFoundError,
|
||||
SettingsError
|
||||
SettingsError,
|
||||
} = require('./Errors')
|
||||
|
||||
module.exports = class S3Persistor extends AbstractPersistor {
|
||||
|
@ -36,7 +36,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
// egress from us to S3
|
||||
const observeOptions = {
|
||||
metric: 's3.egress',
|
||||
Metrics: this.settings.Metrics
|
||||
Metrics: this.settings.Metrics,
|
||||
}
|
||||
|
||||
const observer = new PersistorHelper.ObserverStream(observeOptions)
|
||||
|
@ -47,7 +47,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
const uploadOptions = {
|
||||
Bucket: bucketName,
|
||||
Key: key,
|
||||
Body: observer
|
||||
Body: observer,
|
||||
}
|
||||
|
||||
if (opts.contentType) {
|
||||
|
@ -84,7 +84,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
|
||||
const params = {
|
||||
Bucket: bucketName,
|
||||
Key: key
|
||||
Key: key,
|
||||
}
|
||||
if (opts.start != null && opts.end != null) {
|
||||
params.Range = `bytes=${opts.start}-${opts.end}`
|
||||
|
@ -97,7 +97,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
// ingress from S3 to us
|
||||
const observer = new PersistorHelper.ObserverStream({
|
||||
metric: 's3.ingress',
|
||||
Metrics: this.settings.Metrics
|
||||
Metrics: this.settings.Metrics,
|
||||
})
|
||||
|
||||
try {
|
||||
|
@ -122,7 +122,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
).getSignedUrlPromise('getObject', {
|
||||
Bucket: bucketName,
|
||||
Key: key,
|
||||
Expires: expiresSeconds
|
||||
Expires: expiresSeconds,
|
||||
})
|
||||
return url
|
||||
} catch (err) {
|
||||
|
@ -155,7 +155,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
)
|
||||
}
|
||||
|
||||
const objects = response.Contents.map((item) => ({ Key: item.Key }))
|
||||
const objects = response.Contents.map(item => ({ Key: item.Key }))
|
||||
if (objects.length) {
|
||||
try {
|
||||
await this._getClientForBucket(bucketName)
|
||||
|
@ -163,8 +163,8 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
Bucket: bucketName,
|
||||
Delete: {
|
||||
Objects: objects,
|
||||
Quiet: true
|
||||
}
|
||||
Quiet: true,
|
||||
},
|
||||
})
|
||||
.promise()
|
||||
} catch (err) {
|
||||
|
@ -248,7 +248,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
const params = {
|
||||
Bucket: bucketName,
|
||||
Key: destKey,
|
||||
CopySource: `${bucketName}/${sourceKey}`
|
||||
CopySource: `${bucketName}/${sourceKey}`,
|
||||
}
|
||||
try {
|
||||
await this._getClientForBucket(bucketName).copyObject(params).promise()
|
||||
|
@ -283,7 +283,7 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
try {
|
||||
const options = {
|
||||
Bucket: bucketName,
|
||||
Prefix: key
|
||||
Prefix: key,
|
||||
}
|
||||
if (continuationToken) {
|
||||
options.ContinuationToken = continuationToken
|
||||
|
@ -341,12 +341,12 @@ module.exports = class S3Persistor extends AbstractPersistor {
|
|||
if (bucketCredentials) {
|
||||
options.credentials = {
|
||||
accessKeyId: bucketCredentials.auth_key,
|
||||
secretAccessKey: bucketCredentials.auth_secret
|
||||
secretAccessKey: bucketCredentials.auth_secret,
|
||||
}
|
||||
} else {
|
||||
options.credentials = {
|
||||
accessKeyId: this.settings.key,
|
||||
secretAccessKey: this.settings.secret
|
||||
secretAccessKey: this.settings.secret,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,10 @@ describe('FSPersistorTests', function () {
|
|||
readStream = {
|
||||
name: 'readStream',
|
||||
on: sinon.stub().yields(),
|
||||
pipe: sinon.stub()
|
||||
pipe: sinon.stub(),
|
||||
}
|
||||
uuid = {
|
||||
v1: () => randomNumber
|
||||
v1: () => randomNumber,
|
||||
}
|
||||
tempFile = `/tmp/${randomNumber}`
|
||||
fs = {
|
||||
|
@ -37,21 +37,21 @@ describe('FSPersistorTests', function () {
|
|||
createWriteStream: sinon.stub().returns(writeStream),
|
||||
unlink: sinon.stub().yields(),
|
||||
open: sinon.stub().yields(null, fd),
|
||||
stat: sinon.stub().yields(null, stat)
|
||||
stat: sinon.stub().yields(null, stat),
|
||||
}
|
||||
glob = sinon.stub().yields(null, globs)
|
||||
stream = {
|
||||
pipeline: sinon.stub().yields(),
|
||||
Transform: StreamModule.Transform
|
||||
Transform: StreamModule.Transform,
|
||||
}
|
||||
Hash = {
|
||||
end: sinon.stub(),
|
||||
read: sinon.stub().returns(md5),
|
||||
digest: sinon.stub().returns(md5),
|
||||
setEncoding: sinon.stub()
|
||||
setEncoding: sinon.stub(),
|
||||
}
|
||||
crypto = {
|
||||
createHash: sinon.stub().returns(Hash)
|
||||
createHash: sinon.stub().returns(Hash),
|
||||
}
|
||||
FSPersistor = new (SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
|
@ -62,9 +62,9 @@ describe('FSPersistorTests', function () {
|
|||
crypto,
|
||||
'node-uuid': uuid,
|
||||
// imported by PersistorHelper but otherwise unused here
|
||||
'logger-sharelatex': {}
|
||||
'logger-sharelatex': {},
|
||||
},
|
||||
globals: { console }
|
||||
globals: { console },
|
||||
}))({ paths: { uploadFolder: '/tmp' } })
|
||||
})
|
||||
|
||||
|
@ -114,7 +114,7 @@ describe('FSPersistorTests', function () {
|
|||
it('should return a write error', async function () {
|
||||
await expect(
|
||||
FSPersistor.sendStream(location, files[0], remoteStream, {
|
||||
sourceMd5: '00000000'
|
||||
sourceMd5: '00000000',
|
||||
})
|
||||
)
|
||||
.to.eventually.be.rejected.and.be.an.instanceOf(Errors.WriteError)
|
||||
|
@ -124,7 +124,7 @@ describe('FSPersistorTests', function () {
|
|||
it('deletes the copied file', async function () {
|
||||
try {
|
||||
await FSPersistor.sendStream(location, files[0], remoteStream, {
|
||||
sourceMd5: '00000000'
|
||||
sourceMd5: '00000000',
|
||||
})
|
||||
} catch (_) {}
|
||||
expect(fs.unlink).to.have.been.calledWith(
|
||||
|
@ -145,12 +145,12 @@ describe('FSPersistorTests', function () {
|
|||
it('should pass the options to createReadStream', async function () {
|
||||
await FSPersistor.getObjectStream(location, files[0], {
|
||||
start: 0,
|
||||
end: 8
|
||||
end: 8,
|
||||
})
|
||||
expect(fs.createReadStream).to.have.been.calledWith(null, {
|
||||
start: 0,
|
||||
end: 8,
|
||||
fd
|
||||
fd,
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -39,31 +39,31 @@ describe('GcsPersistorTests', function () {
|
|||
Settings = {
|
||||
directoryKeyRegex: /^[0-9a-fA-F]{24}\/[0-9a-fA-F]{24}/,
|
||||
Metrics: {
|
||||
count: sinon.stub()
|
||||
}
|
||||
count: sinon.stub(),
|
||||
},
|
||||
}
|
||||
|
||||
files = [
|
||||
{
|
||||
metadata: { size: 11, md5Hash: '/////wAAAAD/////AAAAAA==' },
|
||||
delete: sinon.stub()
|
||||
delete: sinon.stub(),
|
||||
},
|
||||
{
|
||||
metadata: { size: 22, md5Hash: '/////wAAAAD/////AAAAAA==' },
|
||||
delete: sinon.stub()
|
||||
}
|
||||
delete: sinon.stub(),
|
||||
},
|
||||
]
|
||||
|
||||
ReadStream = {
|
||||
pipe: sinon.stub().returns('readStream'),
|
||||
on: sinon.stub(),
|
||||
removeListener: sinon.stub()
|
||||
removeListener: sinon.stub(),
|
||||
}
|
||||
ReadStream.on.withArgs('end').yields()
|
||||
ReadStream.on.withArgs('pipe').yields({
|
||||
unpipe: sinon.stub(),
|
||||
resume: sinon.stub(),
|
||||
on: sinon.stub()
|
||||
on: sinon.stub(),
|
||||
})
|
||||
|
||||
Transform = class {
|
||||
|
@ -79,7 +79,7 @@ describe('GcsPersistorTests', function () {
|
|||
|
||||
Stream = {
|
||||
pipeline: sinon.stub().yields(),
|
||||
Transform: Transform
|
||||
Transform: Transform,
|
||||
}
|
||||
|
||||
GcsFile = {
|
||||
|
@ -89,12 +89,12 @@ describe('GcsPersistorTests', function () {
|
|||
createWriteStream: sinon.stub().returns(WriteStream),
|
||||
copy: sinon.stub().resolves(),
|
||||
exists: sinon.stub().resolves([true]),
|
||||
getSignedUrl: sinon.stub().resolves([redirectUrl])
|
||||
getSignedUrl: sinon.stub().resolves([redirectUrl]),
|
||||
}
|
||||
|
||||
GcsBucket = {
|
||||
file: sinon.stub().returns(GcsFile),
|
||||
getFiles: sinon.stub().resolves([files])
|
||||
getFiles: sinon.stub().resolves([files]),
|
||||
}
|
||||
|
||||
Storage = class {
|
||||
|
@ -108,7 +108,7 @@ describe('GcsPersistorTests', function () {
|
|||
GcsNotFoundError.code = 404
|
||||
|
||||
Fs = {
|
||||
createReadStream: sinon.stub().returns(ReadStream)
|
||||
createReadStream: sinon.stub().returns(ReadStream),
|
||||
}
|
||||
|
||||
FileNotFoundError = new Error('File not found')
|
||||
|
@ -118,14 +118,14 @@ describe('GcsPersistorTests', function () {
|
|||
end: sinon.stub(),
|
||||
read: sinon.stub().returns(md5),
|
||||
digest: sinon.stub().returns(md5),
|
||||
setEncoding: sinon.stub()
|
||||
setEncoding: sinon.stub(),
|
||||
}
|
||||
crypto = {
|
||||
createHash: sinon.stub().returns(Hash)
|
||||
createHash: sinon.stub().returns(Hash),
|
||||
}
|
||||
|
||||
Logger = {
|
||||
warn: sinon.stub()
|
||||
warn: sinon.stub(),
|
||||
}
|
||||
|
||||
GcsPersistor = new (SandboxedModule.require(modulePath, {
|
||||
|
@ -136,9 +136,9 @@ describe('GcsPersistorTests', function () {
|
|||
'./Errors': Errors,
|
||||
fs: Fs,
|
||||
stream: Stream,
|
||||
crypto
|
||||
crypto,
|
||||
},
|
||||
globals: { console, Buffer }
|
||||
globals: { console, Buffer },
|
||||
}))(Settings)
|
||||
})
|
||||
|
||||
|
@ -162,7 +162,7 @@ describe('GcsPersistorTests', function () {
|
|||
|
||||
it('disables automatic decompression', function () {
|
||||
expect(GcsFile.createReadStream).to.have.been.calledWith({
|
||||
decompress: false
|
||||
decompress: false,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -179,7 +179,7 @@ describe('GcsPersistorTests', function () {
|
|||
beforeEach(async function () {
|
||||
stream = await GcsPersistor.getObjectStream(bucket, key, {
|
||||
start: 5,
|
||||
end: 10
|
||||
end: 10,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -191,7 +191,7 @@ describe('GcsPersistorTests', function () {
|
|||
expect(GcsFile.createReadStream).to.have.been.calledWith({
|
||||
decompress: false,
|
||||
start: 5,
|
||||
end: 10
|
||||
end: 10,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -279,7 +279,7 @@ describe('GcsPersistorTests', function () {
|
|||
GcsPersistor.settings.unsignedUrls = true
|
||||
GcsPersistor.settings.endpoint = {
|
||||
apiScheme: 'http',
|
||||
apiEndpoint: 'custom.endpoint'
|
||||
apiEndpoint: 'custom.endpoint',
|
||||
}
|
||||
signedUrl = await GcsPersistor.getRedirectUrl(bucket, key)
|
||||
})
|
||||
|
@ -368,7 +368,7 @@ describe('GcsPersistorTests', function () {
|
|||
|
||||
it('should not try to create a resumable upload', function () {
|
||||
expect(GcsFile.createWriteStream).to.have.been.calledWith({
|
||||
resumable: false
|
||||
resumable: false,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -388,7 +388,7 @@ describe('GcsPersistorTests', function () {
|
|||
describe('when a hash is supplied', function () {
|
||||
beforeEach(async function () {
|
||||
return GcsPersistor.sendStream(bucket, key, ReadStream, {
|
||||
sourceMd5: 'aaaaaaaabbbbbbbbaaaaaaaabbbbbbbb'
|
||||
sourceMd5: 'aaaaaaaabbbbbbbbaaaaaaaabbbbbbbb',
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -400,9 +400,9 @@ describe('GcsPersistorTests', function () {
|
|||
expect(GcsFile.createWriteStream).to.have.been.calledWith({
|
||||
validation: 'md5',
|
||||
metadata: {
|
||||
md5Hash: 'qqqqqru7u7uqqqqqu7u7uw=='
|
||||
md5Hash: 'qqqqqru7u7uqqqqqu7u7uw==',
|
||||
},
|
||||
resumable: false
|
||||
resumable: false,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -418,14 +418,14 @@ describe('GcsPersistorTests', function () {
|
|||
beforeEach(async function () {
|
||||
return GcsPersistor.sendStream(bucket, key, ReadStream, {
|
||||
contentType,
|
||||
contentEncoding
|
||||
contentEncoding,
|
||||
})
|
||||
})
|
||||
|
||||
it('should send the metadata to GCS', function () {
|
||||
expect(GcsFile.createWriteStream).to.have.been.calledWith({
|
||||
metadata: { contentType, contentEncoding },
|
||||
resumable: false
|
||||
resumable: false,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -572,7 +572,7 @@ describe('GcsPersistorTests', function () {
|
|||
expect(Storage.prototype.bucket).to.have.been.calledWith(bucket)
|
||||
expect(GcsBucket.getFiles).to.have.been.calledWith({
|
||||
directory: directoryName,
|
||||
autoPaginate: false
|
||||
autoPaginate: false,
|
||||
})
|
||||
expect(GcsBucket.getFiles).to.have.been.calledWith('call-1')
|
||||
expect(GcsBucket.getFiles).to.have.been.calledWith('call-2')
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('MigrationPersistorTests', function () {
|
|||
fileStream = {
|
||||
name: 'fileStream',
|
||||
on: sinon.stub().withArgs('end').yields(),
|
||||
pipe: sinon.stub()
|
||||
pipe: sinon.stub(),
|
||||
}
|
||||
|
||||
newPersistor = function (hasFile) {
|
||||
|
@ -53,32 +53,32 @@ describe('MigrationPersistorTests', function () {
|
|||
: sinon.stub().rejects(notFoundError),
|
||||
getObjectMd5Hash: hasFile
|
||||
? sinon.stub().resolves(md5)
|
||||
: sinon.stub().rejects(notFoundError)
|
||||
: sinon.stub().rejects(notFoundError),
|
||||
}
|
||||
}
|
||||
|
||||
Settings = {
|
||||
buckets: {
|
||||
[bucket]: fallbackBucket
|
||||
}
|
||||
[bucket]: fallbackBucket,
|
||||
},
|
||||
}
|
||||
|
||||
Stream = {
|
||||
pipeline: sinon.stub().yields(),
|
||||
PassThrough: sinon.stub()
|
||||
PassThrough: sinon.stub(),
|
||||
}
|
||||
|
||||
Logger = {
|
||||
warn: sinon.stub()
|
||||
warn: sinon.stub(),
|
||||
}
|
||||
|
||||
MigrationPersistor = SandboxedModule.require(modulePath, {
|
||||
requires: {
|
||||
stream: Stream,
|
||||
'./Errors': Errors,
|
||||
'logger-sharelatex': Logger
|
||||
'logger-sharelatex': Logger,
|
||||
},
|
||||
globals: { console }
|
||||
globals: { console },
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ describe('PersistorManager', function () {
|
|||
'./FSPersistor': FSPersistor,
|
||||
'logger-sharelatex': {
|
||||
info() {},
|
||||
err() {}
|
||||
}
|
||||
err() {},
|
||||
},
|
||||
}
|
||||
PersistorFactory = SandboxedModule.require(modulePath, { requires })
|
||||
})
|
||||
|
|
|
@ -12,8 +12,8 @@ describe('S3PersistorTests', function () {
|
|||
const defaultS3Credentials = {
|
||||
credentials: {
|
||||
accessKeyId: defaultS3Key,
|
||||
secretAccessKey: defaultS3Secret
|
||||
}
|
||||
secretAccessKey: defaultS3Secret,
|
||||
},
|
||||
}
|
||||
const filename = '/wombat/potato.tex'
|
||||
const bucket = 'womBucket'
|
||||
|
@ -23,7 +23,7 @@ describe('S3PersistorTests', function () {
|
|||
const genericError = new Error('guru meditation error')
|
||||
const files = [
|
||||
{ Key: 'llama', Size: 11 },
|
||||
{ Key: 'hippo', Size: 22 }
|
||||
{ Key: 'hippo', Size: 22 },
|
||||
]
|
||||
const filesSize = 33
|
||||
const md5 = 'ffffffff00000000ffffffff00000000'
|
||||
|
@ -50,7 +50,7 @@ describe('S3PersistorTests', function () {
|
|||
settings = {
|
||||
secret: defaultS3Secret,
|
||||
key: defaultS3Key,
|
||||
partSize: 100 * 1024 * 1024
|
||||
partSize: 100 * 1024 * 1024,
|
||||
}
|
||||
|
||||
Transform = class {
|
||||
|
@ -66,29 +66,29 @@ describe('S3PersistorTests', function () {
|
|||
|
||||
Stream = {
|
||||
pipeline: sinon.stub().yields(),
|
||||
Transform: Transform
|
||||
Transform: Transform,
|
||||
}
|
||||
|
||||
EmptyPromise = {
|
||||
promise: sinon.stub().resolves()
|
||||
promise: sinon.stub().resolves(),
|
||||
}
|
||||
|
||||
ReadStream = {
|
||||
pipe: sinon.stub().returns('readStream'),
|
||||
on: sinon.stub(),
|
||||
removeListener: sinon.stub()
|
||||
removeListener: sinon.stub(),
|
||||
}
|
||||
ReadStream.on.withArgs('end').yields()
|
||||
ReadStream.on.withArgs('pipe').yields({
|
||||
unpipe: sinon.stub(),
|
||||
resume: sinon.stub()
|
||||
resume: sinon.stub(),
|
||||
})
|
||||
|
||||
FileNotFoundError = new Error('File not found')
|
||||
FileNotFoundError.code = 'ENOENT'
|
||||
|
||||
Fs = {
|
||||
createReadStream: sinon.stub().returns(ReadStream)
|
||||
createReadStream: sinon.stub().returns(ReadStream),
|
||||
}
|
||||
|
||||
S3NotFoundError = new Error('not found')
|
||||
|
@ -100,27 +100,27 @@ describe('S3PersistorTests', function () {
|
|||
S3ReadStream = {
|
||||
on: sinon.stub(),
|
||||
pipe: sinon.stub(),
|
||||
removeListener: sinon.stub()
|
||||
removeListener: sinon.stub(),
|
||||
}
|
||||
S3ReadStream.on.withArgs('end').yields()
|
||||
S3ReadStream.on.withArgs('pipe').yields({
|
||||
unpipe: sinon.stub(),
|
||||
resume: sinon.stub()
|
||||
resume: sinon.stub(),
|
||||
})
|
||||
S3Client = {
|
||||
getObject: sinon.stub().returns({
|
||||
createReadStream: sinon.stub().returns(S3ReadStream)
|
||||
createReadStream: sinon.stub().returns(S3ReadStream),
|
||||
}),
|
||||
headObject: sinon.stub().returns({
|
||||
promise: sinon.stub().resolves({
|
||||
ContentLength: objectSize,
|
||||
ETag: md5
|
||||
})
|
||||
ETag: md5,
|
||||
}),
|
||||
}),
|
||||
listObjectsV2: sinon.stub().returns({
|
||||
promise: sinon.stub().resolves({
|
||||
Contents: files
|
||||
})
|
||||
Contents: files,
|
||||
}),
|
||||
}),
|
||||
upload: sinon
|
||||
.stub()
|
||||
|
@ -128,21 +128,21 @@ describe('S3PersistorTests', function () {
|
|||
copyObject: sinon.stub().returns(EmptyPromise),
|
||||
deleteObject: sinon.stub().returns(EmptyPromise),
|
||||
deleteObjects: sinon.stub().returns(EmptyPromise),
|
||||
getSignedUrlPromise: sinon.stub().resolves(redirectUrl)
|
||||
getSignedUrlPromise: sinon.stub().resolves(redirectUrl),
|
||||
}
|
||||
S3 = sinon.stub().returns(S3Client)
|
||||
|
||||
Hash = {
|
||||
end: sinon.stub(),
|
||||
read: sinon.stub().returns(md5),
|
||||
setEncoding: sinon.stub()
|
||||
setEncoding: sinon.stub(),
|
||||
}
|
||||
crypto = {
|
||||
createHash: sinon.stub().returns(Hash)
|
||||
createHash: sinon.stub().returns(Hash),
|
||||
}
|
||||
|
||||
Logger = {
|
||||
warn: sinon.stub()
|
||||
warn: sinon.stub(),
|
||||
}
|
||||
|
||||
S3Persistor = new (SandboxedModule.require(modulePath, {
|
||||
|
@ -152,9 +152,9 @@ describe('S3PersistorTests', function () {
|
|||
'./Errors': Errors,
|
||||
fs: Fs,
|
||||
stream: Stream,
|
||||
crypto
|
||||
crypto,
|
||||
},
|
||||
globals: { console, Buffer }
|
||||
globals: { console, Buffer },
|
||||
}))(settings)
|
||||
})
|
||||
|
||||
|
@ -177,7 +177,7 @@ describe('S3PersistorTests', function () {
|
|||
it('fetches the right key from the right bucket', function () {
|
||||
expect(S3Client.getObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -194,7 +194,7 @@ describe('S3PersistorTests', function () {
|
|||
beforeEach(async function () {
|
||||
stream = await S3Persistor.getObjectStream(bucket, key, {
|
||||
start: 5,
|
||||
end: 10
|
||||
end: 10,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -206,7 +206,7 @@ describe('S3PersistorTests', function () {
|
|||
expect(S3Client.getObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key,
|
||||
Range: 'bytes=5-10'
|
||||
Range: 'bytes=5-10',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -218,15 +218,15 @@ describe('S3PersistorTests', function () {
|
|||
const alternativeS3Credentials = {
|
||||
credentials: {
|
||||
accessKeyId: alternativeKey,
|
||||
secretAccessKey: alternativeSecret
|
||||
}
|
||||
secretAccessKey: alternativeSecret,
|
||||
},
|
||||
}
|
||||
|
||||
beforeEach(async function () {
|
||||
settings.bucketCreds = {}
|
||||
settings.bucketCreds[bucket] = {
|
||||
auth_key: alternativeKey,
|
||||
auth_secret: alternativeSecret
|
||||
auth_secret: alternativeSecret,
|
||||
}
|
||||
|
||||
stream = await S3Persistor.getObjectStream(bucket, key)
|
||||
|
@ -243,7 +243,7 @@ describe('S3PersistorTests', function () {
|
|||
it('fetches the right key from the right bucket', function () {
|
||||
expect(S3Client.getObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -402,7 +402,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should pass the bucket and key to S3', function () {
|
||||
expect(S3Client.headObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -412,7 +412,7 @@ describe('S3PersistorTests', function () {
|
|||
|
||||
beforeEach(async function () {
|
||||
S3Client.headObject = sinon.stub().returns({
|
||||
promise: sinon.stub().rejects(S3NotFoundError)
|
||||
promise: sinon.stub().rejects(S3NotFoundError),
|
||||
})
|
||||
try {
|
||||
await S3Persistor.getObjectSize(bucket, key)
|
||||
|
@ -435,7 +435,7 @@ describe('S3PersistorTests', function () {
|
|||
|
||||
beforeEach(async function () {
|
||||
S3Client.headObject = sinon.stub().returns({
|
||||
promise: sinon.stub().rejects(genericError)
|
||||
promise: sinon.stub().rejects(genericError),
|
||||
})
|
||||
try {
|
||||
await S3Persistor.getObjectSize(bucket, key)
|
||||
|
@ -464,13 +464,13 @@ describe('S3PersistorTests', function () {
|
|||
expect(S3Client.upload).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key,
|
||||
Body: sinon.match.instanceOf(Stream.Transform)
|
||||
Body: sinon.match.instanceOf(Stream.Transform),
|
||||
})
|
||||
})
|
||||
|
||||
it('should upload files in a single part', function () {
|
||||
expect(S3Client.upload).to.have.been.calledWith(sinon.match.any, {
|
||||
partSize: 100 * 1024 * 1024
|
||||
partSize: 100 * 1024 * 1024,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -484,7 +484,7 @@ describe('S3PersistorTests', function () {
|
|||
describe('when a hash is supplied', function () {
|
||||
beforeEach(async function () {
|
||||
return S3Persistor.sendStream(bucket, key, ReadStream, {
|
||||
sourceMd5: 'aaaaaaaabbbbbbbbaaaaaaaabbbbbbbb'
|
||||
sourceMd5: 'aaaaaaaabbbbbbbbaaaaaaaabbbbbbbb',
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -493,7 +493,7 @@ describe('S3PersistorTests', function () {
|
|||
Bucket: bucket,
|
||||
Key: key,
|
||||
Body: sinon.match.instanceOf(Transform),
|
||||
ContentMD5: 'qqqqqru7u7uqqqqqu7u7uw=='
|
||||
ContentMD5: 'qqqqqru7u7uqqqqqu7u7uw==',
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -505,7 +505,7 @@ describe('S3PersistorTests', function () {
|
|||
beforeEach(async function () {
|
||||
return S3Persistor.sendStream(bucket, key, ReadStream, {
|
||||
contentType,
|
||||
contentEncoding
|
||||
contentEncoding,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -515,7 +515,7 @@ describe('S3PersistorTests', function () {
|
|||
Key: key,
|
||||
Body: sinon.match.instanceOf(Transform),
|
||||
ContentType: contentType,
|
||||
ContentEncoding: contentEncoding
|
||||
ContentEncoding: contentEncoding,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -524,7 +524,7 @@ describe('S3PersistorTests', function () {
|
|||
let error
|
||||
beforeEach(async function () {
|
||||
S3Client.upload = sinon.stub().returns({
|
||||
promise: sinon.stub().rejects(genericError)
|
||||
promise: sinon.stub().rejects(genericError),
|
||||
})
|
||||
try {
|
||||
await S3Persistor.sendStream(bucket, key, ReadStream)
|
||||
|
@ -553,7 +553,7 @@ describe('S3PersistorTests', function () {
|
|||
expect(S3Client.upload).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key,
|
||||
Body: sinon.match.instanceOf(Transform)
|
||||
Body: sinon.match.instanceOf(Transform),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -573,7 +573,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should get the hash from the object metadata', function () {
|
||||
expect(S3Client.headObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -589,8 +589,8 @@ describe('S3PersistorTests', function () {
|
|||
promise: sinon.stub().resolves({
|
||||
ETag: 'somethingthatisntanmd5',
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
})
|
||||
Key: key,
|
||||
}),
|
||||
})
|
||||
|
||||
hash = await S3Persistor.getObjectMd5Hash(bucket, key)
|
||||
|
@ -599,7 +599,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should re-fetch the file to verify it', function () {
|
||||
expect(S3Client.getObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -629,7 +629,7 @@ describe('S3PersistorTests', function () {
|
|||
expect(S3Client.copyObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: destKey,
|
||||
CopySource: `${bucket}/${key}`
|
||||
CopySource: `${bucket}/${key}`,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -639,7 +639,7 @@ describe('S3PersistorTests', function () {
|
|||
|
||||
beforeEach(async function () {
|
||||
S3Client.copyObject = sinon.stub().returns({
|
||||
promise: sinon.stub().rejects(S3NotFoundError)
|
||||
promise: sinon.stub().rejects(S3NotFoundError),
|
||||
})
|
||||
try {
|
||||
await S3Persistor.copyObject(bucket, key, destKey)
|
||||
|
@ -663,7 +663,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should delete the object', function () {
|
||||
expect(S3Client.deleteObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -678,7 +678,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should list the objects in the directory', function () {
|
||||
expect(S3Client.listObjectsV2).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key
|
||||
Prefix: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -687,8 +687,8 @@ describe('S3PersistorTests', function () {
|
|||
Bucket: bucket,
|
||||
Delete: {
|
||||
Objects: [{ Key: 'llama' }, { Key: 'hippo' }],
|
||||
Quiet: true
|
||||
}
|
||||
Quiet: true,
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -704,7 +704,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should list the objects in the directory', function () {
|
||||
expect(S3Client.listObjectsV2).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key
|
||||
Prefix: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -720,8 +720,8 @@ describe('S3PersistorTests', function () {
|
|||
promise: sinon.stub().resolves({
|
||||
Contents: files,
|
||||
IsTruncated: true,
|
||||
NextContinuationToken: continuationToken
|
||||
})
|
||||
NextContinuationToken: continuationToken,
|
||||
}),
|
||||
})
|
||||
|
||||
return S3Persistor.deleteDirectory(bucket, key)
|
||||
|
@ -731,12 +731,12 @@ describe('S3PersistorTests', function () {
|
|||
expect(S3Client.listObjectsV2).to.be.calledTwice
|
||||
expect(S3Client.listObjectsV2).to.be.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key
|
||||
Prefix: key,
|
||||
})
|
||||
expect(S3Client.listObjectsV2).to.be.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key,
|
||||
ContinuationToken: continuationToken
|
||||
ContinuationToken: continuationToken,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -807,7 +807,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should list the objects in the directory', function () {
|
||||
expect(S3Client.listObjectsV2).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key
|
||||
Prefix: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -829,7 +829,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should list the objects in the directory', function () {
|
||||
expect(S3Client.listObjectsV2).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key
|
||||
Prefix: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -846,8 +846,8 @@ describe('S3PersistorTests', function () {
|
|||
promise: sinon.stub().resolves({
|
||||
Contents: files,
|
||||
IsTruncated: true,
|
||||
NextContinuationToken: continuationToken
|
||||
})
|
||||
NextContinuationToken: continuationToken,
|
||||
}),
|
||||
})
|
||||
|
||||
size = await S3Persistor.directorySize(bucket, key)
|
||||
|
@ -857,12 +857,12 @@ describe('S3PersistorTests', function () {
|
|||
expect(S3Client.listObjectsV2).to.be.calledTwice
|
||||
expect(S3Client.listObjectsV2).to.be.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key
|
||||
Prefix: key,
|
||||
})
|
||||
expect(S3Client.listObjectsV2).to.be.calledWith({
|
||||
Bucket: bucket,
|
||||
Prefix: key,
|
||||
ContinuationToken: continuationToken
|
||||
ContinuationToken: continuationToken,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -906,7 +906,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should get the object header', function () {
|
||||
expect(S3Client.headObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -928,7 +928,7 @@ describe('S3PersistorTests', function () {
|
|||
it('should get the object header', function () {
|
||||
expect(S3Client.headObject).to.have.been.calledWith({
|
||||
Bucket: bucket,
|
||||
Key: key
|
||||
Key: key,
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"extends": [
|
||||
"standard",
|
||||
"plugin:prettier/recommended",
|
||||
"plugin:mocha/recommended",
|
||||
"plugin:chai-expect/recommended",
|
||||
"plugin:chai-friendly/recommended"
|
||||
],
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["test/**/*.js"],
|
||||
"env": {
|
||||
"mocha": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
|
@ -40,7 +40,7 @@ function createClient(opts) {
|
|||
client = new Redis(standardOpts)
|
||||
}
|
||||
monkeyPatchIoRedisExec(client)
|
||||
client.healthCheck = (callback) => {
|
||||
client.healthCheck = callback => {
|
||||
if (callback) {
|
||||
// callback based invocation
|
||||
healthCheck(client).then(callback).catch(callback)
|
||||
|
@ -77,7 +77,7 @@ async function runCheck(client, uniqueToken, context) {
|
|||
context.stage = 'write'
|
||||
const writeAck = await client
|
||||
.set(healthCheckKey, healthCheckValue, 'EX', 60)
|
||||
.catch((err) => {
|
||||
.catch(err => {
|
||||
throw new RedisHealthCheckWriteError('write errored', context, err)
|
||||
})
|
||||
if (writeAck !== 'OK') {
|
||||
|
@ -92,7 +92,7 @@ async function runCheck(client, uniqueToken, context) {
|
|||
.get(healthCheckKey)
|
||||
.del(healthCheckKey)
|
||||
.exec()
|
||||
.catch((err) => {
|
||||
.catch(err => {
|
||||
throw new RedisHealthCheckVerifyError(
|
||||
'read/delete errored',
|
||||
context,
|
||||
|
@ -137,7 +137,7 @@ function monkeyPatchIoRedisExec(client) {
|
|||
client.multi = function () {
|
||||
const multi = _multi.apply(client, arguments)
|
||||
const _exec = multi.exec
|
||||
multi.exec = (callback) => {
|
||||
multi.exec = callback => {
|
||||
if (callback) {
|
||||
// callback based invocation
|
||||
_exec.call(multi, (error, result) => {
|
||||
|
|
2959
libraries/redis-wrapper/package-lock.json
generated
2959
libraries/redis-wrapper/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -11,10 +11,10 @@
|
|||
"repository": "github:overleaf/redis-wrapper",
|
||||
"license": "ISC",
|
||||
"scripts": {
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "eslint --fix .",
|
||||
"format": "prettier-eslint $PWD'/**/*.js' --list-different",
|
||||
"format:fix": "prettier-eslint $PWD'/**/*.js' --write",
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"test": "mocha --recursive test/unit/src/",
|
||||
"test:ci": "npm run test"
|
||||
},
|
||||
|
@ -27,21 +27,8 @@
|
|||
"devDependencies": {
|
||||
"@overleaf/o-error": "^3.3.1",
|
||||
"chai": "^4.3.4",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.1",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-chai-expect": "^2.1.0",
|
||||
"eslint-plugin-chai-friendly": "^0.5.0",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-mocha": "^6.3.0",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-promise": "^4.3.1",
|
||||
"eslint-plugin-standard": "^4.1.0",
|
||||
"@overleaf/logger": "^2.3.0",
|
||||
"mocha": "^8.3.2",
|
||||
"prettier": "^2.2.1",
|
||||
"prettier-eslint-cli": "^5.0.1",
|
||||
"sandboxed-module": "^2.0.4",
|
||||
"sinon": "^9.2.4"
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ const rclient = redis.createClient({
|
|||
})
|
||||
|
||||
setInterval(() => {
|
||||
rclient.healthCheck((err) => {
|
||||
rclient.healthCheck(err => {
|
||||
if (err) {
|
||||
logger.error({ err }, 'HEALTH CHECK FAILED')
|
||||
} else {
|
||||
|
|
|
@ -7,7 +7,7 @@ const logger = require('@overleaf/logger')
|
|||
const rclient = redis.createClient({ host: 'localhost', port: '6379' })
|
||||
|
||||
setInterval(() => {
|
||||
rclient.healthCheck((err) => {
|
||||
rclient.healthCheck(err => {
|
||||
if (err) {
|
||||
logger.error({ err }, 'HEALTH CHECK FAILED')
|
||||
} else {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"env": {
|
||||
"node": true
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -26,14 +26,23 @@ clean:
|
|||
-$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local
|
||||
-$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local
|
||||
|
||||
HERE=$(shell pwd)
|
||||
MONOREPO=$(shell cd ../../ && pwd)
|
||||
# Run the linting commands in the scope of the monorepo.
|
||||
# Eslint and prettier (plus some configs) are on the root.
|
||||
RUN_LINTING = docker run --rm -v $(MONOREPO):$(MONOREPO) -w $(HERE) node:14.18.1 npm run --silent
|
||||
|
||||
format:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format
|
||||
$(RUN_LINTING) format
|
||||
|
||||
format_fix:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix
|
||||
$(RUN_LINTING) format:fix
|
||||
|
||||
lint:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint
|
||||
$(RUN_LINTING) lint
|
||||
|
||||
lint_fix:
|
||||
$(RUN_LINTING) lint:fix
|
||||
|
||||
test: format lint test_unit test_acceptance
|
||||
|
||||
|
|
1404
services/chat/package-lock.json
generated
1404
services/chat/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,10 +13,10 @@
|
|||
"nodemon": "nodemon --config nodemon.json",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "eslint --fix ."
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "^3.1.0",
|
||||
|
@ -32,19 +32,8 @@
|
|||
"ajv": "^6.12.0",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"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",
|
||||
"mocha": "^8.3.2",
|
||||
"nodemon": "^2.0.2",
|
||||
"prettier": "^2.2.1",
|
||||
"request": "^2.88.2",
|
||||
"sandboxed-module": "^2.0.3",
|
||||
"sinon": "^9.0.0",
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -26,14 +26,23 @@ clean:
|
|||
-$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local
|
||||
-$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local
|
||||
|
||||
HERE=$(shell pwd)
|
||||
MONOREPO=$(shell cd ../../ && pwd)
|
||||
# Run the linting commands in the scope of the monorepo.
|
||||
# Eslint and prettier (plus some configs) are on the root.
|
||||
RUN_LINTING = docker run --rm -v $(MONOREPO):$(MONOREPO) -w $(HERE) node:14.18.1 npm run --silent
|
||||
|
||||
format:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format
|
||||
$(RUN_LINTING) format
|
||||
|
||||
format_fix:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix
|
||||
$(RUN_LINTING) format:fix
|
||||
|
||||
lint:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint
|
||||
$(RUN_LINTING) lint
|
||||
|
||||
lint_fix:
|
||||
$(RUN_LINTING) lint:fix
|
||||
|
||||
test: format lint test_unit test_acceptance
|
||||
|
||||
|
|
1711
services/clsi/package-lock.json
generated
1711
services/clsi/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,10 +13,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": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "eslint --fix ."
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix ."
|
||||
},
|
||||
"author": "James Allen <james@sharelatex.com>",
|
||||
"dependencies": {
|
||||
|
@ -42,19 +42,8 @@
|
|||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"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",
|
||||
"mocha": "^8.3.2",
|
||||
"nodemon": "^2.0.7",
|
||||
"prettier": "^2.2.1",
|
||||
"sandboxed-module": "^2.0.3",
|
||||
"sinon": "~9.0.1",
|
||||
"sinon-chai": "^3.7.0",
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -26,14 +26,23 @@ clean:
|
|||
-$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local
|
||||
-$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local
|
||||
|
||||
HERE=$(shell pwd)
|
||||
MONOREPO=$(shell cd ../../ && pwd)
|
||||
# Run the linting commands in the scope of the monorepo.
|
||||
# Eslint and prettier (plus some configs) are on the root.
|
||||
RUN_LINTING = docker run --rm -v $(MONOREPO):$(MONOREPO) -w $(HERE) node:14.18.1 npm run --silent
|
||||
|
||||
format:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format
|
||||
$(RUN_LINTING) format
|
||||
|
||||
format_fix:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix
|
||||
$(RUN_LINTING) format:fix
|
||||
|
||||
lint:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint
|
||||
$(RUN_LINTING) lint
|
||||
|
||||
lint_fix:
|
||||
$(RUN_LINTING) lint:fix
|
||||
|
||||
test: format lint test_unit test_acceptance
|
||||
|
||||
|
|
1639
services/contacts/package-lock.json
generated
1639
services/contacts/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -14,10 +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": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "eslint --fix ."
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "^3.1.0",
|
||||
|
@ -34,18 +34,7 @@
|
|||
"devDependencies": {
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"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",
|
||||
"mocha": "^8.3.2",
|
||||
"prettier": "^2.2.1",
|
||||
"sandboxed-module": "~2.0.3",
|
||||
"sinon": "~9.0.1",
|
||||
"timekeeper": "2.2.0"
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -26,14 +26,23 @@ clean:
|
|||
-$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local
|
||||
-$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local
|
||||
|
||||
HERE=$(shell pwd)
|
||||
MONOREPO=$(shell cd ../../ && pwd)
|
||||
# Run the linting commands in the scope of the monorepo.
|
||||
# Eslint and prettier (plus some configs) are on the root.
|
||||
RUN_LINTING = docker run --rm -v $(MONOREPO):$(MONOREPO) -w $(HERE) node:14.18.1 npm run --silent
|
||||
|
||||
format:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format
|
||||
$(RUN_LINTING) format
|
||||
|
||||
format_fix:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix
|
||||
$(RUN_LINTING) format:fix
|
||||
|
||||
lint:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint
|
||||
$(RUN_LINTING) lint
|
||||
|
||||
lint_fix:
|
||||
$(RUN_LINTING) lint:fix
|
||||
|
||||
test: format lint test_unit test_acceptance
|
||||
|
||||
|
|
1660
services/docstore/package-lock.json
generated
1660
services/docstore/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -14,10 +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": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "eslint --fix ."
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "^3.1.0",
|
||||
|
@ -40,18 +40,7 @@
|
|||
"@google-cloud/storage": "^5.1.2",
|
||||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"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",
|
||||
"mocha": "^8.3.2",
|
||||
"prettier": "^2.2.1",
|
||||
"sandboxed-module": "~2.0.4",
|
||||
"sinon": "~9.0.2",
|
||||
"sinon-chai": "^3.5.0"
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -26,14 +26,23 @@ clean:
|
|||
-$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local
|
||||
-$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local
|
||||
|
||||
HERE=$(shell pwd)
|
||||
MONOREPO=$(shell cd ../../ && pwd)
|
||||
# Run the linting commands in the scope of the monorepo.
|
||||
# Eslint and prettier (plus some configs) are on the root.
|
||||
RUN_LINTING = docker run --rm -v $(MONOREPO):$(MONOREPO) -w $(HERE) node:14.18.1 npm run --silent
|
||||
|
||||
format:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format
|
||||
$(RUN_LINTING) format
|
||||
|
||||
format_fix:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix
|
||||
$(RUN_LINTING) format:fix
|
||||
|
||||
lint:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint
|
||||
$(RUN_LINTING) lint
|
||||
|
||||
lint_fix:
|
||||
$(RUN_LINTING) lint:fix
|
||||
|
||||
test: format lint test_unit test_acceptance
|
||||
|
||||
|
|
1462
services/document-updater/package-lock.json
generated
1462
services/document-updater/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,10 +13,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": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "eslint --fix ."
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "^3.1.0",
|
||||
|
@ -40,18 +40,7 @@
|
|||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"cluster-key-slot": "^1.0.5",
|
||||
"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",
|
||||
"mocha": "^8.3.2",
|
||||
"prettier": "^2.2.1",
|
||||
"sandboxed-module": "^2.0.4",
|
||||
"sinon": "^9.0.2",
|
||||
"timekeeper": "^2.0.0"
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -26,14 +26,23 @@ clean:
|
|||
-$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local
|
||||
-$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local
|
||||
|
||||
HERE=$(shell pwd)
|
||||
MONOREPO=$(shell cd ../../ && pwd)
|
||||
# Run the linting commands in the scope of the monorepo.
|
||||
# Eslint and prettier (plus some configs) are on the root.
|
||||
RUN_LINTING = docker run --rm -v $(MONOREPO):$(MONOREPO) -w $(HERE) node:14.18.1 npm run --silent
|
||||
|
||||
format:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format
|
||||
$(RUN_LINTING) format
|
||||
|
||||
format_fix:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix
|
||||
$(RUN_LINTING) format:fix
|
||||
|
||||
lint:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint
|
||||
$(RUN_LINTING) lint
|
||||
|
||||
lint_fix:
|
||||
$(RUN_LINTING) lint:fix
|
||||
|
||||
test: format lint test_unit test_acceptance
|
||||
|
||||
|
|
2503
services/filestore/package-lock.json
generated
2503
services/filestore/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -13,12 +13,12 @@
|
|||
"test:unit": "npm run test:unit:_run -- --grep=$MOCHA_GREP",
|
||||
"start": "node $NODE_APP_OPTIONS app.js",
|
||||
"nodemon": "nodemon --config nodemon.json",
|
||||
"lint": "eslint --max-warnings 0 --format unix .",
|
||||
"format": "prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "prettier --write $PWD/'**/*.js'",
|
||||
"lint": "../../node_modules/.bin/eslint --max-warnings 0 --format unix .",
|
||||
"format": "../../node_modules/.bin/prettier --list-different $PWD/'**/*.js'",
|
||||
"format:fix": "../../node_modules/.bin/prettier --write $PWD/'**/*.js'",
|
||||
"test:acceptance:_run": "mocha --recursive --reporter spec --timeout 15000 --exit $@ test/acceptance/js",
|
||||
"test:unit:_run": "mocha --recursive --reporter spec $@ test/unit/js",
|
||||
"lint:fix": "eslint --fix ."
|
||||
"lint:fix": "../../node_modules/.bin/eslint --fix ."
|
||||
},
|
||||
"dependencies": {
|
||||
"@overleaf/logger": "^3.1.0",
|
||||
|
@ -45,20 +45,8 @@
|
|||
"chai": "^4.2.0",
|
||||
"chai-as-promised": "^7.1.1",
|
||||
"disrequire": "^1.1.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",
|
||||
"mocha": "^8.3.2",
|
||||
"mongodb": "^3.5.9",
|
||||
"prettier": "^2.2.1",
|
||||
"prettier-eslint": "^9.0.2",
|
||||
"sandboxed-module": "2.0.4",
|
||||
"sinon": "9.0.2",
|
||||
"sinon-chai": "^3.5.0",
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// this file was auto-generated, do not edit it directly.
|
||||
// instead run bin/update_build_scripts from
|
||||
// https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018
|
||||
},
|
||||
"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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": "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",
|
||||
|
||||
// Do not allow importing of implicit dependencies.
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
// Do not allow importing of devDependencies.
|
||||
"devDependencies": false
|
||||
}]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
# This file was auto-generated, do not edit it directly.
|
||||
# Instead run bin/update_build_scripts from
|
||||
# https://github.com/sharelatex/sharelatex-dev-environment
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 2,
|
||||
"useTabs": false
|
||||
}
|
|
@ -26,14 +26,23 @@ clean:
|
|||
-$(DOCKER_COMPOSE_TEST_UNIT) down --rmi local
|
||||
-$(DOCKER_COMPOSE_TEST_ACCEPTANCE) down --rmi local
|
||||
|
||||
HERE=$(shell pwd)
|
||||
MONOREPO=$(shell cd ../../ && pwd)
|
||||
# Run the linting commands in the scope of the monorepo.
|
||||
# Eslint and prettier (plus some configs) are on the root.
|
||||
RUN_LINTING = docker run --rm -v $(MONOREPO):$(MONOREPO) -w $(HERE) node:14.18.1 npm run --silent
|
||||
|
||||
format:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format
|
||||
$(RUN_LINTING) format
|
||||
|
||||
format_fix:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent format:fix
|
||||
$(RUN_LINTING) format:fix
|
||||
|
||||
lint:
|
||||
$(DOCKER_COMPOSE) run --rm test_unit npm run --silent lint
|
||||
$(RUN_LINTING) lint
|
||||
|
||||
lint_fix:
|
||||
$(RUN_LINTING) lint:fix
|
||||
|
||||
test: format lint test_unit test_acceptance
|
||||
|
||||
|
|
1672
services/notifications/package-lock.json
generated
1672
services/notifications/package-lock.json
generated
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue