From 7b66e181ae7777f265118c3f6decb58becb2ad06 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Thu, 21 Jun 2018 10:35:56 -0700 Subject: [PATCH 001/374] feat(preprocessor): Allow preprocessor to handle binary files (#3054) --- lib/preprocessor.js | 14 +++++++------- test/unit/preprocessor.spec.js | 27 +++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 7d1c8bfb4..db59bd4bf 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -98,12 +98,7 @@ function createPreprocessor (config, basePath, injector) { var preprocessorNames = [] for (var i = 0; i < patterns.length; i++) { if (mm(file.originalPath, patterns[i], {dot: true})) { - if (thisFileIsBinary) { - log.warn('Ignoring preprocessing (%s) %s because it is a binary file.', - config[patterns[i]].join(', '), file.originalPath) - } else { - preprocessorNames = combineLists(preprocessorNames, config[patterns[i]]) - } + preprocessorNames = combineLists(preprocessorNames, config[patterns[i]]) } } @@ -125,7 +120,12 @@ function createPreprocessor (config, basePath, injector) { } instances[name] = p - preprocessors.push(p) + if (!thisFileIsBinary || p.handleBinaryFiles) { + preprocessors.push(p) + } else { + log.warn('Ignored preprocessing %s because %s has handleBinaryFiles=false.', + file.originalPath, name) + } }) nextPreprocessor(null, thisFileIsBinary ? buffer : buffer.toString()) diff --git a/test/unit/preprocessor.spec.js b/test/unit/preprocessor.spec.js index e0f4a48c0..2bf6f9a62 100644 --- a/test/unit/preprocessor.spec.js +++ b/test/unit/preprocessor.spec.js @@ -272,7 +272,7 @@ describe('preprocessor', () => { thirdCallback('error') }) - it('should tbrow after 3 retries', (done) => { + it('should throw after 3 retries', (done) => { var injector = new di.Injector([{}, emitterSetting]) var pp = m.createPreprocessor({'**/*.js': []}, null, injector) @@ -288,7 +288,7 @@ describe('preprocessor', () => { }) }) - it('should not preprocess binary files', (done) => { + it('should not preprocess binary files by default', (done) => { var fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) @@ -310,6 +310,29 @@ describe('preprocessor', () => { }) }) + it('should preprocess binary files if handleBinaryFiles=true', (done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { + done(null, content) + }) + fakePreprocessor.handleBinaryFiles = true + + var injector = new di.Injector([{ + 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] + }, emitterSetting]) + + pp = m.createPreprocessor({'**/*': ['fake']}, null, injector) + + const file = {originalPath: '/some/photo.png', path: 'path'} + + pp(file, (err) => { + if (err) throw err + + expect(fakePreprocessor).to.have.been.calledOnce + expect(file.content).to.be.an.instanceof(Buffer) + done() + }) + }) + it('should not preprocess binary files with capital letters in extension', (done) => { var fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) From ad820a1d0998f0a81eb1d231e3f9b034d8ff21c6 Mon Sep 17 00:00:00 2001 From: lukasz Date: Sat, 16 Jun 2018 10:33:47 +0200 Subject: [PATCH 002/374] refactor(preprocessor): update lib/preprocessor.js to ES6 --- lib/preprocessor.js | 76 ++++++++-------- lib/utils/crypto-utils.js | 14 +++ test/unit/preprocessor.spec.js | 124 ++++++++++++++------------- test/unit/utils/crypto-utils.spec.js | 9 ++ 4 files changed, 120 insertions(+), 103 deletions(-) create mode 100644 lib/utils/crypto-utils.js create mode 100644 test/unit/utils/crypto-utils.spec.js diff --git a/lib/preprocessor.js b/lib/preprocessor.js index db59bd4bf..0728ecac1 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -1,16 +1,12 @@ -var fs = require('graceful-fs') -var crypto = require('crypto') -var mm = require('minimatch') -var isBinaryFile = require('isbinaryfile') -var combineLists = require('combine-lists') - -var log = require('./logger').create('preprocess') - -function sha1 (data) { - var hash = crypto.createHash('sha1') - hash.update(data) - return hash.digest('hex') -} +'use strict' + +const fs = require('graceful-fs') +const mm = require('minimatch') +const isBinaryFile = require('isbinaryfile') +const combineLists = require('combine-lists') +const CryptoUtils = require('./utils/crypto-utils') + +const log = require('./logger').create('preprocess') function createNextProcessor (preprocessors, file, done) { return function nextPreprocessor (error, content) { @@ -29,7 +25,7 @@ function createNextProcessor (preprocessors, file, done) { if (!preprocessors.length) { file.contentPath = null file.content = content - file.sha = sha1(content) + file.sha = CryptoUtils.sha1(content) return done() } @@ -38,27 +34,25 @@ function createNextProcessor (preprocessors, file, done) { } function createPreprocessor (config, basePath, injector) { - var alreadyDisplayedErrors = {} - var instances = {} - var patterns = Object.keys(config) - - var emitter = injector.get('emitter') + const emitter = injector.get('emitter') + const alreadyDisplayedErrors = {} + const instances = {} + let patterns = Object.keys(config) function instantiatePreprocessor (name) { if (alreadyDisplayedErrors[name]) { return } - var p + let p try { p = injector.get('preprocessor:' + name) } catch (e) { - if (e.message.indexOf('No provider for "preprocessor:' + name + '"') !== -1) { - log.error('Can not load "%s", it is not registered!\n ' + - 'Perhaps you are missing some plugin?', name) + if (e.message.indexOf(`No provider for "preprocessor:${name}"`) !== -1) { + log.error(`Can not load "${name}", it is not registered!\n Perhaps you are missing some plugin?`) } else { - log.error('Can not load "%s"!\n ' + e.stack, name) + log.error(`Can not load "${name}"!\n ` + e.stack) } alreadyDisplayedErrors[name] = true emitter.emit('load_error', 'preprocessor', name) @@ -67,16 +61,16 @@ function createPreprocessor (config, basePath, injector) { return p } - var allPreprocessors = [] - patterns.forEach(function (pattern) { + let allPreprocessors = [] + patterns.forEach((pattern) => { allPreprocessors = combineLists(allPreprocessors, config[pattern]) }) allPreprocessors.forEach(instantiatePreprocessor) return function preprocess (file, done) { patterns = Object.keys(config) - var retryCount = 0 - var maxRetries = 3 + let retryCount = 0 + let maxRetries = 3 function readFileCallback (err, buffer) { if (err) { log.warn(err) @@ -90,25 +84,22 @@ function createPreprocessor (config, basePath, injector) { } } - isBinaryFile(buffer, buffer.length, function (err, thisFileIsBinary) { + isBinaryFile(buffer, buffer.length, function (err, isBinary) { if (err) { throw err } var preprocessorNames = [] - for (var i = 0; i < patterns.length; i++) { - if (mm(file.originalPath, patterns[i], {dot: true})) { - preprocessorNames = combineLists(preprocessorNames, config[patterns[i]]) + patterns.forEach((pattern) => { + if (mm(file.originalPath, pattern, {dot: true})) { + preprocessorNames = combineLists(preprocessorNames, config[pattern]) } - } + }) - var preprocessors = [] - var nextPreprocessor = createNextProcessor(preprocessors, file, done) - preprocessorNames.forEach(function (name) { - var p = instances[name] - if (p == null) { - p = instantiatePreprocessor(name) - } + let preprocessors = [] + const nextPreprocessor = createNextProcessor(preprocessors, file, done) + preprocessorNames.forEach((name) => { + const p = instances[name] || instantiatePreprocessor(name) if (p == null) { if (!alreadyDisplayedErrors[name]) { @@ -120,7 +111,7 @@ function createPreprocessor (config, basePath, injector) { } instances[name] = p - if (!thisFileIsBinary || p.handleBinaryFiles) { + if (!isBinary || p.handleBinaryFiles) { preprocessors.push(p) } else { log.warn('Ignored preprocessing %s because %s has handleBinaryFiles=false.', @@ -128,12 +119,13 @@ function createPreprocessor (config, basePath, injector) { } }) - nextPreprocessor(null, thisFileIsBinary ? buffer : buffer.toString()) + nextPreprocessor(null, isBinary ? buffer : buffer.toString()) }) } return fs.readFile(file.originalPath, readFileCallback) } } + createPreprocessor.$inject = ['config.preprocessors', 'config.basePath', 'injector'] exports.createPreprocessor = createPreprocessor diff --git a/lib/utils/crypto-utils.js b/lib/utils/crypto-utils.js new file mode 100644 index 000000000..9dc9a073d --- /dev/null +++ b/lib/utils/crypto-utils.js @@ -0,0 +1,14 @@ +'use strict' + +const crypto = require('crypto') + +const CryptoUtils = { + sha1 (data) { + return crypto + .createHash('sha1') + .update(data) + .digest('hex') + } +} + +module.exports = CryptoUtils diff --git a/test/unit/preprocessor.spec.js b/test/unit/preprocessor.spec.js index 2bf6f9a62..1e4439a6c 100644 --- a/test/unit/preprocessor.spec.js +++ b/test/unit/preprocessor.spec.js @@ -1,16 +1,18 @@ -var mocks = require('mocks') -var di = require('di') -var path = require('path') +'use strict' -var events = require('../../lib/events') +const mocks = require('mocks') +const di = require('di') +const path = require('path') + +const events = require('../../lib/events') describe('preprocessor', () => { - var pp - var m - var mockFs - var emitterSetting + let pp + let m + let mockFs + let emitterSetting // mimic first few bytes of a pdf file - var binarydata = new Buffer([0x25, 0x50, 0x44, 0x66, 0x46, 0x00]) // eslint-disable-line node/no-deprecated-api + const binarydata = new Buffer([0x25, 0x50, 0x44, 0x66, 0x46, 0x00]) // eslint-disable-line node/no-deprecated-api beforeEach(() => { mockFs = mocks.fs.create({ @@ -26,7 +28,7 @@ describe('preprocessor', () => { } }) - var mocks_ = { + const mocks_ = { 'graceful-fs': mockFs, minimatch: require('minimatch') } @@ -35,19 +37,19 @@ describe('preprocessor', () => { }) it('should preprocess matching file', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { file.path = file.path + '-preprocessed' done(null, 'new-content') }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': [ 'factory', function () { return fakePreprocessor } ] }, emitterSetting]) pp = m.createPreprocessor({'**/*.js': ['fake']}, null, injector) - var file = {originalPath: '/some/a.js', path: 'path'} + const file = {originalPath: '/some/a.js', path: 'path'} pp(file, () => { expect(fakePreprocessor).to.have.been.called @@ -58,17 +60,17 @@ describe('preprocessor', () => { }) it('should match directories starting with a dot', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { file.path = file.path + '-preprocessed' done(null, 'new-content') }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) pp = m.createPreprocessor({'**/*.js': ['fake']}, null, injector) - var file = {originalPath: '/some/.dir/a.js', path: 'path'} + const file = {originalPath: '/some/.dir/a.js', path: 'path'} pp(file, () => { expect(fakePreprocessor).to.have.been.called @@ -79,18 +81,18 @@ describe('preprocessor', () => { }) it('should check patterns after creation when invoked', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { file.path = file.path + '-preprocessed' done(null, 'new-content') }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) - var config = {'**/*.txt': ['fake']} + const config = {'**/*.txt': ['fake']} pp = m.createPreprocessor(config, null, injector) - var file = {originalPath: '/some/a.js', path: 'path'} + const file = {originalPath: '/some/a.js', path: 'path'} config['**/*.js'] = ['fake'] @@ -103,16 +105,16 @@ describe('preprocessor', () => { }) it('should ignore not matching file', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { done(null, '') }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) pp = m.createPreprocessor({'**/*.js': ['fake']}, null, injector) - var file = {originalPath: '/some/a.txt', path: 'path'} + const file = {originalPath: '/some/a.txt', path: 'path'} pp(file, () => { expect(fakePreprocessor).to.not.have.been.called @@ -121,24 +123,24 @@ describe('preprocessor', () => { }) it('should apply all preprocessors', (done) => { - var fakePreprocessor1 = sinon.spy((content, file, done) => { + const fakePreprocessor1 = sinon.spy((content, file, done) => { file.path = file.path + '-p1' done(null, content + '-c1') }) - var fakePreprocessor2 = sinon.spy((content, file, done) => { + const fakePreprocessor2 = sinon.spy((content, file, done) => { file.path = file.path + '-p2' done(content + '-c2') }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake1': ['factory', function () { return fakePreprocessor1 }], 'preprocessor:fake2': ['factory', function () { return fakePreprocessor2 }] }, emitterSetting]) pp = m.createPreprocessor({'**/*.js': ['fake1', 'fake2']}, null, injector) - var file = {originalPath: '/some/a.js', path: 'path'} + const file = {originalPath: '/some/a.js', path: 'path'} pp(file, () => { expect(fakePreprocessor1).to.have.been.calledOnce @@ -151,12 +153,12 @@ describe('preprocessor', () => { it('should compute SHA', (done) => { pp = m.createPreprocessor({}, null, new di.Injector([emitterSetting])) - var file = {originalPath: '/some/a.js', path: 'path'} + const file = {originalPath: '/some/a.js', path: 'path'} pp(file, () => { expect(file.sha).to.exist expect(file.sha.length).to.equal(40) - var previousSHA = file.sha + const previousSHA = file.sha pp(file, () => { expect(file.sha).to.equal(previousSHA) @@ -172,18 +174,18 @@ describe('preprocessor', () => { }) it('should compute SHA from content returned by a processor', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { done(null, content + '-processed') }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) pp = m.createPreprocessor({'**/a.js': ['fake']}, null, injector) - var fileProcess = {originalPath: '/some/a.js', path: 'path'} - var fileSkip = {originalPath: '/some/b.js', path: 'path'} + const fileProcess = {originalPath: '/some/a.js', path: 'path'} + const fileSkip = {originalPath: '/some/b.js', path: 'path'} pp(fileProcess, () => { pp(fileSkip, () => { @@ -198,17 +200,17 @@ describe('preprocessor', () => { }) it('should return error if any preprocessor fails', (done) => { - var failingPreprocessor = sinon.spy((content, file, done) => { + const failingPreprocessor = sinon.spy((content, file, done) => { done(new Error('Some error'), null) }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:failing': ['factory', function () { return failingPreprocessor }] }, emitterSetting]) pp = m.createPreprocessor({'**/*.js': ['failing']}, null, injector) - var file = {originalPath: '/some/a.js', path: 'path'} + const file = {originalPath: '/some/a.js', path: 'path'} pp(file, (err) => { expect(err).to.exist @@ -217,22 +219,22 @@ describe('preprocessor', () => { }) it('should stop preprocessing after an error', (done) => { - var failingPreprocessor = sinon.spy((content, file, done) => { + const failingPreprocessor = sinon.spy((content, file, done) => { done(new Error('Some error'), null) }) - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:failing': ['factory', function () { return failingPreprocessor }], 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) pp = m.createPreprocessor({'**/*.js': ['failing', 'fake']}, null, injector) - var file = {originalPath: '/some/a.js', path: 'path'} + const file = {originalPath: '/some/a.js', path: 'path'} pp(file, () => { expect(fakePreprocessor).not.to.have.been.called @@ -241,8 +243,8 @@ describe('preprocessor', () => { }) describe('when fs.readFile fails', () => { - var file = {originalPath: '/some/a.js', path: 'path'} - var getReadFileCallback = (nthCall) => { + const file = {originalPath: '/some/a.js', path: 'path'} + const getReadFileCallback = (nthCall) => { return mockFs.readFile.args[nthCall][1] } @@ -251,15 +253,15 @@ describe('preprocessor', () => { }) it('should retry up to 3 times', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) - var pp = m.createPreprocessor({'**/*.js': ['fake']}, null, injector) + const pp = m.createPreprocessor({'**/*.js': ['fake']}, null, injector) pp(file, () => { expect(fakePreprocessor).to.have.been.called @@ -267,15 +269,15 @@ describe('preprocessor', () => { }) getReadFileCallback(0)('error') getReadFileCallback(1)('error') - var thirdCallback = getReadFileCallback(2) + const thirdCallback = getReadFileCallback(2) mockFs.readFile.restore() thirdCallback('error') }) it('should throw after 3 retries', (done) => { - var injector = new di.Injector([{}, emitterSetting]) + const injector = new di.Injector([{}, emitterSetting]) - var pp = m.createPreprocessor({'**/*.js': []}, null, injector) + const pp = m.createPreprocessor({'**/*.js': []}, null, injector) pp(file, () => { }) @@ -289,17 +291,17 @@ describe('preprocessor', () => { }) it('should not preprocess binary files by default', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) pp = m.createPreprocessor({'**/*': ['fake']}, null, injector) - var file = {originalPath: '/some/photo.png', path: 'path'} + const file = {originalPath: '/some/photo.png', path: 'path'} pp(file, (err) => { if (err) throw err @@ -334,17 +336,17 @@ describe('preprocessor', () => { }) it('should not preprocess binary files with capital letters in extension', (done) => { - var fakePreprocessor = sinon.spy((content, file, done) => { + const fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { fakePreprocessor }] }, emitterSetting]) pp = m.createPreprocessor({'**/*': ['fake']}, null, injector) - var file = {originalPath: '/some/CAM_PHOTO.JPG', path: 'path'} + const file = {originalPath: '/some/CAM_PHOTO.JPG', path: 'path'} pp(file, (err) => { if (err) throw err @@ -356,25 +358,25 @@ describe('preprocessor', () => { }) it('should merge lists of preprocessors', (done) => { - var callOrder = [] - var fakePreprocessorA = sinon.spy((content, file, done) => { + const callOrder = [] + const fakePreprocessorA = sinon.spy((content, file, done) => { callOrder.push('a') done(null, content) }) - var fakePreprocessorB = sinon.spy((content, file, done) => { + const fakePreprocessorB = sinon.spy((content, file, done) => { callOrder.push('b') done(null, content) }) - var fakePreprocessorC = sinon.spy((content, file, done) => { + const fakePreprocessorC = sinon.spy((content, file, done) => { callOrder.push('c') done(null, content) }) - var fakePreprocessorD = sinon.spy((content, file, done) => { + const fakePreprocessorD = sinon.spy((content, file, done) => { callOrder.push('d') done(null, content) }) - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fakeA': ['factory', function () { return fakePreprocessorA }], 'preprocessor:fakeB': ['factory', function () { return fakePreprocessorB }], 'preprocessor:fakeC': ['factory', function () { return fakePreprocessorC }], @@ -387,7 +389,7 @@ describe('preprocessor', () => { '/some/a.js': ['fakeD'] }, null, injector) - var file = {originalPath: '/some/a.js', path: 'path'} + const file = {originalPath: '/some/a.js', path: 'path'} pp(file, (err) => { if (err) throw err diff --git a/test/unit/utils/crypto-utils.spec.js b/test/unit/utils/crypto-utils.spec.js new file mode 100644 index 000000000..671712ecf --- /dev/null +++ b/test/unit/utils/crypto-utils.spec.js @@ -0,0 +1,9 @@ +'use strict' + +const CryptoUtils = require('../../../lib/utils/crypto-utils') + +describe('CryptoUtils.sha1', () => { + it('create sha1 digest from string', () => { + expect(CryptoUtils.sha1('Example text')).to.equal('cf3df620b86f0c9f586359136950217cb3b8c035') + }) +}) From 850a90bc2be8f98de6bfbadbb0476752081563cb Mon Sep 17 00:00:00 2001 From: Sergei Startsev Date: Tue, 3 Jul 2018 23:25:12 +0300 Subject: [PATCH 003/374] fix(server): pass bound port to prevent`EADDRINUSE` issue. (#3065) --- lib/server.js | 9 +++-- lib/utils/net-utils.js | 33 +++++++---------- package.json | 1 + test/unit/server.spec.js | 61 ++++++++++++++++++++----------- test/unit/utils/net-utils.spec.js | 53 ++++++++++----------------- 5 files changed, 79 insertions(+), 78 deletions(-) diff --git a/lib/server.js b/lib/server.js index cbad577ed..1b440231c 100644 --- a/lib/server.js +++ b/lib/server.js @@ -116,9 +116,10 @@ class Server extends KarmaEventEmitter { BundleUtils.bundleResourceIfNotExist('client/main.js', 'static/karma.js'), BundleUtils.bundleResourceIfNotExist('context/main.js', 'static/context.js') ]) - .then(() => NetUtils.getAvailablePort(config.port, config.listenAddress)) - .then((port) => { - config.port = port + .then(() => NetUtils.bindAvailablePort(config.port, config.listenAddress)) + .then((boundServer) => { + config.port = boundServer.address().port + this._boundServer = boundServer this._injector.invoke(this._start, this) }) .catch(this.dieOnError.bind(this)) @@ -156,7 +157,7 @@ class Server extends KarmaEventEmitter { this._injector.invoke(watcher.watch) } - webServer.listen(config.port, config.listenAddress, () => { + webServer.listen(this._boundServer, () => { this.log.info(`Karma v${constant.VERSION} server started at ${config.protocol}//${config.listenAddress}:${config.port}${config.urlRoot}`) this.emit('listening', config.port) diff --git a/lib/utils/net-utils.js b/lib/utils/net-utils.js index 7262ba40b..28531d441 100644 --- a/lib/utils/net-utils.js +++ b/lib/utils/net-utils.js @@ -4,29 +4,24 @@ const Promise = require('bluebird') const net = require('net') const NetUtils = { - isPortAvailable (port, listenAddress) { + bindAvailablePort (port, listenAddress) { return new Promise((resolve, reject) => { const server = net.createServer() - server.unref() - server.on('error', (err) => { - server.close() - if (err.code === 'EADDRINUSE' || err.code === 'EACCES') { - resolve(false) - } else { - reject(err) - } - }) - - server.listen(port, listenAddress, () => { - server.close(() => resolve(true)) - }) + server + .on('error', (err) => { + server.close() + if (err.code === 'EADDRINUSE' || err.code === 'EACCES') { + server.listen(++port, listenAddress) + } else { + reject(err) + } + }) + .on('listening', () => { + resolve(server) + }) + .listen(port, listenAddress) }) - }, - - getAvailablePort (port, listenAddress) { - return NetUtils.isPortAvailable(port, listenAddress) - .then((available) => available ? port : NetUtils.getAvailablePort(port + 1, listenAddress)) } } diff --git a/package.json b/package.json index e111f79b3..6bac5fdf5 100644 --- a/package.json +++ b/package.json @@ -195,6 +195,7 @@ "Samuel Marks ", "Saugat Acharya ", "Schmulik Raskin ", + "Sergei Startsev ", "Sergey Kruk ", "Sergey Simonchik ", "Seth Rhodes ", diff --git a/test/unit/server.spec.js b/test/unit/server.spec.js index a13104739..fcd2f9b61 100644 --- a/test/unit/server.spec.js +++ b/test/unit/server.spec.js @@ -11,6 +11,7 @@ describe('server', () => { var mockLauncher var mockWebServer var mockSocketServer + var mockBoundServer var mockExecutor var doneSpy var server = mockConfig = browserCollection = webServerOnError = null @@ -45,8 +46,7 @@ describe('server', () => { sinon.stub(server._injector, 'invoke').returns([]) - mockExecutor = - {schedule: () => {}} + mockExecutor = { schedule: () => {} } mockFileList = { refresh: sinon.spy(() => { @@ -80,6 +80,13 @@ describe('server', () => { } } + mockBoundServer = { + on: sinon.spy((event, callback) => callback && callback()), + listen: sinon.spy((port, listenAddress, callback) => callback && callback()), + close: sinon.spy((callback) => callback && callback()), + address: () => { return { port: 9876 } } + } + mockWebServer = { on (name, handler) { if (name === 'error') { @@ -99,7 +106,8 @@ describe('server', () => { close: sinon.spy((callback) => callback && callback()) } - sinon.stub(server._injector, 'get') + sinon + .stub(server._injector, 'get') .withArgs('webServer').returns(mockWebServer) .withArgs('socketServer').returns(mockSocketServer) @@ -107,10 +115,15 @@ describe('server', () => { }) describe('start', () => { + var config beforeEach(() => { + config = { port: 9876, listenAddress: '127.0.0.1' } sinon.spy(BundleUtils, 'bundleResourceIfNotExist') - sinon.stub(NetUtils, 'getAvailablePort').resolves(9876) - sinon.stub(server, 'get').withArgs('config').returns({ port: 9876, listenAddress: '127.0.0.1' }) + sinon.stub(NetUtils, 'bindAvailablePort').resolves(mockBoundServer) + sinon.stub(mockBoundServer, 'address').returns({ port: 9877 }) + sinon + .stub(server, 'get') + .withArgs('config').returns(config) }) it('should compile static resources', (done) => { @@ -123,7 +136,17 @@ describe('server', () => { it('should search for available port', (done) => { server.start().then(() => { - expect(NetUtils.getAvailablePort).to.have.been.calledWith(9876, '127.0.0.1') + expect(NetUtils.bindAvailablePort).to.have.been.calledWith(9876, '127.0.0.1') + expect(mockBoundServer.address).to.have.been.called + done() + }) + }) + + it('should change config.port to available', (done) => { + expect(config.port).to.be.equal(9876) + server.start().then(() => { + expect(config.port).to.be.equal(9877) + expect(server._boundServer).to.be.equal(mockBoundServer) done() }) }) @@ -133,6 +156,10 @@ describe('server', () => { // server._start() // ============================================================================ describe('_start', () => { + beforeEach(() => { + server._boundServer = mockBoundServer + }) + it('should start the web server after all files have been preprocessed successfully', () => { server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) @@ -142,7 +169,8 @@ describe('server', () => { expect(server._injector.invoke).not.to.have.been.calledWith(mockLauncher.launch, mockLauncher) fileListOnResolve() - expect(mockWebServer.listen).to.have.been.called + expect(mockWebServer.listen).to.have.been.calledWith(mockBoundServer, sinon.match.func) + expect(webServerOnError).not.to.be.null expect(server._injector.invoke).to.have.been.calledWith(mockLauncher.launch, mockLauncher) }) @@ -155,7 +183,8 @@ describe('server', () => { expect(server._injector.invoke).not.to.have.been.calledWith(mockLauncher.launch, mockLauncher) fileListOnReject() - expect(mockWebServer.listen).to.have.been.called + expect(mockWebServer.listen).to.have.been.calledWith(mockBoundServer, sinon.match.func) + expect(webServerOnError).not.to.be.null expect(server._injector.invoke).to.have.been.calledWith(mockLauncher.launch, mockLauncher) }) @@ -163,26 +192,14 @@ describe('server', () => { server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) expect(mockWebServer.listen).not.to.have.been.called + expect(webServerOnError).not.to.be.null expect(server._injector.invoke).not.to.have.been.calledWith(mockLauncher.launch, mockLauncher) fileListOnResolve() - expect(mockWebServer.listen).to.have.been.called + expect(mockWebServer.listen).to.have.been.calledWith(mockBoundServer, sinon.match.func) expect(server._injector.invoke).to.have.been.calledWith(mockLauncher.launch, mockLauncher) }) - it('should listen on the listenAddress in the config', () => { - server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) - - expect(mockWebServer.listen).not.to.have.been.called - expect(webServerOnError).not.to.be.null - - expect(mockConfig.listenAddress).to.be.equal('127.0.0.1') - - fileListOnResolve() - expect(mockWebServer.listen).to.have.been.calledWith(9876, '127.0.0.1') - expect(mockConfig.listenAddress).to.be.equal('127.0.0.1') - }) - it('should emit a listening event once server begin accepting connections', () => { server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) diff --git a/test/unit/utils/net-utils.spec.js b/test/unit/utils/net-utils.spec.js index 23d32e4cf..e7051b970 100644 --- a/test/unit/utils/net-utils.spec.js +++ b/test/unit/utils/net-utils.spec.js @@ -4,46 +4,33 @@ const NetUtils = require('../../../lib/utils/net-utils') const connect = require('connect') const net = require('net') -describe('NetUtils.isPortAvailable', () => { - it('it is possible to run server on available port', (done) => { - NetUtils.isPortAvailable(9876, '127.0.0.1').then((available) => { - expect(available).to.be.true - const server = net - .createServer(connect()) - .listen(9876, '127.0.0.1', () => { - server.close(done) - }) +describe('NetUtils.bindAvailablePort', () => { + it('resolves server with bound port when it is available', (done) => { + NetUtils.bindAvailablePort(9876, '127.0.0.1').then((boundServer) => { + const port = boundServer.address().port + expect(port).to.be.equal(9876) + expect(boundServer).not.to.be.null + const server = net.createServer(connect()).listen(boundServer, () => { + server.close(done) + }) }) }) - it('resolves with false when port is used', (done) => { - const server = net - .createServer(connect()) - .listen(9876, '127.0.0.1', () => { - NetUtils.isPortAvailable(9876, '127.0.0.1').then((available) => { - expect(available).to.be.false - server.close(done) - }) + it('resolves with next available port', (done) => { + const server = net.createServer(connect()).listen(9876, '127.0.0.1', () => { + NetUtils.bindAvailablePort(9876, '127.0.0.1').then((boundServer) => { + const port = boundServer.address().port + expect(port).to.be.equal(9877) + expect(boundServer).not.to.be.null + server.close(done) }) - }) -}) - -describe('NetUtils.getAvailablePort', () => { - it('resolves with port when is available', (done) => { - NetUtils.getAvailablePort(9876, '127.0.0.1').then((port) => { - expect(port).to.equal(9876) - done() }) }) - it('resolves with next available port', (done) => { - const stub = sinon.stub(NetUtils, 'isPortAvailable') - stub.withArgs(9876).resolves(false) - stub.withArgs(9877).resolves(false) - stub.withArgs(9878).resolves(true) - - NetUtils.getAvailablePort(9876, '127.0.0.1').then((port) => { - expect(port).to.equal(9878) + it('rejects if a critical error occurs', (done) => { + const incorrectAddress = '123.321' + NetUtils.bindAvailablePort(9876, incorrectAddress).catch((err) => { + expect(err).not.to.be.null done() }) }) From 518cb118d8f90b2a64846a109a974b1b5873aabf Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Tue, 10 Jul 2018 11:52:28 +0200 Subject: [PATCH 004/374] fix: remove circular reference in Browser After migrating the the `browser.js` file to ES2015, the `Browser` class has now fields with circular references (like `emitter`), which breaks the Karma JSON reporters available starting with Karma 2.0.1. This commit removes the circular dependencies by adding a `toJSON()` method to the `Browser` class, which produces a similar result to the browser object before the migration. Fixes #3075 --- lib/browser.js | 13 +++++++++++++ test/unit/browser.spec.js | 8 ++++++++ 2 files changed, 21 insertions(+) diff --git a/lib/browser.js b/lib/browser.js index ba870157e..0d764dfec 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -62,6 +62,19 @@ class Browser { return this.name } + toJSON () { + return { + id: this.id, + fullName: this.fullName, + name: this.name, + state: this.state, + lastResult: this.lastResult, + disconnectsCount: this.disconnectsCount, + noActivityTimeout: this.noActivityTimeout, + disconnectDelay: this.disconnectDelay + } + } + onKarmaError (error) { if (this.isReady()) { return diff --git a/test/unit/browser.spec.js b/test/unit/browser.spec.js index 3d857773e..f375f67e0 100644 --- a/test/unit/browser.spec.js +++ b/test/unit/browser.spec.js @@ -32,6 +32,14 @@ describe('Browser', () => { expect(browser.fullName).to.equal(fullName) }) + it('should serialize to JSON', () => { + const fullName = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.7 ' + '(KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7' + browser = new Browser('id', fullName, collection, emitter, socket) + emitter.browser = browser + const json = JSON.stringify(browser) + expect(json).to.contain(fullName) + }) + describe('init', () => { it('should emit "browser_register"', () => { const spyRegister = sinon.spy() From 93ba05ad476ed055e3355f7c4cc03eccd7874e74 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Mon, 25 Jun 2018 13:46:56 -0700 Subject: [PATCH 005/374] fix(middleware): Obey the Promise API. Rather than catching and discarding the error if no error handler is passed, let the promise package chain it. This allows use to have a .catch() follow the then(). --- lib/middleware/common.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/middleware/common.js b/lib/middleware/common.js index d338f2b06..2a001dd35 100644 --- a/lib/middleware/common.js +++ b/lib/middleware/common.js @@ -16,8 +16,7 @@ class PromiseContainer { } then (success, error) { - error = error || _.noop - return this.promise.then(success).catch(error) + return this.promise.then(success, error) } set (newPromise) { From a70173273aed9774f078ce3d2f1071f760dfbbaa Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Mon, 16 Jul 2018 09:06:07 -0700 Subject: [PATCH 006/374] fix(doc): Document release steps for admins (#3063) --- docs/dev/03-maintaining.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/dev/03-maintaining.md b/docs/dev/03-maintaining.md index 9d93f1238..310959446 100644 --- a/docs/dev/03-maintaining.md +++ b/docs/dev/03-maintaining.md @@ -32,6 +32,18 @@ Please, make sure: - e.g. if the first commit is `fix(web-server): serve binary files` and a second commit is “fix unit tests broken in the previous commit”, you should squash them into a single commit. - It’s alright to ask the author of the pull request to fix any of the above. +## Releasing npm +For core collaborators with admin rights. +- Be on a good network that won't go down in the middle. +- Make sure you are sync to upstream master. +- `echo $GH_TOKEN` + - If not set, set GH_TOKEN from https://github.com/settings/tokens/new +- `npm login karmarunnerbot` + - The password is known to authorized releasers. +- `grunt release` +If the release fails, check the state of the git tags pushed to github. You may have to delete one. + + ## Ownership Every project has one or more owners (or “maintainers”), listed in `owners` field of the `package.json`. Typically, owners have push permissions. From 7617279f68507642fdc7eb0083916f3c6c2a28cb Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 17 Jul 2018 16:37:18 -0700 Subject: [PATCH 007/374] refactor(filelist): rename promise -> lastCompletedRefresh and remove unused promise (#3060) --- lib/file-list.js | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/file-list.js b/lib/file-list.js index 887a9d71e..02d0bacdc 100644 --- a/lib/file-list.js +++ b/lib/file-list.js @@ -29,7 +29,8 @@ class FileList { this.buckets = new Map() - this._refreshing = Promise.resolve() + // A promise that is pending if and only if we are active in this.refresh_() + this._refreshing = null const emit = () => { this._emitter.emit('file_list_modified', this.files) @@ -65,8 +66,8 @@ class FileList { _refresh () { const matchedFiles = new Set() - let promise - promise = Promise.map(this._patterns, (patternObject) => { + let lastCompletedRefresh = this._refreshing + lastCompletedRefresh = Promise.map(this._patterns, (patternObject) => { const pattern = patternObject.pattern const type = patternObject.type @@ -113,14 +114,18 @@ class FileList { }) }) .then(() => { - if (this._refreshing !== promise) { + // When we return from this function the file processing chain will be + // complete. In the case of two fast refresh() calls, the second call + // will overwrite this._refreshing, and we want the status to reflect + // the second call and skip the modification event from the first call. + if (this._refreshing !== lastCompletedRefresh) { return this._refreshing } this._emitModified(true) return this.files }) - return promise + return lastCompletedRefresh } get files () { From dc7265bbb5e92b3b9fd48ce85dbdc0d776772cf5 Mon Sep 17 00:00:00 2001 From: Alexei Date: Tue, 24 Jul 2018 01:35:02 +0200 Subject: [PATCH 008/374] fix(browser): ensure browser state is EXECUTING when tests start (#3074) * fix(browser): ensure browser state is EXECUTING when tests start Browser state is EXECUTING when it actually started to execute tests. This state change is triggered by client on actual tests execution start. Introduced an additional browser state CONFIGURING The CONFIGURING state means that the browser is not just CONNECTED for tests, but someone has requested tests execution (and provided a config file). But the provided config file is not yet processed, configuration is not applied or the tests execution is not yet started and we have not received the first event from the remote browser, so the browser object is not yet at EXECUTING state. Refactored browser state names: renamed READY -> CONNECTED Fixes #1640 --- client/updater.js | 2 +- lib/browser.js | 47 +++++++++++----------- lib/browser_collection.js | 11 +----- lib/executor.js | 1 - lib/reporters/base.js | 2 +- test/unit/browser.spec.js | 59 ++++++++++++++++++---------- test/unit/browser_collection.spec.js | 32 ++------------- 7 files changed, 70 insertions(+), 84 deletions(-) diff --git a/client/updater.js b/client/updater.js index b1562e1cf..6c6be933a 100644 --- a/client/updater.js +++ b/client/updater.js @@ -8,7 +8,7 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { var items = [] var status for (var i = 0; i < browsers.length; i++) { - status = browsers[i].isReady ? 'idle' : 'executing' + status = browsers[i].isConnected ? 'idle' : 'executing' items.push('
  • ' + browsers[i].name + ' is ' + status + '
  • ') } browsersElement.innerHTML = items.join('\n') diff --git a/lib/browser.js b/lib/browser.js index 0d764dfec..1ff636555 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -4,14 +4,14 @@ const Result = require('./browser_result') const helper = require('./helper') const logger = require('./logger') -// The browser is ready to execute tests. -const READY = 1 +// The browser is connected but not yet been commanded to execute tests. +const CONNECTED = 1 -// The browser is executing the tests. -const EXECUTING = 2 +// The browser has been told to execute tests; it is configuring before tests execution. +const CONFIGURING = 2 -// The browser is not executing, but temporarily disconnected (waiting for reconnecting). -const READY_DISCONNECTED = 3 +// The browser is executing the tests. +const EXECUTING = 3 // The browser is executing the tests, but temporarily disconnect (waiting for reconnecting). const EXECUTING_DISCONNECTED = 4 @@ -24,7 +24,7 @@ class Browser { this.id = id this.fullName = fullName this.name = helper.browserFullNameToShort(fullName) - this.state = READY + this.state = CONNECTED this.lastResult = new Result() this.disconnectsCount = 0 this.activeSockets = [socket] @@ -54,8 +54,8 @@ class Browser { this.emitter.emit('browser_register', this) } - isReady () { - return this.state === READY + isConnected () { + return this.state === CONNECTED } toString () { @@ -76,7 +76,7 @@ class Browser { } onKarmaError (error) { - if (this.isReady()) { + if (this.isConnected()) { return } @@ -87,7 +87,7 @@ class Browser { } onInfo (info) { - if (this.isReady()) { + if (this.isConnected()) { return } @@ -114,6 +114,8 @@ class Browser { this.lastResult = new Result() this.lastResult.total = info.total + this.state = EXECUTING + if (info.total === null) { this.log.warn('Adapter did not report total number of specs.') } @@ -123,11 +125,11 @@ class Browser { } onComplete (result) { - if (this.isReady()) { + if (this.isConnected()) { return } - this.state = READY + this.state = CONNECTED this.lastResult.totalTimeEnd() if (!this.lastResult.success) { @@ -148,9 +150,9 @@ class Browser { return } - if (this.state === READY) { + if (this.state === CONNECTED) { this.disconnect() - } else if (this.state === EXECUTING) { + } else if (this.state === CONFIGURING || this.state === EXECUTING) { this.log.debug('Disconnected during run, waiting %sms for reconnecting.', this.disconnectDelay) this.state = EXECUTING_DISCONNECTED @@ -169,10 +171,10 @@ class Browser { if (this.state === EXECUTING_DISCONNECTED) { this.state = EXECUTING this.log.debug('Reconnected on %s.', newSocket.id) - } else if (this.state === EXECUTING || this.state === READY) { + } else if (this.state === CONNECTED || this.state === CONFIGURING || this.state === EXECUTING) { this.log.debug('New connection %s (already have %s)', newSocket.id, this.getActiveSocketsIds()) } else if (this.state === DISCONNECTED) { - this.state = READY + this.state = CONNECTED this.log.info('Connected on socket %s with id %s', newSocket.id, this.id) this.collection.add(this) @@ -201,7 +203,7 @@ class Browser { } // ignore - probably results from last run (after server disconnecting) - if (this.isReady()) { + if (this.isConnected()) { return } @@ -215,14 +217,15 @@ class Browser { return { id: this.id, name: this.name, - isReady: this.state === READY + isConnected: this.state === CONNECTED } } execute (config) { this.activeSockets.forEach((socket) => socket.emit('execute', config)) - this.state = EXECUTING + this.state = CONFIGURING + this.refreshNoActivityTimeout() } @@ -279,9 +282,9 @@ Browser.factory = function ( return new Browser(id, fullName, collection, emitter, socket, timer, disconnectDelay, noActivityTimeout) } -Browser.STATE_READY = READY +Browser.STATE_CONNECTED = CONNECTED +Browser.STATE_CONFIGURING = CONFIGURING Browser.STATE_EXECUTING = EXECUTING -Browser.STATE_READY_DISCONNECTED = READY_DISCONNECTED Browser.STATE_EXECUTING_DISCONNECTED = EXECUTING_DISCONNECTED Browser.STATE_DISCONNECTED = DISCONNECTED diff --git a/lib/browser_collection.js b/lib/browser_collection.js index fd77fd815..0c624d762 100644 --- a/lib/browser_collection.js +++ b/lib/browser_collection.js @@ -1,6 +1,5 @@ 'use strict' -const EXECUTING = require('./browser').STATE_EXECUTING const Result = require('./browser_result') class BrowserCollection { @@ -31,19 +30,11 @@ class BrowserCollection { return this.browsers.find((browser) => browser.id === browserId) || null } - setAllToExecuting () { - this.browsers.forEach((browser) => { - browser.state = EXECUTING - }) - - this.emitter.emit('browsers_change', this) - } - areAllReady (nonReadyList) { nonReadyList = nonReadyList || [] this.browsers.forEach((browser) => { - if (!browser.isReady()) { + if (!browser.isConnected()) { nonReadyList.push(browser) } }) diff --git a/lib/executor.js b/lib/executor.js index 55694c4b8..189c575fc 100644 --- a/lib/executor.js +++ b/lib/executor.js @@ -31,7 +31,6 @@ class Executor { log.debug('Captured %s browsers', this.capturedBrowsers.length) this.executionScheduled = false this.capturedBrowsers.clearResults() - this.capturedBrowsers.setAllToExecuting() this.pendingCount = this.capturedBrowsers.length this.runningBrowsers = this.capturedBrowsers.clone() this.emitter.emit('run_start', this.runningBrowsers) diff --git a/lib/reporters/base.js b/lib/reporters/base.js index d5227ef4a..e55a8819d 100644 --- a/lib/reporters/base.js +++ b/lib/reporters/base.js @@ -47,7 +47,7 @@ const BaseReporter = function (formatError, reportSlow, useColors, browserConsol msg += util.format(' (skipped %d)', results.skipped) } - if (browser.isReady) { + if (browser.isConnected) { if (results.disconnected) { msg += this.FINISHED_DISCONNECTED } else if (results.error) { diff --git a/test/unit/browser.spec.js b/test/unit/browser.spec.js index f375f67e0..8c670eb97 100644 --- a/test/unit/browser.spec.js +++ b/test/unit/browser.spec.js @@ -94,7 +94,7 @@ describe('Browser', () => { it('should ignore if browser not executing', () => { const spy = sinon.spy() emitter.on('browser_error', spy) - browser.state = Browser.STATE_READY + browser.state = Browser.STATE_CONNECTED browser.onKarmaError() expect(browser.lastResult.error).to.equal(false) @@ -130,7 +130,7 @@ describe('Browser', () => { const spy = sinon.spy() emitter.on('browser_dump', spy) - browser.state = Browser.STATE_READY + browser.state = Browser.STATE_CONNECTED browser.onInfo({dump: 'something'}) browser.onInfo({total: 20}) @@ -144,8 +144,13 @@ describe('Browser', () => { browser = new Browser('fake-id', 'full name', collection, emitter, socket) }) + it('should change state to EXECUTING', () => { + browser.state = Browser.STATE_CONNECTED + browser.onStart({total: 20}) + expect(browser.state).to.equal(Browser.STATE_EXECUTING) + }) + it('should set total count of specs', () => { - browser.state = Browser.STATE_EXECUTING browser.onStart({total: 20}) expect(browser.lastResult.total).to.equal(20) }) @@ -154,7 +159,6 @@ describe('Browser', () => { const spy = sinon.spy() emitter.on('browser_start', spy) - browser.state = Browser.STATE_EXECUTING browser.onStart({total: 20}) expect(spy).to.have.been.calledWith(browser, {total: 20}) @@ -172,10 +176,10 @@ describe('Browser', () => { Date.now.restore() }) - it('should set isReady to true', () => { + it('should set isConnected to true', () => { browser.state = Browser.STATE_EXECUTING browser.onComplete() - expect(browser.isReady()).to.equal(true) + expect(browser.isConnected()).to.equal(true) }) it('should fire "browsers_change" event', () => { @@ -192,7 +196,7 @@ describe('Browser', () => { emitter.on('browsers_change', spy) emitter.on('browser_complete', spy) - browser.state = Browser.STATE_READY + browser.state = Browser.STATE_CONNECTED browser.onComplete() expect(spy).not.to.have.been.called }) @@ -245,7 +249,7 @@ describe('Browser', () => { it('should not complete if browser not executing', () => { const spy = sinon.spy() emitter.on('browser_complete', spy) - browser.state = Browser.STATE_READY + browser.state = Browser.STATE_CONNECTED browser.onDisconnect('socket.io-reason', socket) expect(spy).not.to.have.been.called @@ -294,7 +298,7 @@ describe('Browser', () => { browser.reconnect(mkSocket()) - expect(browser.isReady()).to.equal(true) + expect(browser.isConnected()).to.equal(true) }) }) @@ -328,7 +332,7 @@ describe('Browser', () => { }) it('should ignore if not running', () => { - browser.state = Browser.STATE_READY + browser.state = Browser.STATE_CONNECTED browser.onResult(createSuccessResult()) browser.onResult(createSuccessResult()) browser.onResult(createFailedResult()) @@ -360,27 +364,36 @@ describe('Browser', () => { }) describe('serialize', () => { - it('should return plain object with only name, id, isReady properties', () => { + it('should return plain object with only name, id, isConnected properties', () => { browser = new Browser('fake-id', 'full name', collection, emitter, socket) - browser.state = Browser.STATE_READY + browser.state = Browser.STATE_CONNECTED browser.name = 'Browser 1.0' browser.id = '12345' - expect(browser.serialize()).to.deep.equal({id: '12345', name: 'Browser 1.0', isReady: true}) + expect(browser.serialize()).to.deep.equal({id: '12345', name: 'Browser 1.0', isConnected: true}) }) }) - describe('execute', () => { - it('should emit execute and change state to EXECUTING', () => { + describe('execute and start', () => { + it('should emit execute and change state to CONFIGURING', () => { const spyExecute = sinon.spy() const config = {} browser = new Browser('fake-id', 'full name', collection, emitter, socket) socket.on('execute', spyExecute) browser.execute(config) - expect(browser.isReady()).to.equal(false) + expect(browser.state).to.equal(Browser.STATE_CONFIGURING) expect(spyExecute).to.have.been.calledWith(config) }) + + it('should emit start and change state to EXECUTING', () => { + browser = new Browser('fake-id', 'full name', collection, emitter, socket) + browser.init() // init socket listeners + + expect(browser.state).to.equal(Browser.STATE_CONNECTED) + socket.emit('start', {total: 1}) + expect(browser.state).to.equal(Browser.STATE_EXECUTING) + }) }) describe('scenario:', () => { @@ -391,15 +404,15 @@ describe('Browser', () => { browser.state = Browser.STATE_EXECUTING socket.emit('result', {success: true, suite: [], log: []}) socket.emit('disconnect', 'socket.io reason') - expect(browser.isReady()).to.equal(false) + expect(browser.isConnected()).to.equal(false) const newSocket = mkSocket() browser.reconnect(newSocket) - expect(browser.isReady()).to.equal(false) + expect(browser.isConnected()).to.equal(false) newSocket.emit('result', {success: false, suite: [], log: []}) newSocket.emit('complete') - expect(browser.isReady()).to.equal(true) + expect(browser.isConnected()).to.equal(true) expect(browser.lastResult.success).to.equal(1) expect(browser.lastResult.failed).to.equal(1) }) @@ -427,6 +440,7 @@ describe('Browser', () => { const timer = createMockTimer() browser = new Browser('fake-id', 'Chrome 31.0', collection, emitter, socket, timer, 10) browser.init() + expect(browser.state).to.equal(Browser.STATE_CONNECTED) browser.execute() socket.emit('start', {total: 10}) @@ -443,8 +457,9 @@ describe('Browser', () => { // reconnect on a new socket (which triggers re-execution) browser.reconnect(newSocket) - expect(browser.state).to.equal(Browser.STATE_EXECUTING) + expect(browser.state).to.equal(Browser.STATE_CONFIGURING) newSocket.emit('start', {total: 11}) + expect(browser.state).to.equal(Browser.STATE_EXECUTING) socket.emit('result', {success: true, suite: [], log: []}) // expected cleared last result (should not include the results from previous run) @@ -459,6 +474,8 @@ describe('Browser', () => { // we need to keep the old socket, in the case that the new socket will disconnect. browser = new Browser('fake-id', 'Chrome 31.0', collection, emitter, socket, null, 10) browser.init() + expect(browser.state).to.equal(Browser.STATE_CONNECTED) + browser.execute() // A second connection... @@ -467,6 +484,8 @@ describe('Browser', () => { // Disconnect the second connection... browser.onDisconnect('socket.io-reason', newSocket) + expect(browser.state).to.equal(Browser.STATE_CONFIGURING) + socket.emit('start', {total: 1}) expect(browser.state).to.equal(Browser.STATE_EXECUTING) // It should still be listening on the old socket. diff --git a/test/unit/browser_collection.spec.js b/test/unit/browser_collection.spec.js index 7fb36a45f..417d2ad79 100644 --- a/test/unit/browser_collection.spec.js +++ b/test/unit/browser_collection.spec.js @@ -71,39 +71,13 @@ describe('BrowserCollection', () => { }) }) - describe('setAllToExecuting', () => { - let browsers = null - - beforeEach(() => { - browsers = [new Browser(), new Browser(), new Browser()] - browsers.forEach((browser) => { - collection.add(browser) - }) - }) - - it('should set all browsers state to executing', () => { - collection.setAllToExecuting() - browsers.forEach((browser) => { - expect(browser.isReady()).to.equal(false) - expect(browser.state).to.equal(Browser.STATE_EXECUTING) - }) - }) - - it('should fire "browsers_change" event', () => { - const spy = sinon.spy() - emitter.on('browsers_change', spy) - collection.setAllToExecuting() - expect(spy).to.have.been.called - }) - }) - describe('areAllReady', () => { let browsers = null beforeEach(() => { browsers = [new Browser(), new Browser(), new Browser()] browsers.forEach((browser) => { - browser.state = Browser.STATE_READY + browser.state = Browser.STATE_CONNECTED collection.add(browser) }) }) @@ -135,8 +109,8 @@ describe('BrowserCollection', () => { collection.add(browsers[1]) expect(collection.serialize()).to.deep.equal([ - {id: '1', name: 'B 1.0', isReady: true}, - {id: '2', name: 'B 2.0', isReady: true} + {id: '1', name: 'B 1.0', isConnected: true}, + {id: '2', name: 'B 2.0', isConnected: true} ]) }) }) From 02dc1f44ca790bd02ea5773346d6f5508b65d476 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 24 Jul 2018 10:39:47 -0700 Subject: [PATCH 009/374] chore: update contributors --- package.json | 73 +++++++++++++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 35 deletions(-) diff --git a/package.json b/package.json index 6bac5fdf5..9c87d42a7 100644 --- a/package.json +++ b/package.json @@ -40,38 +40,37 @@ "Mark Trostler ", "lukasz ", "Ciro Nunes ", - "Pawel Kozlowski ", - "Shyam Seshadri ", - "Christian Budde Christensen ", "Robo ", "Tim Cuthbertson ", - "Daniel Compton ", - "Mark Ethan Trostler ", + "Pawel Kozlowski ", + "Christian Budde Christensen ", + "Shyam Seshadri ", "Mourad ", - "Nick Malaguti ", - "Brian Di Palma ", - "Kim Joar Bekkelund ", + "Mark Ethan Trostler ", + "Daniel Compton ", "vivganes ", + "Kim Joar Bekkelund ", "joshjb84 ", - "Pieter Mees ", - "Jeff Jewiss ", - "Ilya Volodin ", - "Andrew Martin ", + "Brian Di Palma ", + "Nick Malaguti ", + "Daniel Aleksandersen ", + "pavelgj ", + "sylvain-hamel ", "David Souther ", "Iristyle ", + "Ilya Volodin ", + "Chris Hunt ", + "ywong ", "Jérémy Judéaux ", - "Daniel Aleksandersen ", - "Aymeric Beaumet ", + "Brian Ford ", + "Pieter Mees ", "Jake Champion ", + "Jeff Jewiss ", + "Chris Casola ", + "Aymeric Beaumet ", "Georgii Dolzhykov ", - "Chris Hunt ", - "Brian Ford ", "Marcello Nuccio ", - "Chris Casola ", - "pavelgj ", - "sylvain-hamel ", - "ywong ", - "David Herges ", + "Andrew Martin ", "Ruben Bridgewater ", "Réda Housni Alaoui ", "Ethan J. Brown ", @@ -81,48 +80,51 @@ "Filipe Guerra ", "David Pärsson ", "Bulat Shakirzyanov ", - "Shane Russell ", "Jonas Pommerening ", + "Shane Russell ", "Jonathan Freeman ", - "Stefan Dragnev ", "Josh ", + "Stefan Dragnev ", "Steve Mao ", "Steve Mao ", "Steve Van Opstal ", "Sylvain Hamel ", "Greenkeeper ", "Andrew Morris ", - "Thomas Parisot ", "KJ Tsanaktsidis ", - "Tom Erik Støwer ", + "Thomas Parisot ", "Aseem Bansal ", "ChangZhuo Chen (陳昌倬) ", + "Tom Erik Støwer ", "Hugues Malphettes ", "Igor Minar ", + "Igor Minar ", + "Kelly Jensen ", "Vivek Ganesan ", "Vladimir Starkov ", - "Kelly Jensen ", - "Igor Minar ", "Kevin Huang ", "Parashuram ", "Pat Tullmann ", "Kevin WENNER ", "PatrickJS ", - "comdiv ", "Levi Thomason ", - "Luke Page ", + "comdiv ", "Bryan Smith ", + "Luke Page ", "James Ford ", - "karmarunnerbot ", "DarthCharles ", + "James Talmage ", "Richard Harrington ", + "karmarunnerbot ", "Roarke Gaskill ", + "David Herges ", "ngiebel ", - "rdodev ", - "James Talmage ", "Robin Liang ", + "rdodev ", + "Karol Fabjańczuk ", "Karolis Narkevicius ", "Keats ", + "Keen Yee Liau ", "Keith Cirkel ", "Kent C. Dodds ", "Kevin Ortman ", @@ -195,7 +197,7 @@ "Samuel Marks ", "Saugat Acharya ", "Schmulik Raskin ", - "Sergei Startsev ", + "Sergei Startsev ", "Sergey Kruk ", "Sergey Simonchik ", "Seth Rhodes ", @@ -232,6 +234,7 @@ "adamnation ", "ahaurw01 ", "ashaffer ", + "cexbrayat ", "coderaiser ", "compact ", "coridrew ", @@ -261,6 +264,7 @@ "Ales Rosina ", "Alexander Pepper ", "Alexander Shtuchkin ", + "Alexei ", "Anders Ekdahl ", "Anders Janmyr ", "Andreas Krummsdorf ", @@ -351,8 +355,7 @@ "Jurko Gospodnetić ", "Justin Ridgewell ", "KahWee Teng ", - "Karl Lindmark ", - "Karol Fabjańczuk " + "Karl Lindmark " ], "dependencies": { "bluebird": "^3.3.0", From 00189471d383600a95415ea526b152dd556ce751 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 24 Jul 2018 10:39:53 -0700 Subject: [PATCH 010/374] chore: release v2.0.5 --- CHANGELOG.md | 19 +++++++++++++++++++ package.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7b8e13a8..f4c0013db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ + +## [2.0.5](https://github.com/karma-runner/karma/compare/v2.0.4...v2.0.5) (2018-07-24) + + +### Bug Fixes + +* remove circular reference in Browser ([518cb11](https://github.com/karma-runner/karma/commit/518cb11)), closes [#3075](https://github.com/karma-runner/karma/issues/3075) +* **browser:** ensure browser state is EXECUTING when tests start ([#3074](https://github.com/karma-runner/karma/issues/3074)) ([dc7265b](https://github.com/karma-runner/karma/commit/dc7265b)), closes [#1640](https://github.com/karma-runner/karma/issues/1640) +* **doc:** Document release steps for admins ([#3063](https://github.com/karma-runner/karma/issues/3063)) ([a701732](https://github.com/karma-runner/karma/commit/a701732)) +* **middleware:** Obey the Promise API. ([93ba05a](https://github.com/karma-runner/karma/commit/93ba05a)) +* **server:** pass bound port to prevent`EADDRINUSE` issue. ([#3065](https://github.com/karma-runner/karma/issues/3065)) ([850a90b](https://github.com/karma-runner/karma/commit/850a90b)) + + +### Features + +* **preprocessor:** Allow preprocessor to handle binary files ([#3054](https://github.com/karma-runner/karma/issues/3054)) ([7b66e18](https://github.com/karma-runner/karma/commit/7b66e18)) + + + ## [2.0.4](https://github.com/karma-runner/karma/compare/v2.0.3...v2.0.4) (2018-06-21) diff --git a/package.json b/package.json index 9c87d42a7..f6c1a18ef 100644 --- a/package.json +++ b/package.json @@ -461,7 +461,7 @@ "engines": { "node": ">= 4" }, - "version": "2.0.4", + "version": "2.0.5", "license": "MIT", "scripts": { "lint": "eslint . --ext js --ignore-pattern *.tpl.js", From c5dc62db7642b8ca9504e71319e3b80143b8510a Mon Sep 17 00:00:00 2001 From: Nir Moav Date: Wed, 25 Jul 2018 10:42:07 +0300 Subject: [PATCH 011/374] docs: better clarity for API usage extract config to a var to create better clarity for API usage --- docs/dev/04-public-api.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/dev/04-public-api.md b/docs/dev/04-public-api.md index ef5efacec..21974dd40 100644 --- a/docs/dev/04-public-api.md +++ b/docs/dev/04-public-api.md @@ -8,7 +8,8 @@ You can, however, call Karma programmatically from your node module. Here is the ```javascript var Server = require('karma').Server -var server = new Server({port: 9876}, function(exitCode) { +var karmaConfig = {port: 9876} +var server = new Server(karmaConfig, function(exitCode) { console.log('Karma has exited with ' + exitCode) process.exit(exitCode) }) From 94a6728de96b44788f7179ae1dc29602746d55a6 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 25 Jul 2018 16:46:34 -0700 Subject: [PATCH 012/374] chore: remove support for node 4, update log4js (#3082) This PR will start v3.0 --- .travis.yml | 1 - appveyor.yml | 1 - package.json | 4 ++-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7dfc3ae9a..c55edaec1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ sudo: false language: node_js node_js: - - 4 - 6 - 8 - 9 diff --git a/appveyor.yml b/appveyor.yml index 12f756f1c..c30a4056a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,6 @@ version: "{build}" environment: matrix: - - nodejs_version: "4" - nodejs_version: "6" - nodejs_version: "8" - nodejs_version: "10" diff --git a/package.json b/package.json index f6c1a18ef..933c1192b 100644 --- a/package.json +++ b/package.json @@ -373,7 +373,7 @@ "http-proxy": "^1.13.0", "isbinaryfile": "^3.0.0", "lodash": "^4.17.4", - "log4js": "^2.5.3", + "log4js": "^3.0.0", "mime": "^1.3.4", "minimatch": "^3.0.2", "optimist": "^0.6.1", @@ -459,7 +459,7 @@ "karma": "./bin/karma" }, "engines": { - "node": ">= 4" + "node": ">= 6" }, "version": "2.0.5", "license": "MIT", From 88b977fcada5d08ae8d5bba9bc8eefc8404eff82 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 26 Jul 2018 08:26:59 -0700 Subject: [PATCH 013/374] fix(config): wait 20s for browser activity. (#3087) On low-horsepower CI systems karma frequently times out waiting for phantomjs. We see this in our Travis-CI runs. Users also see it: https://github.com/karma-runner/karma-phantomjs-launcher/issues/126. --- docs/config/01-configuration-file.md | 4 ++-- lib/config.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config/01-configuration-file.md b/docs/config/01-configuration-file.md index 02ab11bdb..656d3bf03 100644 --- a/docs/config/01-configuration-file.md +++ b/docs/config/01-configuration-file.md @@ -156,7 +156,7 @@ a flaky network link between the Karma server and the browsers. ## browserNoActivityTimeout **Type:** Number -**Default:** `10000` +**Default:** `20000` **Description:** How long will Karma wait for a message from a browser before disconnecting from it (in ms). @@ -581,7 +581,7 @@ Note: Using `'https:'` requires you to specify `httpsServerOptions`. **Description:** Module used for Karma webserver. -Uses the provided module instead of node's built in `http` or `https` module. The module loaded here must exactly match the interface of node's http module. This can be useful for loading in a module like `node-http2` to allow for http2 support. +Uses the provided module instead of node's built in `http` or `https` module. The module loaded here must exactly match the interface of node's http module. This can be useful for loading in a module like `node-http2` to allow for http2 support. Note: if you're using this to enable `http2` you must also set the `protocol` to `https:` and specify certificates as http2 can only run of https. diff --git a/lib/config.js b/lib/config.js index 488ae41fe..f446defb6 100644 --- a/lib/config.js +++ b/lib/config.js @@ -343,7 +343,7 @@ class Config { } this.browserDisconnectTimeout = 2000 this.browserDisconnectTolerance = 0 - this.browserNoActivityTimeout = 10000 + this.browserNoActivityTimeout = 20000 this.processKillTimeout = 2000 this.concurrency = Infinity this.failOnEmptyTestSuite = true From a58fa45c1df08ff4e74f9e75379f74c1311073c3 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Fri, 27 Jul 2018 11:13:37 -0700 Subject: [PATCH 014/374] fix(travis): Validate TRAVIS_PULL_REQUEST_SHA rather than TRAVIS_COMMIT. (#3093) Also add some debug messages for commits and remove an old node4 command. --- .travis.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index c55edaec1..c014cb844 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,13 +14,13 @@ env: matrix: fast_finish: true include: - - node_js: "8" + - name: "Lint code and commit message format" + node_js: "8" env: VALIDATE_COMMIT_MSG=true LINT=true before_install: - npm config set loglevel warn - g++-4.8 --version - - if [[ "`node --version`" = v4* ]]; then npm install -g npm@latest-3; fi addons: firefox: @@ -36,7 +36,10 @@ before_script: - sh -e /etc/init.d/xvfb start - npm run init - export $(openssl aes-256-cbc -pass env:CREDENTIALS_PASS -d -in credentials) - - 'if [ "$VALIDATE_COMMIT_MSG" == "true" ]; then ./scripts/validate-commit-msg.sh $TRAVIS_COMMIT; fi' + - echo "git head commit $(git rev-parse FETCH_HEAD)" + - echo "TRAVIS_COMMIT $TRAVIS_COMMIT" + - echo "TRAVIS_PULL_REQUEST_SHA $TRAVIS_PULL_REQUEST_SHA" + - 'if [ "$VALIDATE_COMMIT_MSG" == "true" ]; then ./scripts/validate-commit-msg.sh $TRAVIS_PULL_REQUEST_SHA; fi' - 'if [ "$LINT" == "true" ]; then npm run lint; fi' script: From f6d2f0ea5a3323c5e359e26fe5be9fbf68db819f Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Fri, 27 Jul 2018 15:18:14 -0700 Subject: [PATCH 015/374] fix(config): Wait 30s for browser activity per Travis. (#3091) https://docs.travis-ci.com/user/gui-and-headless-browsers/#karma-and-firefox-inactivity-timeouts --- docs/config/01-configuration-file.md | 4 ++-- lib/config.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/config/01-configuration-file.md b/docs/config/01-configuration-file.md index 656d3bf03..8bc689cc2 100644 --- a/docs/config/01-configuration-file.md +++ b/docs/config/01-configuration-file.md @@ -156,11 +156,11 @@ a flaky network link between the Karma server and the browsers. ## browserNoActivityTimeout **Type:** Number -**Default:** `20000` +**Default:** `30000` **Description:** How long will Karma wait for a message from a browser before disconnecting from it (in ms). -If, during test execution, Karma does not receive any message from a browser within `browserNoActivityTimeout`(ms), it will disconnect from the browser. +If, during test execution, Karma does not receive any message from a browser within `browserNoActivityTimeout`(ms), it will disconnect from the browser. The default is the one recommended by Travis (https://docs.travis-ci.com/user/gui-and-headless-browsers/#karma-and-firefox-inactivity-timeouts) ## browsers diff --git a/lib/config.js b/lib/config.js index f446defb6..1d0369cbc 100644 --- a/lib/config.js +++ b/lib/config.js @@ -343,7 +343,7 @@ class Config { } this.browserDisconnectTimeout = 2000 this.browserDisconnectTolerance = 0 - this.browserNoActivityTimeout = 20000 + this.browserNoActivityTimeout = 30000 this.processKillTimeout = 2000 this.concurrency = Infinity this.failOnEmptyTestSuite = true From 56fda53ec19a1a691cd80342fef9b23d9f9fe4d2 Mon Sep 17 00:00:00 2001 From: Terry Date: Tue, 31 Jul 2018 23:58:44 +0800 Subject: [PATCH 016/374] fix(init): add "ChromeHeadless" to the browsers' options (#3096) --- lib/completion.js | 2 +- lib/init.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/completion.js b/lib/completion.js index 25b646904..157c81611 100644 --- a/lib/completion.js +++ b/lib/completion.js @@ -13,7 +13,7 @@ const options = { '--no-colors': BOOLEAN, '--reporters': ['dots', 'progress'], '--no-reporters': BOOLEAN, - '--browsers': ['Chrome', 'ChromeCanary', 'Firefox', 'PhantomJS', 'Safari', 'Opera'], + '--browsers': ['Chrome', 'ChromeHeadless', 'ChromeCanary', 'Firefox', 'PhantomJS', 'Safari', 'Opera'], '--no-browsers': BOOLEAN, '--single-run': BOOLEAN, '--no-single-run': BOOLEAN, diff --git a/lib/init.js b/lib/init.js index f8fae6055..9edafb715 100755 --- a/lib/init.js +++ b/lib/init.js @@ -100,7 +100,7 @@ var questions = [{ id: 'browsers', question: 'Do you want to capture any browsers automatically ?', hint: 'Press tab to list possible options. Enter empty string to move to the next question.', - options: ['Chrome', 'ChromeCanary', 'Firefox', 'Safari', 'PhantomJS', 'Opera', 'IE', ''], + options: ['Chrome', 'ChromeHeadless', 'ChromeCanary', 'Firefox', 'Safari', 'PhantomJS', 'Opera', 'IE', ''], validate: validateBrowser, multiple: true }, { From fba5d365146bad122d54af75bf191ad0b6091dd0 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 31 Jul 2018 12:21:25 -0700 Subject: [PATCH 017/374] fix(travis): validate TRAVIS_COMMIT if TRAVIS_PULL_REQUEST_SHA is not set. (#3094) Looks like the pre-merge travis run sets TRAVIS_PULL_REQUEST_SHA but the post-merge run does not. In the post-merge the TRAVIS_COMMIT should be the PR, so validate it. --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c014cb844..1d1e432cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,10 +36,11 @@ before_script: - sh -e /etc/init.d/xvfb start - npm run init - export $(openssl aes-256-cbc -pass env:CREDENTIALS_PASS -d -in credentials) - - echo "git head commit $(git rev-parse FETCH_HEAD)" - echo "TRAVIS_COMMIT $TRAVIS_COMMIT" - echo "TRAVIS_PULL_REQUEST_SHA $TRAVIS_PULL_REQUEST_SHA" - - 'if [ "$VALIDATE_COMMIT_MSG" == "true" ]; then ./scripts/validate-commit-msg.sh $TRAVIS_PULL_REQUEST_SHA; fi' + - COMMIT_TO_VALIDATE=${TRAVIS_PULL_REQUEST_SHA:-TRAVIS_COMMIT} + - echo "COMMIT_TO_VALIDATE $COMMIT_TO_VALIDATE" + - 'if [ "$VALIDATE_COMMIT_MSG" == "true" ]; then ./scripts/validate-commit-msg.sh $COMMIT_TO_VALIDATE; fi' - 'if [ "$LINT" == "true" ]; then npm run lint; fi' script: From 90f5546a9f88199f8118eae506922d4e8ee38945 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 31 Jul 2018 18:28:13 -0700 Subject: [PATCH 018/374] fix(travis): use the value not the key name. (#3097) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1d1e432cd..c6a13a28f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -38,7 +38,7 @@ before_script: - export $(openssl aes-256-cbc -pass env:CREDENTIALS_PASS -d -in credentials) - echo "TRAVIS_COMMIT $TRAVIS_COMMIT" - echo "TRAVIS_PULL_REQUEST_SHA $TRAVIS_PULL_REQUEST_SHA" - - COMMIT_TO_VALIDATE=${TRAVIS_PULL_REQUEST_SHA:-TRAVIS_COMMIT} + - COMMIT_TO_VALIDATE=${TRAVIS_PULL_REQUEST_SHA:-$TRAVIS_COMMIT} - echo "COMMIT_TO_VALIDATE $COMMIT_TO_VALIDATE" - 'if [ "$VALIDATE_COMMIT_MSG" == "true" ]; then ./scripts/validate-commit-msg.sh $COMMIT_TO_VALIDATE; fi' - 'if [ "$LINT" == "true" ]; then npm run lint; fi' From 0fdd8f9e91b6039c07c857e11a5d7f7b3205cf01 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Sat, 4 Aug 2018 09:09:06 -0700 Subject: [PATCH 019/374] chore(deps): update socket.io -> 2.1.1 (#3099) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 933c1192b..f64a05bdc 100644 --- a/package.json +++ b/package.json @@ -381,7 +381,7 @@ "range-parser": "^1.2.0", "rimraf": "^2.6.0", "safe-buffer": "^5.0.1", - "socket.io": "2.0.4", + "socket.io": "2.1.1", "source-map": "^0.6.1", "tmp": "0.0.33", "useragent": "2.2.1" From 02f54c6c57f5a3e0be3a44e8e5ca1db98b8dbc8f Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Sat, 4 Aug 2018 09:15:16 -0700 Subject: [PATCH 020/374] fix(server): Exit clean on unhandledRejections. (#3092) Add a handler for unhandledRejections, log error and disconnect all, then exit. Also remove broken, untested rejection handler in middleware. Prior to #3064, this block was probably unreachable; the arguments to serveStaticFile are incorrect. --- lib/middleware/karma.js | 8 -------- lib/server.js | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 5b4ac8718..211b53424 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -236,14 +236,6 @@ function createKarmaMiddleware ( .replace('%MAPPINGS%', mappings) .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) }) - }, function (errorFiles) { - serveStaticFile(requestUrl, response, function (data) { - common.setNoCacheHeaders(response) - return data.replace('%SCRIPTS%', '').replace('%CLIENT_CONFIG%', '').replace('%MAPPINGS%', - 'window.__karma__.error("TEST RUN WAS CANCELLED because ' + - (errorFiles.length > 1 ? 'these files contain' : 'this file contains') + - ' some errors:\\n ' + errorFiles.join('\\n ') + '");') - }) }) } else if (requestUrl === '/context.json') { return filesPromise.then(function (files) { diff --git a/lib/server.js b/lib/server.js index 1b440231c..043c8a29c 100644 --- a/lib/server.js +++ b/lib/server.js @@ -353,6 +353,11 @@ class Server extends KarmaEventEmitter { this.log.error(error) disconnectBrowsers(1) }) + + processWrapper.on('unhandledRejection', (error) => { + this.log.error(error) + disconnectBrowsers(1) + }) } _detach (config, done) { From 10025695c4af3ea983c2c1316ec4ef078e056ebc Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Sun, 5 Aug 2018 11:02:34 -0700 Subject: [PATCH 021/374] chore(ci): drop node 9 from travis tests (#3100) --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c6a13a28f..f524aba18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ language: node_js node_js: - 6 - 8 - - 9 - 10 env: From 173848e3a0659bceea9d87d4eeee6c8a11c0f1a1 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 7 Aug 2018 11:10:14 -0700 Subject: [PATCH 022/374] Remove erroneous change log entries for 2.0.3 Fixes #3105 --- CHANGELOG.md | 307 +-------------------------------------------------- 1 file changed, 2 insertions(+), 305 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f4c0013db..42787d997 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,313 +32,10 @@ -## [2.0.3](https://github.com/karma-runner/karma/compare/v0.12.16...v2.0.3) (2018-06-15) - - -### Bug Fixes - -* **BaseReporter:** log message correctly with just one browser ([#3045](https://github.com/karma-runner/karma/issues/3045)) ([c1eb236](https://github.com/karma-runner/karma/commit/c1eb236)) -* **browser:** don't add already active socket again on reconnect ([37a7958](https://github.com/karma-runner/karma/commit/37a7958)) -* **browser:** filter browser logging by level ([35965d9](https://github.com/karma-runner/karma/commit/35965d9)), closes [#2228](https://github.com/karma-runner/karma/issues/2228) -* **browser:** nicer "disconnect" - no more "Disconnectedundefined" ([a987d63](https://github.com/karma-runner/karma/commit/a987d63)) -* **build:** pin npm version in appveyor to v3, compat with node 4 ([#2983](https://github.com/karma-runner/karma/issues/2983)) ([bc1453e](https://github.com/karma-runner/karma/commit/bc1453e)) -* **ci:** Repaired AppVeyor for Node.js@0.12 ([cbfd98c](https://github.com/karma-runner/karma/commit/cbfd98c)) -* **cli:** override if an arg is defined multiple times ([31eb2c2](https://github.com/karma-runner/karma/commit/31eb2c2)), closes [#1192](https://github.com/karma-runner/karma/issues/1192) -* **cli:** print UserAgent string verbatim if from an unknown browser ([9d97226](https://github.com/karma-runner/karma/commit/9d97226)) -* **cli:** restore shell completion in the npm package ([f56b5a5](https://github.com/karma-runner/karma/commit/f56b5a5)), closes [#2351](https://github.com/karma-runner/karma/issues/2351) -* **cli:** Use `bin` field in package.json ([6823926](https://github.com/karma-runner/karma/commit/6823926)), closes [#1351](https://github.com/karma-runner/karma/issues/1351) -* **client:** add ES5 shim ([14c30b7](https://github.com/karma-runner/karma/commit/14c30b7)), closes [#1529](https://github.com/karma-runner/karma/issues/1529) -* **client:** add proxy support to stringify ([be10116](https://github.com/karma-runner/karma/commit/be10116)) -* **client:** does not throws an error for non DOM object that has `tagName` property ([ba55afb](https://github.com/karma-runner/karma/commit/ba55afb)), closes [#2139](https://github.com/karma-runner/karma/issues/2139) -* **client:** don't crash if receive array-like results ([e095411](https://github.com/karma-runner/karma/commit/e095411)), closes [#2061](https://github.com/karma-runner/karma/issues/2061) -* **client:** dynamic protocol for socket.io ([c986eef](https://github.com/karma-runner/karma/commit/c986eef)), closes [#1400](https://github.com/karma-runner/karma/issues/1400) -* **client:** Fix stringify serializing objects ([0d0972a](https://github.com/karma-runner/karma/commit/0d0972a)) -* **client:** Revert back to old reloading detection ([f1c22d6](https://github.com/karma-runner/karma/commit/f1c22d6)), closes [#1656](https://github.com/karma-runner/karma/issues/1656) -* **client:** serialise DOM objects ([1f73be4](https://github.com/karma-runner/karma/commit/1f73be4)), closes [#1106](https://github.com/karma-runner/karma/issues/1106) -* **client:** Update location detection for socket.io ([7a23fa5](https://github.com/karma-runner/karma/commit/7a23fa5)) -* **client:** Use supported shim path. ([184f12e](https://github.com/karma-runner/karma/commit/184f12e)) -* **client:** Wait for childwindow to load ([c1bb15a](https://github.com/karma-runner/karma/commit/c1bb15a)) -* **client:** Wait for iframe to be loaded ([1631474](https://github.com/karma-runner/karma/commit/1631474)), closes [#1652](https://github.com/karma-runner/karma/issues/1652) -* **client.html:** always open debug.html in a new browser process ([d176bcf](https://github.com/karma-runner/karma/commit/d176bcf)) -* **common:** fix AppVeyor build ([6c5e7d0](https://github.com/karma-runner/karma/commit/6c5e7d0)) -* **common:** more detailed info about error ([424aacc](https://github.com/karma-runner/karma/commit/424aacc)) -* **common:** Proxy function toString does not contain Proxy. ([4fb3484](https://github.com/karma-runner/karma/commit/4fb3484)) -* **common:** stringify error on 'Cannot convert a Symbol value to a string' ([#2990](https://github.com/karma-runner/karma/issues/2990)) ([65b658a](https://github.com/karma-runner/karma/commit/65b658a)), closes [#2856](https://github.com/karma-runner/karma/issues/2856) -* **config:** [#1113](https://github.com/karma-runner/karma/issues/1113) Watching is not working properly on linux ([c91ffbc](https://github.com/karma-runner/karma/commit/c91ffbc)) -* **config:** add crossOriginAttribute config option ([1e465b1](https://github.com/karma-runner/karma/commit/1e465b1)) -* **config:** Call debug log methods after setting the loglevel based upon config/cli-options. ([a340dae](https://github.com/karma-runner/karma/commit/a340dae)) -* **config:** Call debug log methods after setting the loglevel based upon config/cli-options. ([99fd3f0](https://github.com/karma-runner/karma/commit/99fd3f0)) -* **config:** corrects spelling in example config template ([9fafc60](https://github.com/karma-runner/karma/commit/9fafc60)) -* **config:** Default remaining client options if any are set ([632dd5e](https://github.com/karma-runner/karma/commit/632dd5e)), closes [#961](https://github.com/karma-runner/karma/issues/961) -* **config:** Error when browers option isn't array ([b695460](https://github.com/karma-runner/karma/commit/b695460)) -* **config:** Log the final config just before use. ([#3041](https://github.com/karma-runner/karma/issues/3041)) ([05dd09a](https://github.com/karma-runner/karma/commit/05dd09a)) -* **config:** Retry install with appveyor-retry. ([17d5791](https://github.com/karma-runner/karma/commit/17d5791)) -* **config:** Workaround npm 5.4 windows bug ([ec47d81](https://github.com/karma-runner/karma/commit/ec47d81)) -* **context:** Updated postMessage listener to stop validating non-Karma messages ([306e565](https://github.com/karma-runner/karma/commit/306e565)) -* **debug-runner:** support asynchronous tests in the debug runner ([a36f3eb](https://github.com/karma-runner/karma/commit/a36f3eb)), closes [#2811](https://github.com/karma-runner/karma/issues/2811) -* **deps:** freeze socket.io version ([73e300d](https://github.com/karma-runner/karma/commit/73e300d)) -* **deps:** Update dependencies ([b9a4ce9](https://github.com/karma-runner/karma/commit/b9a4ce9)), closes [#1410](https://github.com/karma-runner/karma/issues/1410) -* **deps:** Update log4js in package.json ([#2996](https://github.com/karma-runner/karma/issues/2996)) ([667b47e](https://github.com/karma-runner/karma/commit/667b47e)) -* **deps:** update socket.io to version 2.0.3. ([3b7b019](https://github.com/karma-runner/karma/commit/3b7b019)), closes [#2821](https://github.com/karma-runner/karma/issues/2821) [#2777](https://github.com/karma-runner/karma/issues/2777) -* **deps:** Upgrade connect 3. ([b490985](https://github.com/karma-runner/karma/commit/b490985)), closes [#1410](https://github.com/karma-runner/karma/issues/1410) -* **docs:** fix stopper.stop wrong variable name. closes [#2244](https://github.com/karma-runner/karma/issues/2244) ([0745a00](https://github.com/karma-runner/karma/commit/0745a00)) -* **docs:** Remove mention of pre 1.0.0 version ([#3010](https://github.com/karma-runner/karma/issues/3010)) ([6847ca0](https://github.com/karma-runner/karma/commit/6847ca0)) -* **eslint:** Fix formatting for the new ESLint 1.8.0 ([dc1bbab](https://github.com/karma-runner/karma/commit/dc1bbab)) -* **executor:** ensure run_complete is emitted last ([9c894f9](https://github.com/karma-runner/karma/commit/9c894f9)), closes [#2210](https://github.com/karma-runner/karma/issues/2210) -* **file_list:** follow symlinks ([ee26748](https://github.com/karma-runner/karma/commit/ee26748)) -* **file_list:** Incorrect response after remove and add file ([0dbc020](https://github.com/karma-runner/karma/commit/0dbc020)) -* **file-list:** always use file from first matcher ([74bfdf3](https://github.com/karma-runner/karma/commit/74bfdf3)) -* **file-list:** Ensure autowatchDelay is working ([0f33268](https://github.com/karma-runner/karma/commit/0f33268)), closes [#1520](https://github.com/karma-runner/karma/issues/1520) -* **file-list:** Ensure autowatchDelay is working. ([655599a](https://github.com/karma-runner/karma/commit/655599a)), closes [#1520](https://github.com/karma-runner/karma/issues/1520) -* **file-list:** Ensure files are sorted and unique ([9dc5f8b](https://github.com/karma-runner/karma/commit/9dc5f8b)), closes [#1498](https://github.com/karma-runner/karma/issues/1498) [#1499](https://github.com/karma-runner/karma/issues/1499) -* **file-list:** ensure patterns are comparable ([4d1bf3e](https://github.com/karma-runner/karma/commit/4d1bf3e)), closes [#2194](https://github.com/karma-runner/karma/issues/2194) -* **file-list:** Normalize glob patterns ([fb841a7](https://github.com/karma-runner/karma/commit/fb841a7)), closes [#1494](https://github.com/karma-runner/karma/issues/1494) -* **file-list:** refresh resolves before 'file_list_modified' event ([65f1eca](https://github.com/karma-runner/karma/commit/65f1eca)), closes [#1550](https://github.com/karma-runner/karma/issues/1550) -* **file-list:** Stop polluting global environment with core-js ([0988022](https://github.com/karma-runner/karma/commit/0988022)) -* **file-list:** Use correct find function ([4cfaae9](https://github.com/karma-runner/karma/commit/4cfaae9)) -* **file-list:** use lodash find() ([3bd15a7](https://github.com/karma-runner/karma/commit/3bd15a7)), closes [#1533](https://github.com/karma-runner/karma/issues/1533) -* **file-list:** Use modified throttle instead of debounce ([cb2aafb](https://github.com/karma-runner/karma/commit/cb2aafb)), closes [#1545](https://github.com/karma-runner/karma/issues/1545) -* **files:** Ignore included:false pattern ([db42a7f](https://github.com/karma-runner/karma/commit/db42a7f)), closes [#1530](https://github.com/karma-runner/karma/issues/1530) -* **flaky-test:** Add time to beforeEach() to allow plugins to load on first pass. ([#3025](https://github.com/karma-runner/karma/issues/3025)) ([31d9a08](https://github.com/karma-runner/karma/commit/31d9a08)) -* **helper:** Ensure browser detection is handled in the unkown case ([9328f67](https://github.com/karma-runner/karma/commit/9328f67)) -* **helper:** Patched replaceWinPath from choking on `null` values ([caa4d21](https://github.com/karma-runner/karma/commit/caa4d21)) -* **init:** fix test-main.(js/coffee) generation ([d8521ef](https://github.com/karma-runner/karma/commit/d8521ef)), closes [#1120](https://github.com/karma-runner/karma/issues/1120) [#896](https://github.com/karma-runner/karma/issues/896) -* **init:** Make the requirejs config template normalize paths ([54dcce3](https://github.com/karma-runner/karma/commit/54dcce3)), closes [/github.com/karma-runner/karma/issues/513#issuecomment-48616784](https://github.com//github.com/karma-runner/karma/issues/513/issues/issuecomment-48616784) -* **karma:** Escape quotes for file names. This fixes issue [#1876](https://github.com/karma-runner/karma/issues/1876). ([9dff3f3](https://github.com/karma-runner/karma/commit/9dff3f3)) -* **launcher:** Allow dynamic browser launches ([2b7d703](https://github.com/karma-runner/karma/commit/2b7d703)) -* **launcher:** Continue with exit when SIGKILL fails ([1eaccb4](https://github.com/karma-runner/karma/commit/1eaccb4)) -* **launcher:** exclude concurrent browser on launcher restart ([96f8f14](https://github.com/karma-runner/karma/commit/96f8f14)), closes [#2280](https://github.com/karma-runner/karma/issues/2280) -* **launcher:** send sigkill on timeout when force killing ([c615c1f](https://github.com/karma-runner/karma/commit/c615c1f)) -* **launchers:** Listen to the correct error event. ([45a6922](https://github.com/karma-runner/karma/commit/45a6922)) -* **lint:** exempt built files ([#3024](https://github.com/karma-runner/karma/issues/3024)) ([bc9acd3](https://github.com/karma-runner/karma/commit/bc9acd3)) -* **logging:** Summarize SKIPPED tests in debug.html. ([a01100f](https://github.com/karma-runner/karma/commit/a01100f)), closes [#1111](https://github.com/karma-runner/karma/issues/1111) -* **logging:** Upgrade to log4js 2.x API. ([#2868](https://github.com/karma-runner/karma/issues/2868)) ([f6f8707](https://github.com/karma-runner/karma/commit/f6f8707)), closes [#2858](https://github.com/karma-runner/karma/issues/2858) -* **middleware:** Actually serve the favicon. ([f12db63](https://github.com/karma-runner/karma/commit/f12db63)) -* **middleware:** add file type to absolute urls ([bd1f799](https://github.com/karma-runner/karma/commit/bd1f799)) -* **middleware:** avoid using deprecated Buffer API ([018e6be](https://github.com/karma-runner/karma/commit/018e6be)), closes [/nodejs.org/api/deprecations.html#deprecations_dep0005](https://github.com//nodejs.org/api/deprecations.html/issues/deprecations_dep0005) -* **middleware:** change to use vanilla for loop ([ac62cc0](https://github.com/karma-runner/karma/commit/ac62cc0)), closes [#2671](https://github.com/karma-runner/karma/issues/2671) -* **middleware:** Correct spelling of middleware logger name ([9e9e7e6](https://github.com/karma-runner/karma/commit/9e9e7e6)) -* **middleware:** does not work with mootools ([#2591](https://github.com/karma-runner/karma/issues/2591)) ([2685e13](https://github.com/karma-runner/karma/commit/2685e13)) -* **middleware:** ensure Range headers adhere more closely to RFC 2616 ([8b1b4b1](https://github.com/karma-runner/karma/commit/8b1b4b1)), closes [#2310](https://github.com/karma-runner/karma/issues/2310) -* **middleware:** fix WARN log when passing undefined error handler to promise.then ([20b87de](https://github.com/karma-runner/karma/commit/20b87de)), closes [#2227](https://github.com/karma-runner/karma/issues/2227) -* **middleware:** Inject `config.urlRoot`. ([569ca0e](https://github.com/karma-runner/karma/commit/569ca0e)), closes [#1516](https://github.com/karma-runner/karma/issues/1516) -* **middleware:** update `Buffer` usage ([3d94b8c](https://github.com/karma-runner/karma/commit/3d94b8c)) -* **package.json:** sinon-chai 2.13 is not compatible with sinon 4.x ([#2977](https://github.com/karma-runner/karma/issues/2977)) ([e095b05](https://github.com/karma-runner/karma/commit/e095b05)) -* **preprocessor:** Better handling of failing preprocessors ([a2376b8](https://github.com/karma-runner/karma/commit/a2376b8)), closes [#1521](https://github.com/karma-runner/karma/issues/1521) -* **preprocessor:** calculate sha1 on content returned from a preprocessor ([6cf7955](https://github.com/karma-runner/karma/commit/6cf7955)), closes [#1204](https://github.com/karma-runner/karma/issues/1204) -* **preprocessor:** Directory names with dots ([4b5e094](https://github.com/karma-runner/karma/commit/4b5e094)) -* **preprocessor:** Improve handling of failed preprocessors ([e726d1c](https://github.com/karma-runner/karma/commit/e726d1c)), closes [#1521](https://github.com/karma-runner/karma/issues/1521) -* **preprocessor:** Lookup patterns once invoked ([00a2781](https://github.com/karma-runner/karma/commit/00a2781)), closes [#1340](https://github.com/karma-runner/karma/issues/1340) -* **preprocessor:** renamed handeFile to readFileCallback ([92a8c81](https://github.com/karma-runner/karma/commit/92a8c81)) -* **preprocessor:** retry if fs.readFile fails ([4b60513](https://github.com/karma-runner/karma/commit/4b60513)) -* **preprocessor:** Throw error if can't open file ([bb4edde](https://github.com/karma-runner/karma/commit/bb4edde)) -* **preprocessor:** throw if retry fails ([2789bf5](https://github.com/karma-runner/karma/commit/2789bf5)) -* **preprocessor:** treat *.gz files as binary ([1b56932](https://github.com/karma-runner/karma/commit/1b56932)) -* **preprocessor:** treat *.swf files as binary ([62d7d38](https://github.com/karma-runner/karma/commit/62d7d38)) -* **preprocessor:** treat *.tgz, *.tbz2, *.txz & *.xz as binary ([7b64244](https://github.com/karma-runner/karma/commit/7b64244)) -* **proxy:** More useful proxyError log message ([96640a7](https://github.com/karma-runner/karma/commit/96640a7)) -* **proxy:** Pass protocol in target object to enable https requests ([142db90](https://github.com/karma-runner/karma/commit/142db90)) -* **proxy:** Port mixup and infinite loop ([05616a2](https://github.com/karma-runner/karma/commit/05616a2)), closes [#1987](https://github.com/karma-runner/karma/issues/1987) -* **proxy:** proxy to correct port ([a483636](https://github.com/karma-runner/karma/commit/a483636)) -* **reporter:** Better handling of non string error ([82f1c12](https://github.com/karma-runner/karma/commit/82f1c12)), closes [#1969](https://github.com/karma-runner/karma/issues/1969) [#1988](https://github.com/karma-runner/karma/issues/1988) -* **reporter:** Disable source maps for URLs without line number ([2080221](https://github.com/karma-runner/karma/commit/2080221)), closes [#1274](https://github.com/karma-runner/karma/issues/1274) -* **reporter:** do not allow URL domains to span new lines ([2c13404](https://github.com/karma-runner/karma/commit/2c13404)) -* **reporter:** Enable sourcemaps for errors that without column # ([086a542](https://github.com/karma-runner/karma/commit/086a542)) -* **reporter:** Ensure errors use the source map. ([0407a22](https://github.com/karma-runner/karma/commit/0407a22)), closes [#1495](https://github.com/karma-runner/karma/issues/1495) -* **reporter:** Fix issue causing error stack not to be parsed correctly ([ac4e1a9](https://github.com/karma-runner/karma/commit/ac4e1a9)), closes [#2930](https://github.com/karma-runner/karma/issues/2930) -* **reporter:** inject correct config option ([80bd726](https://github.com/karma-runner/karma/commit/80bd726)) -* **reporter:** keep users exact formatError result ([17c2c43](https://github.com/karma-runner/karma/commit/17c2c43)) -* **reporter:** preserve base/absolute word in error ([b3798df](https://github.com/karma-runner/karma/commit/b3798df)) -* **reporter:** remove console.log ([b4e3694](https://github.com/karma-runner/karma/commit/b4e3694)) -* **reporter:** show file path correctly when urlRoot specified ([34dc7d3](https://github.com/karma-runner/karma/commit/34dc7d3)), closes [#2897](https://github.com/karma-runner/karma/issues/2897) -* **reporter:** sourcemap not working in windows ([a9516af](https://github.com/karma-runner/karma/commit/a9516af)), closes [#1200](https://github.com/karma-runner/karma/issues/1200) -* **reporter:** strip only hostname/port ([fbbeccf](https://github.com/karma-runner/karma/commit/fbbeccf)), closes [#2209](https://github.com/karma-runner/karma/issues/2209) -* **reporters:** cannot read property map of undefined ([305df2c](https://github.com/karma-runner/karma/commit/305df2c)), closes [#1662](https://github.com/karma-runner/karma/issues/1662) -* **reporters:** Fix results not being reported ([6303566](https://github.com/karma-runner/karma/commit/6303566)) -* **reporters:** Revert the backwards-incompatible log priority order changes ([316b944](https://github.com/karma-runner/karma/commit/316b944)), closes [#2582](https://github.com/karma-runner/karma/issues/2582) -* **reporters:** Throwing error without loosing stack trace ([8a515ae](https://github.com/karma-runner/karma/commit/8a515ae)) -* **runner:** Fix typo in CSS class name for .idle ([fc5a7ce](https://github.com/karma-runner/karma/commit/fc5a7ce)) -* **runner:** Make process kill timeout configurable ([ffaa054](https://github.com/karma-runner/karma/commit/ffaa054)), closes [#2447](https://github.com/karma-runner/karma/issues/2447) -* **runner:** Make process kill timeout configurable - Fix Build ([a128e5c](https://github.com/karma-runner/karma/commit/a128e5c)), closes [#2447](https://github.com/karma-runner/karma/issues/2447) -* **runner:** Merge config.client.args with client.args provided by run ([91de383](https://github.com/karma-runner/karma/commit/91de383)), closes [#1746](https://github.com/karma-runner/karma/issues/1746) -* **runner:** Remove null characters from terminal output ([3481500](https://github.com/karma-runner/karma/commit/3481500)), closes [#1343](https://github.com/karma-runner/karma/issues/1343) -* **runner:** Test process kill timeout config ([99a1d48](https://github.com/karma-runner/karma/commit/99a1d48)), closes [#2447](https://github.com/karma-runner/karma/issues/2447) -* **runner:** Wait for file list refresh to finish before running ([94cddc0](https://github.com/karma-runner/karma/commit/94cddc0)) -* **server:** check available port before start server (fix [#1476](https://github.com/karma-runner/karma/issues/1476), fix [#3011](https://github.com/karma-runner/karma/issues/3011)) ([a19b8d4](https://github.com/karma-runner/karma/commit/a19b8d4)) -* **server:** complete acknowledgment ([f4144b0](https://github.com/karma-runner/karma/commit/f4144b0)) -* **server:** exit with code 1 when failing due to missing browser ([86e2ef2](https://github.com/karma-runner/karma/commit/86e2ef2)), closes [#2403](https://github.com/karma-runner/karma/issues/2403) -* **server:** Force clients disconnect on Windows ([28239f4](https://github.com/karma-runner/karma/commit/28239f4)), closes [#1109](https://github.com/karma-runner/karma/issues/1109) -* **server:** Handle new socket.io internal format. ([3ab78d6](https://github.com/karma-runner/karma/commit/3ab78d6)), closes [#1782](https://github.com/karma-runner/karma/issues/1782) -* **server:** log browser messages to the terminal ([d1f924c](https://github.com/karma-runner/karma/commit/d1f924c)), closes [#2187](https://github.com/karma-runner/karma/issues/2187) -* **server:** Remove Socket.IO listeners ([c3f05ef](https://github.com/karma-runner/karma/commit/c3f05ef)), closes [#2980](https://github.com/karma-runner/karma/issues/2980) -* **server:** Start webserver and browsers after preprocessing completed ([e0d2d23](https://github.com/karma-runner/karma/commit/e0d2d23)) -* **server:** switch to sync write ([6ec74ee](https://github.com/karma-runner/karma/commit/6ec74ee)) -* **server:** Update timers for limited execution environments ([9cfc1cd](https://github.com/karma-runner/karma/commit/9cfc1cd)), closes [#1519](https://github.com/karma-runner/karma/issues/1519) -* **socket.io:** Force 0.9.16 which works with Chrome ([840ee5f](https://github.com/karma-runner/karma/commit/840ee5f)) -* **stringify:** guard Symobl from IE ([#3023](https://github.com/karma-runner/karma/issues/3023)) ([538081c](https://github.com/karma-runner/karma/commit/538081c)) -* invalid characters in the headers on Node 5.6.0 ([152337d](https://github.com/karma-runner/karma/commit/152337d)) -* **test:** locale in Expire header ([db04cf0](https://github.com/karma-runner/karma/commit/db04cf0)), closes [#1741](https://github.com/karma-runner/karma/issues/1741) -* **test:** update bundleResource test timeout ([#3038](https://github.com/karma-runner/karma/issues/3038)) ([d6060d4](https://github.com/karma-runner/karma/commit/d6060d4)) -* **travis_ci:** converted node versions as string ([25ee6fc](https://github.com/karma-runner/karma/commit/25ee6fc)) -* filter browser logging by level of LOG ([89a7a1c](https://github.com/karma-runner/karma/commit/89a7a1c)), closes [#2228](https://github.com/karma-runner/karma/issues/2228) -* **updater:** Fix time unit on screen display from 'ms' to 'seconds'. ([f39dd04](https://github.com/karma-runner/karma/commit/f39dd04)) -* a missed argument in a debug message ([#3009](https://github.com/karma-runner/karma/issues/3009)) ([af8c6e4](https://github.com/karma-runner/karma/commit/af8c6e4)) -* Add crossorigin attribute to script HTML tags ([5690ffe](https://github.com/karma-runner/karma/commit/5690ffe)) -* add emscripten memory image as binary suffix ([f6b2b56](https://github.com/karma-runner/karma/commit/f6b2b56)) -* call .resume to prevent browser output streams filling up ([107cd02](https://github.com/karma-runner/karma/commit/107cd02)) -* catch exceptions from SourceMapConsumer ([5d42e64](https://github.com/karma-runner/karma/commit/5d42e64)) -* Change timing on test ([0cb6204](https://github.com/karma-runner/karma/commit/0cb6204)) -* ignore jsVersion configuration property in Firefox 59+ ([2694d54](https://github.com/karma-runner/karma/commit/2694d54)), closes [#2957](https://github.com/karma-runner/karma/issues/2957) -* make window.parent.karma available in debugged context ([3e7eaeb](https://github.com/karma-runner/karma/commit/3e7eaeb)) -* Merge config child nodes on config.set() ([65b688a](https://github.com/karma-runner/karma/commit/65b688a)), closes [karma-runner/grunt-karma#165](https://github.com/karma-runner/grunt-karma/issues/165) [karma-runner/grunt-karma#166](https://github.com/karma-runner/grunt-karma/issues/166) -* Remove inadvertently added dependency to mock-fs ([ad5f6b5](https://github.com/karma-runner/karma/commit/ad5f6b5)) -* remove support of jsVersion configuration property ([#3002](https://github.com/karma-runner/karma/issues/3002)) ([2bb4e36](https://github.com/karma-runner/karma/commit/2bb4e36)), closes [#2911](https://github.com/karma-runner/karma/issues/2911) -* restore backward compatibility for karma@0.13 ([648b357](https://github.com/karma-runner/karma/commit/648b357)) -* Safeguard IE against console.log ([0b5ff8f](https://github.com/karma-runner/karma/commit/0b5ff8f)), closes [#1209](https://github.com/karma-runner/karma/issues/1209) -* Setting default value for config in runner and stopper ([414db89](https://github.com/karma-runner/karma/commit/414db89)) -* Switch all requires from fs to graceful-fs ([1e21aaa](https://github.com/karma-runner/karma/commit/1e21aaa)) -* upgrade http-proxy module for bug fixes ([09c75fe](https://github.com/karma-runner/karma/commit/09c75fe)) -* Upgrade socket.io to 1.4.5 ([2f51a9f](https://github.com/karma-runner/karma/commit/2f51a9f)) -* **UTs:** Correct proxy listeners expectation ([af9c84a](https://github.com/karma-runner/karma/commit/af9c84a)) -* **watcher:** Close file watchers on exit event ([7181025](https://github.com/karma-runner/karma/commit/7181025)) -* **watcher:** handle paths on Windows ([6164d86](https://github.com/karma-runner/karma/commit/6164d86)) -* **web-server:** Allow karma to run in project which path contains HTML URL encoded characters. Karma fails on Jenkins when it checks out branches containing '/' as it converts it to '%2F'. Fixes errors seen on [#1751](https://github.com/karma-runner/karma/issues/1751), [#61](https://github.com/karma-runner/karma/issues/61). ([da1930f](https://github.com/karma-runner/karma/commit/da1930f)) -* Wrap url.parse to always return an object for query property ([72452e9](https://github.com/karma-runner/karma/commit/72452e9)), closes [#1182](https://github.com/karma-runner/karma/issues/1182) -* **web-server:** cache static files ([eb5bd53](https://github.com/karma-runner/karma/commit/eb5bd53)) -* **web-server:** Correctly update filesPromise on files updated ([32eec8d](https://github.com/karma-runner/karma/commit/32eec8d)) -* **web-server:** Ensure `filesPromise` is always resolvable ([892fa89](https://github.com/karma-runner/karma/commit/892fa89)), closes [#1544](https://github.com/karma-runner/karma/issues/1544) -* **web-server:** Restart disconnected browser in non-singleRun mode. ([f6587dc](https://github.com/karma-runner/karma/commit/f6587dc)) -* **web-server:** Update config on every request ([8ef475f](https://github.com/karma-runner/karma/commit/8ef475f)), closes [#1972](https://github.com/karma-runner/karma/issues/1972) - - -### Code Refactoring - -* **context:** Future-proofed context.html and debug.html for modularity ([43f6a1a](https://github.com/karma-runner/karma/commit/43f6a1a)), closes [#1984](https://github.com/karma-runner/karma/issues/1984) - - -### Features - -* Add `stopper` to the public API ([3d4fa00](https://github.com/karma-runner/karma/commit/3d4fa00)) -* add an option to run the tests by dynamically loading test scripts without iframe ([aa42c41](https://github.com/karma-runner/karma/commit/aa42c41)) -* Add engine support for iojs@3. ([eb1c8d2](https://github.com/karma-runner/karma/commit/eb1c8d2)) -* Add possibility to stop a karma server ([66ae80b](https://github.com/karma-runner/karma/commit/66ae80b)) -* add support for node 6 ([0b8dc2c](https://github.com/karma-runner/karma/commit/0b8dc2c)) -* add support for node@7 ([eb407ab](https://github.com/karma-runner/karma/commit/eb407ab)), closes [#2559](https://github.com/karma-runner/karma/issues/2559) -* adding support for before middleware ([51b4206](https://github.com/karma-runner/karma/commit/51b4206)) -* Allow custom browser names ([60ba85f](https://github.com/karma-runner/karma/commit/60ba85f)) -* allow frameworks to add preprocessors ([f6f5eec](https://github.com/karma-runner/karma/commit/f6f5eec)) -* Allow frameworks to inject middleware ([d972f3d](https://github.com/karma-runner/karma/commit/d972f3d)) -* better string representation of errors ([c9e1ca9](https://github.com/karma-runner/karma/commit/c9e1ca9)) -* deprecate helper._ ([5c6b151](https://github.com/karma-runner/karma/commit/5c6b151)), closes [#1812](https://github.com/karma-runner/karma/issues/1812) -* Do not fail on empty test suite ([8004763](https://github.com/karma-runner/karma/commit/8004763)), closes [#926](https://github.com/karma-runner/karma/issues/926) -* drop core-js and babel where possible ([60dfc5c](https://github.com/karma-runner/karma/commit/60dfc5c)) -* Fail on launcher-, reporter-, plugin-, or preprocessor-load errors. ([fca930e](https://github.com/karma-runner/karma/commit/fca930e)), closes [#855](https://github.com/karma-runner/karma/issues/855) -* serve ePub as binary files ([82ed0c6](https://github.com/karma-runner/karma/commit/82ed0c6)) -* **api:** add constants to the public api ([ee10977](https://github.com/karma-runner/karma/commit/ee10977)), closes [#2361](https://github.com/karma-runner/karma/issues/2361) -* **api:** expose `config.parseConfig` on the public api ([7d2c1ae](https://github.com/karma-runner/karma/commit/7d2c1ae)) -* **browser:** add browser_info event ([09ac7d7](https://github.com/karma-runner/karma/commit/09ac7d7)), closes [#2192](https://github.com/karma-runner/karma/issues/2192) -* **browser:** Emit a browser error when a disconnect occurs. ([e36ba6c](https://github.com/karma-runner/karma/commit/e36ba6c)) -* **ci:** disable testing of node versions below 4 ([ec92ea9](https://github.com/karma-runner/karma/commit/ec92ea9)) -* **cli:** Add .config/karma.conf.js to the default lookup path ([49bf1aa](https://github.com/karma-runner/karma/commit/49bf1aa)), closes [#1387](https://github.com/karma-runner/karma/issues/1387) -* **cli:** Better CLI args validation ([73d31c2](https://github.com/karma-runner/karma/commit/73d31c2)), closes [#603](https://github.com/karma-runner/karma/issues/603) -* **cli:** Warn on commands with underscores. ([0801a7f](https://github.com/karma-runner/karma/commit/0801a7f)) -* **client:** capture confirm & prompt ([3a618b3](https://github.com/karma-runner/karma/commit/3a618b3)), closes [#694](https://github.com/karma-runner/karma/issues/694) -* **client:** log global error stack trace ([523d608](https://github.com/karma-runner/karma/commit/523d608)), closes [#2812](https://github.com/karma-runner/karma/issues/2812) -* **config:** Add `forceJSONP` option ([8627d67](https://github.com/karma-runner/karma/commit/8627d67)) -* **config:** Add a clearContext config to prevent clearing of context. ([5fc8ee7](https://github.com/karma-runner/karma/commit/5fc8ee7)) -* **config:** Add configuration for adding javascript version. ([0239c75](https://github.com/karma-runner/karma/commit/0239c75)), closes [#1719](https://github.com/karma-runner/karma/issues/1719) -* **config:** add nocache option for file patterns ([6ef7e7b](https://github.com/karma-runner/karma/commit/6ef7e7b)) -* **config:** add restartOnFileChange option ([1082f35](https://github.com/karma-runner/karma/commit/1082f35)) -* **config:** add support for TypeScript ([6445310](https://github.com/karma-runner/karma/commit/6445310)) -* **config:** allow config to be a default export ([9976dce](https://github.com/karma-runner/karma/commit/9976dce)) -* **config:** Allow custom context and debug files, with feature test and some specs. ([225c0e5](https://github.com/karma-runner/karma/commit/225c0e5)) -* **config:** allow to use newer versions of CoffeeScript ([c1fcf42](https://github.com/karma-runner/karma/commit/c1fcf42)) -* **config:** mime config option support ([d562383](https://github.com/karma-runner/karma/commit/d562383)), closes [#1735](https://github.com/karma-runner/karma/issues/1735) -* **config:** Pass CLI arguments to `karma.config.js`. ([70cf903](https://github.com/karma-runner/karma/commit/70cf903)), closes [#1561](https://github.com/karma-runner/karma/issues/1561) -* **config:** remove polling usage ([b0f41c7](https://github.com/karma-runner/karma/commit/b0f41c7)), closes [#2669](https://github.com/karma-runner/karma/issues/2669) -* **deps:** add support for node@8 ([ea32194](https://github.com/karma-runner/karma/commit/ea32194)), closes [#2754](https://github.com/karma-runner/karma/issues/2754) -* **deps:** add support for node@8 ([7feaee3](https://github.com/karma-runner/karma/commit/7feaee3)), closes [#2754](https://github.com/karma-runner/karma/issues/2754) -* **deps:** update socket.io to `1.7.4` to avoid issue with `ws@1.1.2` ([264442b](https://github.com/karma-runner/karma/commit/264442b)), closes [#2593](https://github.com/karma-runner/karma/issues/2593) -* **file-list:** Upgrade bluebird to v.3 ([f5c252f](https://github.com/karma-runner/karma/commit/f5c252f)) -* **file-list:** Use glob.sync for better speed ([1b65cde](https://github.com/karma-runner/karma/commit/1b65cde)) -* **grunt:** run check_clean before starting release. ([#2978](https://github.com/karma-runner/karma/issues/2978)) ([a3ff6c8](https://github.com/karma-runner/karma/commit/a3ff6c8)) -* **init:** install coffee-script automatically ([e876db6](https://github.com/karma-runner/karma/commit/e876db6)), closes [#1152](https://github.com/karma-runner/karma/issues/1152) -* **launcher:** Add concurrency limit ([1741deb](https://github.com/karma-runner/karma/commit/1741deb)), closes [#1465](https://github.com/karma-runner/karma/issues/1465) -* **launcher:** Enable specification of retry-limit ([cc5547c](https://github.com/karma-runner/karma/commit/cc5547c)), closes [#1126](https://github.com/karma-runner/karma/issues/1126) -* **launcher:** output stderr for failing launchers ([7d33398](https://github.com/karma-runner/karma/commit/7d33398)) -* **launcher:** trim whitespace in browser name ([334f9fb](https://github.com/karma-runner/karma/commit/334f9fb)) -* **launcher:** trim whitespace in browser name ([871d46f](https://github.com/karma-runner/karma/commit/871d46f)) -* **logger:** Add date/time stamp to log output ([4a59443](https://github.com/karma-runner/karma/commit/4a59443)) -* **logger:** Add date/time stamp to log output ([a4b5cdd](https://github.com/karma-runner/karma/commit/a4b5cdd)) -* **logging:** Add colors and log-level options to run-command ([9d4e234](https://github.com/karma-runner/karma/commit/9d4e234)), closes [#1067](https://github.com/karma-runner/karma/issues/1067) -* **logging:** Add colors and log-level options to run-command ([2d29165](https://github.com/karma-runner/karma/commit/2d29165)), closes [#1067](https://github.com/karma-runner/karma/issues/1067) -* **logging:** Add logging-setup function ([d14bd62](https://github.com/karma-runner/karma/commit/d14bd62)) -* **logging:** Send color option to server ([486c4f3](https://github.com/karma-runner/karma/commit/486c4f3)), closes [#1067](https://github.com/karma-runner/karma/issues/1067) -* **logging:** Send color option to server ([287d0db](https://github.com/karma-runner/karma/commit/287d0db)), closes [#1067](https://github.com/karma-runner/karma/issues/1067) -* **middleware:** added manual file type option ([0330cd1](https://github.com/karma-runner/karma/commit/0330cd1)), closes [#2824](https://github.com/karma-runner/karma/issues/2824) -* **preprocessor:** add 'mp3' and 'ogg' as binary formats to avoid media corruption in the browser. ([65a0767](https://github.com/karma-runner/karma/commit/65a0767)) -* **preprocessor:** Capital letters in binary files extenstions ([1688689](https://github.com/karma-runner/karma/commit/1688689)), closes [#1508](https://github.com/karma-runner/karma/issues/1508) -* **preprocessor:** Instantiate preprocessors early to avoid race conditions ([8a9c8c7](https://github.com/karma-runner/karma/commit/8a9c8c7)) -* **preprocessors:** if a file matches multiple preprocessor patterns, intelligently merge the list of preprocessors, deduping and trying to preserve the order ([59642a6](https://github.com/karma-runner/karma/commit/59642a6)) -* **proxy:** add proxy events to config ([f5d99fb](https://github.com/karma-runner/karma/commit/f5d99fb)) -* **proxy:** Allow proxies configuration to be an object ([ad94356](https://github.com/karma-runner/karma/commit/ad94356)) -* **proxy:** Allow to configure changeOrigin option of http-proxy ([ae05ea4](https://github.com/karma-runner/karma/commit/ae05ea4)), closes [#1729](https://github.com/karma-runner/karma/issues/1729) -* **reporter:** add config formatError function ([98a4fbf](https://github.com/karma-runner/karma/commit/98a4fbf)), closes [#2119](https://github.com/karma-runner/karma/issues/2119) -* **reporter:** cache SourceMapConsumer ([fe6ed7e](https://github.com/karma-runner/karma/commit/fe6ed7e)) -* **reporter:** improve source map handling and reporting. ([cf0be47](https://github.com/karma-runner/karma/commit/cf0be47)) -* **reporter:** Replace way-too-big memoizee with a trivial solution. ([58340b1](https://github.com/karma-runner/karma/commit/58340b1)) -* **reporter:** Replace way-too-big memoizee with a trivial solution. ([d926fe3](https://github.com/karma-runner/karma/commit/d926fe3)) -* **reporters:** Look for color-reporter ([fd9262d](https://github.com/karma-runner/karma/commit/fd9262d)) -* **runner:** Buffer stdout and stderr for output when errors occur ([460d423](https://github.com/karma-runner/karma/commit/460d423)), closes [karma-runner/karma#2663](https://github.com/karma-runner/karma/issues/2663) -* **runner:** provide error code on 'ECONNREFUSED' callback ([439bddb](https://github.com/karma-runner/karma/commit/439bddb)) -* **runner:** serve context in JSON format for JS-only environments ([189feff](https://github.com/karma-runner/karma/commit/189feff)) -* **runner:** Use favicon in static runner pages ([6cded4f](https://github.com/karma-runner/karma/commit/6cded4f)) -* **server:** add 'listening' event with port number ([82cd0df](https://github.com/karma-runner/karma/commit/82cd0df)) -* **server:** add listen address option so that IPv6 and loopback interfaces can be used ([8e5bee6](https://github.com/karma-runner/karma/commit/8e5bee6)), closes [#2477](https://github.com/karma-runner/karma/issues/2477) -* **server:** Add public api to force a file list refresh. ([b3c462a](https://github.com/karma-runner/karma/commit/b3c462a)) -* **server:** improve public api ([82cbbad](https://github.com/karma-runner/karma/commit/82cbbad)), closes [#1037](https://github.com/karma-runner/karma/issues/1037) [#1482](https://github.com/karma-runner/karma/issues/1482) [#1467](https://github.com/karma-runner/karma/issues/1467) -* **static:** Support media queries ([94e7b50](https://github.com/karma-runner/karma/commit/94e7b50)) -* **stopper:** Enable programically detached server ([f10fd81](https://github.com/karma-runner/karma/commit/f10fd81)) -* **watcher:** Allow using braces in watcher ([e046379](https://github.com/karma-runner/karma/commit/e046379)), closes [#1249](https://github.com/karma-runner/karma/issues/1249) -* **watcher:** Debounce autoWatchBatchDelay ([2f8c049](https://github.com/karma-runner/karma/commit/2f8c049)), closes [#2331](https://github.com/karma-runner/karma/issues/2331) -* **web-server:** add support for custom headers in files served ([4301bea](https://github.com/karma-runner/karma/commit/4301bea)) -* **web-server:** allow injection of custom middleware. ([2e963c3](https://github.com/karma-runner/karma/commit/2e963c3)), closes [#1612](https://github.com/karma-runner/karma/issues/1612) -* update of supported node versions ([e79463b](https://github.com/karma-runner/karma/commit/e79463b)) -* upgrade dependencies to their latest versions ([08242a0](https://github.com/karma-runner/karma/commit/08242a0)) -* **web-server:** allow overriding of default http module ([1e7514d](https://github.com/karma-runner/karma/commit/1e7514d)), closes [#2424](https://github.com/karma-runner/karma/issues/2424) -* **web-server:** Allow Range headers in web server. ([a567b6f](https://github.com/karma-runner/karma/commit/a567b6f)), closes [#2140](https://github.com/karma-runner/karma/issues/2140) -* **web-server:** Allow running on https ([1696c78](https://github.com/karma-runner/karma/commit/1696c78)) -* Upgrade to socket.io 1.3 ([603872c](https://github.com/karma-runner/karma/commit/603872c)), closes [#1257](https://github.com/karma-runner/karma/issues/1257) [#1258](https://github.com/karma-runner/karma/issues/1258) [#1220](https://github.com/karma-runner/karma/issues/1220) -* upstreamProxy config option to deal with proxies that adjust the base path, etc ([55755e4](https://github.com/karma-runner/karma/commit/55755e4)) -* **web-server:** Serve all files under urlRoot ([1319b32](https://github.com/karma-runner/karma/commit/1319b32)) -* **web-server:** Use isbinaryfile for binary file detection ([f938a8e](https://github.com/karma-runner/karma/commit/f938a8e)), closes [#1070](https://github.com/karma-runner/karma/issues/1070) - - -### Reverts - -* "Merge pull request [#1791](https://github.com/karma-runner/karma/issues/1791) from budde377/feature-adding-no-colors-to-run-command" ([96ebdc4](https://github.com/karma-runner/karma/commit/96ebdc4)), closes [#1894](https://github.com/karma-runner/karma/issues/1894) [#1895](https://github.com/karma-runner/karma/issues/1895) - - -### BREAKING CHANGES - -* **context:** Our `context.html` and `debug.html` structures have changed to lean on `context.js` and `debug.js`. -* **server:** The public api interface has changed to a constructor form. To upgrade -change - -```javascript -var server = require(‘karma’).server -server.start(config, done) -``` - -to - -```javascript -var Server = require(‘karma’).Server -var server = new Server(config, done) -server.start() -``` +## [2.0.3](https://github.com/karma-runner/karma/compare/v2.0.2...v2.0.3) (2018-06-15) +The 2.03. change log was incorrectly created due to an extra pending tag in the repo. ## [2.0.2](https://github.com/karma-runner/karma/compare/v2.0.1...v2.0.2) (2018-04-19) From 732396a087c6dddeea2cf7f7493bf148a508725d Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 7 Aug 2018 15:36:38 -0700 Subject: [PATCH 023/374] fix(travis): Up the socket timeout 2->20s. (#3103) Log something on all disconnect() calls. Up the timeout as suggested by ndcornelius@ on #3102 --- client/main.js | 2 +- lib/browser.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/main.js b/client/main.js index 8f3cfee63..e59095d7b 100644 --- a/client/main.js +++ b/client/main.js @@ -14,7 +14,7 @@ var KARMA_PROXY_PATH = constants.KARMA_PROXY_PATH var socket = io(location.host, { reconnectionDelay: 500, reconnectionDelayMax: Infinity, - timeout: 2000, + timeout: 20000, path: KARMA_PROXY_PATH + KARMA_URL_ROOT.substr(1) + 'socket.io', 'sync disconnect on unload': true }) diff --git a/lib/browser.js b/lib/browser.js index 1ff636555..6abad4b64 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -151,7 +151,7 @@ class Browser { } if (this.state === CONNECTED) { - this.disconnect() + this.disconnect('client disconnected from CONNECTED state') } else if (this.state === CONFIGURING || this.state === EXECUTING) { this.log.debug('Disconnected during run, waiting %sms for reconnecting.', this.disconnectDelay) this.state = EXECUTING_DISCONNECTED @@ -159,7 +159,7 @@ class Browser { this.pendingDisconnect = this.timer.setTimeout(() => { this.lastResult.totalTimeEnd() this.lastResult.disconnected = true - this.disconnect() + this.disconnect(`reconnect failed before timeout of ${this.disconnectDelay}ms`) this.emitter.emit('browser_complete', this) }, this.disconnectDelay) From eb3b1b4ce8e0545832676289deb6e48bde5465fd Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 9 Aug 2018 11:03:01 -0700 Subject: [PATCH 024/374] chore(deps): update mime -> 2.3.1 (#3107) This is the same as @dignifiedrequire #2997 first commit --- lib/middleware/common.js | 6 +++--- package.json | 2 +- test/unit/web-server.spec.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/middleware/common.js b/lib/middleware/common.js index 2a001dd35..368abc830 100644 --- a/lib/middleware/common.js +++ b/lib/middleware/common.js @@ -88,7 +88,7 @@ function createServeFile (fs, directory, config) { // serve from cache if (content && !doNotCache) { - response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain')) + response.setHeader('Content-Type', mime.getType(filepath, 'text/plain')) // call custom transform fn to transform the data responseData = (transform && transform(content)) || content @@ -108,7 +108,7 @@ function createServeFile (fs, directory, config) { cache[filepath] = data.toString() } - response.setHeader('Content-Type', mime.lookup(filepath, 'text/plain')) + response.setHeader('Content-Type', mime.getType(filepath, 'text/plain')) // call custom transform fn to transform the data responseData = (transform && transform(data.toString())) || data @@ -136,7 +136,7 @@ function initializeMimeTypes (config) { _.forEach(config.mime, function (value, key) { const map = {} map[key] = value - mime.define(map) + mime.define(map, true) }) } } diff --git a/package.json b/package.json index f64a05bdc..973bd4edd 100644 --- a/package.json +++ b/package.json @@ -374,7 +374,7 @@ "isbinaryfile": "^3.0.0", "lodash": "^4.17.4", "log4js": "^3.0.0", - "mime": "^1.3.4", + "mime": "^2.3.1", "minimatch": "^3.0.2", "optimist": "^0.6.1", "qjobs": "^1.1.4", diff --git a/test/unit/web-server.spec.js b/test/unit/web-server.spec.js index 6d56cb04c..e7ceadc60 100644 --- a/test/unit/web-server.spec.js +++ b/test/unit/web-server.spec.js @@ -90,11 +90,11 @@ describe('web-server', () => { }) it('should setup mime', () => { - expect(mime.lookup('/my.custom')).to.equal('custom/custom') + expect(mime.getType('/my.custom')).to.equal('custom/custom') }) it('should keep default mimes', () => { - expect(mime.lookup('/my.html')).to.equal('text/html') + expect(mime.getType('/my.html')).to.equal('text/html') }) it('should serve client.html', () => { From 5db939907cabae3d0ef77ec08ae04563177116c2 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 9 Aug 2018 13:14:07 -0700 Subject: [PATCH 025/374] chore: update contributors --- package.json | 117 ++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index 973bd4edd..dcc3deeb6 100644 --- a/package.json +++ b/package.json @@ -26,102 +26,102 @@ "Friedel Ziegelmayer ", "dignifiedquire ", "greenkeeperio-bot ", + "johnjbarton ", "Karma Bot ", "Maksim Ryzhikov ", - "johnjbarton ", "Christian Budde Christensen ", - "ukasz Usarz ", "Yaroslav Admin ", - "taichi ", + "ukasz Usarz ", "Wesley Cho ", + "taichi ", "Liam Newman ", "Todd Wolfson ", "Michał Gołębiowski-Owczarek ", "Mark Trostler ", "lukasz ", "Ciro Nunes ", - "Robo ", "Tim Cuthbertson ", - "Pawel Kozlowski ", - "Christian Budde Christensen ", "Shyam Seshadri ", - "Mourad ", + "Christian Budde Christensen ", + "Robo ", + "Pawel Kozlowski ", "Mark Ethan Trostler ", "Daniel Compton ", - "vivganes ", + "Mourad ", + "Brian Di Palma ", "Kim Joar Bekkelund ", + "vivganes ", "joshjb84 ", - "Brian Di Palma ", "Nick Malaguti ", - "Daniel Aleksandersen ", - "pavelgj ", - "sylvain-hamel ", + "Jeff Jewiss ", "David Souther ", - "Iristyle ", - "Ilya Volodin ", - "Chris Hunt ", - "ywong ", + "Andrew Martin ", + "Georgii Dolzhykov ", "Jérémy Judéaux ", "Brian Ford ", - "Pieter Mees ", - "Jake Champion ", - "Jeff Jewiss ", "Chris Casola ", + "Ilya Volodin ", + "Iristyle ", + "Daniel Aleksandersen ", "Aymeric Beaumet ", - "Georgii Dolzhykov ", + "Jake Champion ", + "Pieter Mees ", "Marcello Nuccio ", - "Andrew Martin ", - "Ruben Bridgewater ", - "Réda Housni Alaoui ", - "Ethan J. Brown ", - "Ezra Brooks ", - "Sammy Jelin ", - "Matt Lewis ", - "Filipe Guerra ", - "David Pärsson ", - "Bulat Shakirzyanov ", - "Jonas Pommerening ", - "Shane Russell ", - "Jonathan Freeman ", - "Josh ", - "Stefan Dragnev ", - "Steve Mao ", - "Steve Mao ", - "Steve Van Opstal ", - "Sylvain Hamel ", - "Greenkeeper ", - "Andrew Morris ", - "KJ Tsanaktsidis ", - "Thomas Parisot ", - "Aseem Bansal ", - "ChangZhuo Chen (陳昌倬) ", - "Tom Erik Støwer ", - "Hugues Malphettes ", - "Igor Minar ", - "Igor Minar ", - "Kelly Jensen ", - "Vivek Ganesan ", + "Chris Hunt ", + "pavelgj ", + "sylvain-hamel ", + "ywong ", "Vladimir Starkov ", + "Réda Housni Alaoui ", "Kevin Huang ", + "Andrew Morris ", + "rdodev ", "Parashuram ", - "Pat Tullmann ", + "Greenkeeper ", "Kevin WENNER ", + "Pat Tullmann ", + "Sylvain Hamel ", + "Ethan J. Brown ", "PatrickJS ", + "Steve Van Opstal ", + "Steve Mao ", "Levi Thomason ", "comdiv ", + "Steve Mao ", + "Sammy Jelin ", + "Robin Liang ", "Bryan Smith ", "Luke Page ", + "Stefan Dragnev ", "James Ford ", + "Josh ", "DarthCharles ", + "Matt Lewis ", + "Jonathan Freeman ", "James Talmage ", - "Richard Harrington ", + "Ruben Bridgewater ", + "Shane Russell ", + "Jonas Pommerening ", "karmarunnerbot ", + "Richard Harrington ", + "Bulat Shakirzyanov ", + "David Pärsson ", + "Filipe Guerra ", "Roarke Gaskill ", "David Herges ", + "Aseem Bansal ", + "ChangZhuo Chen (陳昌倬) ", + "Thomas Parisot ", + "Tom Erik Støwer ", + "KJ Tsanaktsidis ", "ngiebel ", - "Robin Liang ", - "rdodev ", - "Karol Fabjańczuk ", + "Hugues Malphettes ", + "Ezra Brooks ", + "Igor Minar ", + "Igor Minar ", + "Kelly Jensen ", + "Vivek Ganesan ", + "Terry ", "Karolis Narkevicius ", "Keats ", "Keen Yee Liau ", @@ -162,6 +162,7 @@ "Nico Jansen ", "Nicolas Artman ", "Nicolas Ferrero ", + "Nir Moav ", "Nish ", "Nuno Job ", "Oleg Gomozov ", @@ -212,7 +213,6 @@ "Taylor Buley ", "Taylor Hakes ", "Terin Stock ", - "Terry ", "Thai Pangsakulyanont @ Taskworld ", "Thomas Parisot ", "Tim Olshansky ", @@ -355,7 +355,8 @@ "Jurko Gospodnetić ", "Justin Ridgewell ", "KahWee Teng ", - "Karl Lindmark " + "Karl Lindmark ", + "Karol Fabjańczuk " ], "dependencies": { "bluebird": "^3.3.0", From 75f466dc172223cd8aa6fd7eec9bee810c982341 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 9 Aug 2018 13:14:13 -0700 Subject: [PATCH 026/374] chore: release v2.0.6 --- CHANGELOG.md | 17 +++++++++++++++++ package.json | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42787d997..1d15a9e48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ + +## [2.0.6](https://github.com/karma-runner/karma/compare/v2.0.5...v2.0.6) (2018-08-09) + + +### Bug Fixes + +* **config:** wait 20s for browser activity. ([#3087](https://github.com/karma-runner/karma/issues/3087)) ([88b977f](https://github.com/karma-runner/karma/commit/88b977f)) +* **config:** Wait 30s for browser activity per Travis. ([#3091](https://github.com/karma-runner/karma/issues/3091)) ([f6d2f0e](https://github.com/karma-runner/karma/commit/f6d2f0e)) +* **init:** add "ChromeHeadless" to the browsers' options ([#3096](https://github.com/karma-runner/karma/issues/3096)) ([56fda53](https://github.com/karma-runner/karma/commit/56fda53)) +* **server:** Exit clean on unhandledRejections. ([#3092](https://github.com/karma-runner/karma/issues/3092)) ([02f54c6](https://github.com/karma-runner/karma/commit/02f54c6)), closes [#3064](https://github.com/karma-runner/karma/issues/3064) +* **travis:** Up the socket timeout 2->20s. ([#3103](https://github.com/karma-runner/karma/issues/3103)) ([732396a](https://github.com/karma-runner/karma/commit/732396a)), closes [#3102](https://github.com/karma-runner/karma/issues/3102) +* **travis:** use the value not the key name. ([#3097](https://github.com/karma-runner/karma/issues/3097)) ([90f5546](https://github.com/karma-runner/karma/commit/90f5546)) +* **travis:** validate TRAVIS_COMMIT if TRAVIS_PULL_REQUEST_SHA is not set. ([#3094](https://github.com/karma-runner/karma/issues/3094)) ([fba5d36](https://github.com/karma-runner/karma/commit/fba5d36)) +* **travis:** Validate TRAVIS_PULL_REQUEST_SHA rather than TRAVIS_COMMIT. ([#3093](https://github.com/karma-runner/karma/issues/3093)) ([a58fa45](https://github.com/karma-runner/karma/commit/a58fa45)) + + + ## [2.0.5](https://github.com/karma-runner/karma/compare/v2.0.4...v2.0.5) (2018-07-24) diff --git a/package.json b/package.json index dcc3deeb6..69b859f4c 100644 --- a/package.json +++ b/package.json @@ -462,7 +462,7 @@ "engines": { "node": ">= 6" }, - "version": "2.0.5", + "version": "2.0.6", "license": "MIT", "scripts": { "lint": "eslint . --ext js --ignore-pattern *.tpl.js", From a4d5bdcbe36cbe12974fa9936a224a7837c5f0a4 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 9 Aug 2018 13:21:23 -0700 Subject: [PATCH 027/374] chore: release v3.0.0 --- CHANGELOG.md | 17 +++++++++++++++++ package.json | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d15a9e48..b8f8814b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ + +# [3.0.0](https://github.com/karma-runner/karma/compare/v2.0.5...v3.0.0) (2018-08-09) + + +### Bug Fixes + +* **config:** wait 20s for browser activity. ([#3087](https://github.com/karma-runner/karma/issues/3087)) ([88b977f](https://github.com/karma-runner/karma/commit/88b977f)) +* **config:** Wait 30s for browser activity per Travis. ([#3091](https://github.com/karma-runner/karma/issues/3091)) ([f6d2f0e](https://github.com/karma-runner/karma/commit/f6d2f0e)) +* **init:** add "ChromeHeadless" to the browsers' options ([#3096](https://github.com/karma-runner/karma/issues/3096)) ([56fda53](https://github.com/karma-runner/karma/commit/56fda53)) +* **server:** Exit clean on unhandledRejections. ([#3092](https://github.com/karma-runner/karma/issues/3092)) ([02f54c6](https://github.com/karma-runner/karma/commit/02f54c6)), closes [#3064](https://github.com/karma-runner/karma/issues/3064) +* **travis:** Up the socket timeout 2->20s. ([#3103](https://github.com/karma-runner/karma/issues/3103)) ([732396a](https://github.com/karma-runner/karma/commit/732396a)), closes [#3102](https://github.com/karma-runner/karma/issues/3102) +* **travis:** use the value not the key name. ([#3097](https://github.com/karma-runner/karma/issues/3097)) ([90f5546](https://github.com/karma-runner/karma/commit/90f5546)) +* **travis:** validate TRAVIS_COMMIT if TRAVIS_PULL_REQUEST_SHA is not set. ([#3094](https://github.com/karma-runner/karma/issues/3094)) ([fba5d36](https://github.com/karma-runner/karma/commit/fba5d36)) +* **travis:** Validate TRAVIS_PULL_REQUEST_SHA rather than TRAVIS_COMMIT. ([#3093](https://github.com/karma-runner/karma/issues/3093)) ([a58fa45](https://github.com/karma-runner/karma/commit/a58fa45)) + + + ## [2.0.6](https://github.com/karma-runner/karma/compare/v2.0.5...v2.0.6) (2018-08-09) diff --git a/package.json b/package.json index 69b859f4c..64fe2363a 100644 --- a/package.json +++ b/package.json @@ -462,7 +462,7 @@ "engines": { "node": ">= 6" }, - "version": "2.0.6", + "version": "3.0.0", "license": "MIT", "scripts": { "lint": "eslint . --ext js --ignore-pattern *.tpl.js", From 33ed285c8d9279abac3deb1281b15feab8d4e34c Mon Sep 17 00:00:00 2001 From: Sibiraj <20282546+Sibiraj-S@users.noreply.github.com> Date: Fri, 10 Aug 2018 20:36:29 +0530 Subject: [PATCH 028/374] docs(readme): update BREAKING CHANGES in CHANGELOG (#3109) --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8f8814b4..34fb6580a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ * **travis:** validate TRAVIS_COMMIT if TRAVIS_PULL_REQUEST_SHA is not set. ([#3094](https://github.com/karma-runner/karma/issues/3094)) ([fba5d36](https://github.com/karma-runner/karma/commit/fba5d36)) * **travis:** Validate TRAVIS_PULL_REQUEST_SHA rather than TRAVIS_COMMIT. ([#3093](https://github.com/karma-runner/karma/issues/3093)) ([a58fa45](https://github.com/karma-runner/karma/commit/a58fa45)) +### BREAKING CHANGES + +* Drop Support for Nodejs4 ([#3082](https://github.com/karma-runner/karma/pull/3082)) + From 11e3a9d9299544a8c371316073a7a8b8a41db246 Mon Sep 17 00:00:00 2001 From: Nathan Cornelius Date: Mon, 13 Aug 2018 10:14:15 -0500 Subject: [PATCH 029/374] feat(config): Add config option for browser socket timeout (#3102) Add a configuration option that allows modification of the default timeout value for the client socket connection. The previous hardcoded value of 2000 (ms) was insufficent for some environments. Closes #2927 --- client/constants.js | 1 + client/main.js | 3 ++- docs/config/01-configuration-file.md | 23 +++++++++++++++++++++++ lib/config.js | 5 +++++ lib/middleware/karma.js | 7 +++++-- 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/client/constants.js b/client/constants.js index 0e8745395..b003fb72a 100644 --- a/client/constants.js +++ b/client/constants.js @@ -2,5 +2,6 @@ module.exports = { VERSION: '%KARMA_VERSION%', KARMA_URL_ROOT: '%KARMA_URL_ROOT%', KARMA_PROXY_PATH: '%KARMA_PROXY_PATH%', + BROWSER_SOCKET_TIMEOUT: '%BROWSER_SOCKET_TIMEOUT%', CONTEXT_URL: 'context.html' } diff --git a/client/main.js b/client/main.js index e59095d7b..6110db32e 100644 --- a/client/main.js +++ b/client/main.js @@ -9,12 +9,13 @@ var constants = require('./constants') var KARMA_URL_ROOT = constants.KARMA_URL_ROOT var KARMA_PROXY_PATH = constants.KARMA_PROXY_PATH +var BROWSER_SOCKET_TIMEOUT = constants.BROWSER_SOCKET_TIMEOUT // Connect to the server using socket.io http://socket.io var socket = io(location.host, { reconnectionDelay: 500, reconnectionDelayMax: Infinity, - timeout: 20000, + timeout: BROWSER_SOCKET_TIMEOUT, path: KARMA_PROXY_PATH + KARMA_URL_ROOT.substr(1) + 'socket.io', 'sync disconnect on unload': true }) diff --git a/docs/config/01-configuration-file.md b/docs/config/01-configuration-file.md index 8bc689cc2..e16b70080 100644 --- a/docs/config/01-configuration-file.md +++ b/docs/config/01-configuration-file.md @@ -793,6 +793,29 @@ If set then the following fields will be defined and can be overriden: All of Karma's urls get prefixed with the `urlRoot`. This is helpful when using proxies, as sometimes you might want to proxy a url that is already taken by Karma. +## browserSocketTimeout +**Type:** Number + +**Default:** `20000` + +**Description:** Timeout for the client socket connection (in ms). + +This configuration represents the amount of time that the client will wait for the socket +to connect. + +When running a browser in different environments, it can take different amounts of time for the +client socket to connect. If Karma cannot connect within the default timeout, you may see an +error similar to the following: +``` +ChromeHeadless have not captured in 60000ms, killing. +Trying to start ChromeHeadless again (1/2). +ChromeHeadless have not captured in 60000ms, killing. +Trying to start ChromeHeadless again (2/2). +ChromeHeadless have not captured in 60000ms, killing. +ChromeHeadless failed 2 times(timeout). Giving up. +``` +If you see this error, you can try increasing the socket connection timeout. + [plugins]: plugins.html [config/files]: files.html diff --git a/lib/config.js b/lib/config.js index 1d0369cbc..91ef8c76c 100644 --- a/lib/config.js +++ b/lib/config.js @@ -229,6 +229,10 @@ function normalizeConfig (config, configFilePath) { throw new TypeError('Invalid configuration: processKillTimeout option must be a number.') } + if (config.browserSocketTimeout && !helper.isNumber(config.browserSocketTimeout)) { + throw new TypeError('Invalid configuration: browserSocketTimeout option must be a number.') + } + const defaultClient = config.defaultClient || {} Object.keys(defaultClient).forEach(function (key) { const option = config.client[key] @@ -350,6 +354,7 @@ class Config { this.retryLimit = 2 this.detached = false this.crossOriginAttribute = true + this.browserSocketTimeout = 20000 } set (newConfig) { diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 211b53424..6ef06ef63 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -78,7 +78,8 @@ function createKarmaMiddleware ( injector, basePath, urlRoot, - upstreamProxy + upstreamProxy, + browserSocketTimeout ) { var proxyPath = upstreamProxy ? upstreamProxy.path : '/' return function (request, response, next) { @@ -129,6 +130,7 @@ function createKarmaMiddleware ( return data.replace('%KARMA_URL_ROOT%', urlRoot) .replace('%KARMA_VERSION%', VERSION) .replace('%KARMA_PROXY_PATH%', proxyPath) + .replace('%BROWSER_SOCKET_TIMEOUT%', browserSocketTimeout) }) } @@ -260,7 +262,8 @@ createKarmaMiddleware.$inject = [ 'injector', 'config.basePath', 'config.urlRoot', - 'config.upstreamProxy' + 'config.upstreamProxy', + 'config.browserSocketTimeout' ] // PUBLIC API From eeadcf299d990c3569252b5c15a1088d3846e99d Mon Sep 17 00:00:00 2001 From: Sho Ikeda Date: Tue, 14 Aug 2018 00:17:12 +0900 Subject: [PATCH 030/374] fix(init): Support ChromeHeadless in `validateBrowser` (#3110) --- lib/init.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/init.js b/lib/init.js index 9edafb715..f744ec808 100755 --- a/lib/init.js +++ b/lib/init.js @@ -69,7 +69,7 @@ function validatePattern (pattern) { function validateBrowser (name) { // TODO(vojta): check if the path resolves to a binary - installPackage('karma-' + name.toLowerCase().replace('canary', '') + '-launcher') + installPackage('karma-' + name.toLowerCase().replace('headless', '').replace('canary', '') + '-launcher') } function validateFramework (name) { From 74da748908bde520a53c3cbc22dd891d7f2d170a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20P=C3=A5lsson?= Date: Thu, 30 Aug 2018 18:25:42 +0200 Subject: [PATCH 031/374] fix(runner): Make exit code configurable when tests are failing (#3116) Fixes #1300 --- lib/browser_collection.js | 21 ++++++- lib/cli.js | 6 ++ lib/server.js | 9 +-- test/unit/browser_collection.spec.js | 86 ++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 10 deletions(-) diff --git a/lib/browser_collection.js b/lib/browser_collection.js index 0c624d762..d3fff4d8c 100644 --- a/lib/browser_collection.js +++ b/lib/browser_collection.js @@ -46,7 +46,24 @@ class BrowserCollection { return this.browsers.map((browser) => browser.serialize()) } - getResults () { + calculateExitCode (results, singleRunBrowserNotCaptured, failOnEmptyTestSuite, failOnFailingTestSuite) { + if (results.disconnected || singleRunBrowserNotCaptured) { + return 1 + } + if (results.success + results.failed === 0 && !failOnEmptyTestSuite) { + return 0 + } + if (results.error) { + return 1 + } + if (failOnFailingTestSuite === false) { + // Tests executed without infrastructure error, exit with 0 independent of test status. + return 0 + } + return results.failed ? 1 : 0 + } + + getResults (singleRunBrowserNotCaptured, failOnEmptyTestSuite, failOnFailingTestSuite) { const results = this.browsers.reduce((previous, current) => { previous.success += current.lastResult.success previous.failed += current.lastResult.failed @@ -56,7 +73,7 @@ class BrowserCollection { }, {success: 0, failed: 0, error: false, disconnected: false, exitCode: 0}) // compute exit status code - results.exitCode = results.failed || results.error || results.disconnected ? 1 : 0 + results.exitCode = this.calculateExitCode(results, singleRunBrowserNotCaptured, failOnEmptyTestSuite, failOnFailingTestSuite) return results } diff --git a/lib/cli.js b/lib/cli.js index 1d71df41a..0d70273b8 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -46,6 +46,10 @@ function processArgs (argv, options, fs, path) { options.failOnEmptyTestSuite = options.failOnEmptyTestSuite === 'true' } + if (helper.isString(options.failOnFailingTestSuite)) { + options.failOnFailingTestSuite = options.failOnFailingTestSuite === 'true' + } + if (helper.isString(options.formatError)) { let required try { @@ -196,6 +200,8 @@ function describeStart () { .describe('report-slower-than', ' Report tests that are slower than given time [ms].') .describe('fail-on-empty-test-suite', 'Fail on empty test suite.') .describe('no-fail-on-empty-test-suite', 'Do not fail on empty test suite.') + .describe('fail-on-failing-test-suite', 'Fail on failing test suite.') + .describe('no-fail-on-failing-test-suite', 'Do not fail on failing test suite.') .describe('help', 'Print usage and options.') } diff --git a/lib/server.js b/lib/server.js index 043c8a29c..045c4fee0 100644 --- a/lib/server.js +++ b/lib/server.js @@ -247,14 +247,7 @@ class Server extends KarmaEventEmitter { const emitRunCompleteIfAllBrowsersDone = () => { if (Object.keys(singleRunDoneBrowsers).every((key) => singleRunDoneBrowsers[key])) { - const results = singleRunBrowsers.getResults() - if (singleRunBrowserNotCaptured) { - results.exitCode = 1 - } else if (results.success + results.failed === 0 && !config.failOnEmptyTestSuite) { - results.exitCode = 0 - this.log.warn('Test suite was empty.') - } - this.emit('run_complete', singleRunBrowsers, results) + this.emit('run_complete', singleRunBrowsers, singleRunBrowsers.getResults(singleRunBrowserNotCaptured, config.failOnEmptyTestSuite, config.failOnFailingTestSuite)) } } diff --git a/test/unit/browser_collection.spec.js b/test/unit/browser_collection.spec.js index 417d2ad79..d883cb701 100644 --- a/test/unit/browser_collection.spec.js +++ b/test/unit/browser_collection.spec.js @@ -258,4 +258,90 @@ describe('BrowserCollection', () => { }) }) }) + + // ============================================================================ + // server.calculateExitCode + // ============================================================================ + describe('calculateExitCode', () => { + const EXIT_CODE_ERROR = 1 + const EXIT_CODE_SUCCESS = 0 + + describe('no tests', () => { + const results = { + success: 0, + failed: 0, + error: true + } + it('shall pass if failOnEmptyTestSuite not is set', () => { + const res = collection.calculateExitCode(results) + expect(res).to.be.equal(EXIT_CODE_SUCCESS) + }) + it('shall pass if failOnEmptyTestSuite is false', () => { + const res = collection.calculateExitCode(results, false, false) + expect(res).to.be.equal(EXIT_CODE_SUCCESS) + }) + it('shall fail if failOnEmptyTestSuite is true', () => { + const res = collection.calculateExitCode(results, false, true) + expect(res).to.be.equal(EXIT_CODE_ERROR) + }) + it('shall fail if failOnFailingTestSuite is set', () => { + const res = collection.calculateExitCode(results, false, true, true) + expect(res).to.be.equal(EXIT_CODE_ERROR) + }) + }) + describe('all test passed, no errors', () => { + const results = { + success: 10, + failed: 0, + error: false + } + it('shall fail if singleRunBrowserNotCaptured is true', () => { + const res = collection.calculateExitCode(results, true) + expect(res).to.be.equal(EXIT_CODE_ERROR) + }) + it('shall pass if failOnEmptyTestSuite not is set', () => { + const res = collection.calculateExitCode(results, false) + expect(res).to.be.equal(EXIT_CODE_SUCCESS) + }) + it('shall pass if failOnEmptyTestSuite not is set', () => { + const res = collection.calculateExitCode(results, false, false) + expect(res).to.be.equal(EXIT_CODE_SUCCESS) + }) + it('shall pass if failOnFailingTestSuite is true', () => { + const res = collection.calculateExitCode(results, false, true, true) + expect(res).to.be.equal(EXIT_CODE_SUCCESS) + }) + it('shall pass if failOnFailingTestSuite is false', () => { + const res = collection.calculateExitCode(results, false, true, false) + expect(res).to.be.equal(EXIT_CODE_SUCCESS) + }) + }) + describe('all test passed, with error', () => { + const results = { + success: 10, + failed: 5, + error: false + } + it('shall fail if singleRunBrowserNotCaptured is true', () => { + const res = collection.calculateExitCode(results, true) + expect(res).to.be.equal(EXIT_CODE_ERROR) + }) + it('shall fail if failOnEmptyTestSuite not is set', () => { + const res = collection.calculateExitCode(results, false) + expect(res).to.be.equal(EXIT_CODE_ERROR) + }) + it('shall fail if failOnEmptyTestSuite not is set', () => { + const res = collection.calculateExitCode(results, false, false) + expect(res).to.be.equal(EXIT_CODE_ERROR) + }) + it('shall fail if failOnFailingTestSuite is true', () => { + const res = collection.calculateExitCode(results, false, true, true) + expect(res).to.be.equal(EXIT_CODE_ERROR) + }) + it('shall pass if failOnFailingTestSuite is false', () => { + const res = collection.calculateExitCode(results, false, true, false) + expect(res).to.be.equal(EXIT_CODE_SUCCESS) + }) + }) + }) }) From 8257375a85fda791a0fa8b26a89770c613ce87bd Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 5 Sep 2018 09:00:16 -0700 Subject: [PATCH 032/374] feat(frameworks): report start() errors back to server. (#3126) --- context/karma.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/context/karma.js b/context/karma.js index 2403ee898..4ce54cb52 100644 --- a/context/karma.js +++ b/context/karma.js @@ -37,7 +37,11 @@ function ContextKarma (callParentKarmaMethod) { this.loaded = function () { // has error -> cancel if (!hasError) { - this.start(this.config) + try { + this.start(this.config) + } catch (error) { + this.error(error.stack || error.toString()) + } } // remove reference to child iframe From 301b2d6cbe90f7481d6cf8522d32ea71134b23f8 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 5 Sep 2018 09:20:16 -0700 Subject: [PATCH 033/374] Create pull request template. --- PULL_REQUEST_TEMPLATE.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 PULL_REQUEST_TEMPLATE.md diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..648a3822d --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,3 @@ +Check that your description matches the automatic change-log format: +http://karma-runner.github.io/2.0/dev/git-commit-msg.html +then delete this reminder. From c91cb81e496c2e8c758304d77e7c3b7a7c29f073 Mon Sep 17 00:00:00 2001 From: jvalkeejarvi Date: Wed, 5 Sep 2018 19:27:14 +0300 Subject: [PATCH 034/374] fix(runner): Do not persist grep option across runs (#3121) --- lib/helper.js | 12 + lib/middleware/runner.js | 2 + test/unit/helper.spec.js | 28 ++ test/unit/middleware/runner.spec.js | 480 ++++++++++++++-------------- 4 files changed, 287 insertions(+), 235 deletions(-) diff --git a/lib/helper.js b/lib/helper.js index cdf051f01..aaa00b6f5 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -169,3 +169,15 @@ exports.defer = () => { promise: promise } } + +exports.saveOriginalArgs = (config) => { + if (config && config.client && config.client.args) { + config.client.originalArgs = _.cloneDeep(config.client.args) + } +} + +exports.restoreOriginalArgs = (config) => { + if (config && config.client && config.client.originalArgs) { + config.client.args = _.cloneDeep(config.client.originalArgs) + } +} diff --git a/lib/middleware/runner.js b/lib/middleware/runner.js index a90cf5a73..a78134dbf 100644 --- a/lib/middleware/runner.js +++ b/lib/middleware/runner.js @@ -15,6 +15,7 @@ var json = require('body-parser').json() function createRunnerMiddleware (emitter, fileList, capturedBrowsers, reporter, executor, /* config.protocol */ protocol, /* config.hostname */ hostname, /* config.port */ port, /* config.urlRoot */ urlRoot, config) { + helper.saveOriginalArgs(config) return function (request, response, next) { if (request.url !== '/__run__' && request.url !== urlRoot + 'run') { return next() @@ -48,6 +49,7 @@ function createRunnerMiddleware (emitter, fileList, capturedBrowsers, reporter, }) }) + helper.restoreOriginalArgs(config) if (_.isEmpty(data.args)) { log.debug('Ignoring empty client.args from run command') } else if ((_.isArray(data.args) && _.isArray(config.client.args)) || diff --git a/test/unit/helper.spec.js b/test/unit/helper.spec.js index 1cf286c07..3cabf4a1c 100644 --- a/test/unit/helper.spec.js +++ b/test/unit/helper.spec.js @@ -309,4 +309,32 @@ describe('helper', () => { helper.mmPatternWeight('{**,*}').should.be.deep.equal([2, 1, 0, 0, 0, 0]) }) }) + + describe('saveOriginalArgs', () => { + it('should clone config.client.args', () => { + var config = { + client: { + args: ['--somearg'] + } + } + expect(config.client.originalArgs).to.not.exist + helper.saveOriginalArgs(config) + config.client.args.should.be.deep.equal(['--somearg']) + config.client.originalArgs.should.be.deep.equal(['--somearg']) + }) + }) + + describe('restoreOriginalArgs', () => { + it('should restore config.client.originalArgs', () => { + var config = { + client: { + args: ['--somearg'], + originalArgs: [] + } + } + helper.restoreOriginalArgs(config) + config.client.args.should.be.deep.equal([]) + config.client.originalArgs.should.be.deep.equal([]) + }) + }) }) diff --git a/test/unit/middleware/runner.spec.js b/test/unit/middleware/runner.spec.js index 9a7985fb3..c2dd60c7c 100644 --- a/test/unit/middleware/runner.spec.js +++ b/test/unit/middleware/runner.spec.js @@ -23,6 +23,21 @@ describe('middleware.runner', () => { var handler var fileListMock + function createHandler () { + handler = createRunnerMiddleware( + emitter, + fileListMock, + capturedBrowsers, + new MultReporter([mockReporter]), + executor, + 'http:', + 'localhost', + 8877, + '/', + config + ) + } + before(() => { Promise.setScheduler((fn) => fn()) }) @@ -55,302 +70,297 @@ describe('middleware.runner', () => { nextSpy = sinon.spy() response = new HttpResponseMock() config = {client: {}, basePath: '/'} - - handler = createRunnerMiddleware( - emitter, - fileListMock, - capturedBrowsers, - new MultReporter([mockReporter]), - executor, - 'http:', - 'localhost', - 8877, - '/', - config - ) }) - it('should trigger test run and stream the reporter', (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - - response.once('end', () => { - expect(nextSpy).to.not.have.been.called - expect(response).to.beServedAs(200, 'result\x1FEXIT10') - done() + describe('', () => { + beforeEach(() => { + createHandler() }) - handler(new HttpRequestMock('/__run__'), response, nextSpy) + it('should trigger test run and stream the reporter', (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - mockReporter.write('result') - emitter.emit('run_complete', capturedBrowsers, {exitCode: 0}) - }) + response.once('end', () => { + expect(nextSpy).to.not.have.been.called + expect(response).to.beServedAs(200, 'result\x1FEXIT10') + done() + }) - it('should set the empty to 0 if empty results', (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + handler(new HttpRequestMock('/__run__'), response, nextSpy) - response.once('end', () => { - expect(nextSpy).to.not.have.been.called - expect(response).to.beServedAs(200, 'result\x1FEXIT00') - done() + mockReporter.write('result') + emitter.emit('run_complete', capturedBrowsers, {exitCode: 0}) }) - handler(new HttpRequestMock('/__run__'), response, nextSpy) + it('should set the empty to 0 if empty results', (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - mockReporter.write('result') - emitter.emit('run_complete', capturedBrowsers, {exitCode: 0, success: 0, failed: 0}) - }) + response.once('end', () => { + expect(nextSpy).to.not.have.been.called + expect(response).to.beServedAs(200, 'result\x1FEXIT00') + done() + }) - it('should set the empty to 1 if successful tests', (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + handler(new HttpRequestMock('/__run__'), response, nextSpy) - response.once('end', () => { - expect(nextSpy).to.not.have.been.called - expect(response).to.beServedAs(200, 'result\x1FEXIT10') - done() + mockReporter.write('result') + emitter.emit('run_complete', capturedBrowsers, {exitCode: 0, success: 0, failed: 0}) }) - handler(new HttpRequestMock('/__run__'), response, nextSpy) + it('should set the empty to 1 if successful tests', (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - mockReporter.write('result') - emitter.emit('run_complete', capturedBrowsers, {exitCode: 0, success: 3, failed: 0}) - }) + response.once('end', () => { + expect(nextSpy).to.not.have.been.called + expect(response).to.beServedAs(200, 'result\x1FEXIT10') + done() + }) - it('should set the empty to 1 if failed tests', (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + handler(new HttpRequestMock('/__run__'), response, nextSpy) - response.once('end', () => { - expect(nextSpy).to.not.have.been.called - expect(response).to.beServedAs(200, 'result\x1FEXIT10') - done() + mockReporter.write('result') + emitter.emit('run_complete', capturedBrowsers, {exitCode: 0, success: 3, failed: 0}) }) - handler(new HttpRequestMock('/__run__'), response, nextSpy) + it('should set the empty to 1 if failed tests', (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - mockReporter.write('result') - emitter.emit('run_complete', capturedBrowsers, {exitCode: 0, success: 0, failed: 6}) - }) + response.once('end', () => { + expect(nextSpy).to.not.have.been.called + expect(response).to.beServedAs(200, 'result\x1FEXIT10') + done() + }) - it('should not run if there is no browser captured', (done) => { - sinon.stub(fileListMock, 'refresh') + handler(new HttpRequestMock('/__run__'), response, nextSpy) - response.once('end', () => { - expect(nextSpy).to.not.have.been.called - expect(response).to.beServedAs(200, 'No captured browser, open http://localhost:8877/\n') - expect(fileListMock.refresh).not.to.have.been.called - done() + mockReporter.write('result') + emitter.emit('run_complete', capturedBrowsers, {exitCode: 0, success: 0, failed: 6}) }) - handler(new HttpRequestMock('/__run__'), response, nextSpy) - }) + it('should not run if there is no browser captured', (done) => { + sinon.stub(fileListMock, 'refresh') - var clientArgsRuns = [ - { - desc: 'should parse body and set client.args', - expected: ['arg1', 'arg2'], - rawMessage: '{"args": ["arg1", "arg2"]}' - }, - { - desc: 'should set array client args passed by run when there are no existing client.args', - expected: ['my_args'], - rawMessage: '{"args": ["my_args"]}' - }, - { - desc: 'should set object client args passed by run when there are no existing client.args', - expected: {arg2: 'fig', arg3: 'chocolate'}, - rawMessage: '{"args": {"arg2": "fig", "arg3": "chocolate"}}' - }, - { - desc: 'should overwrite empty array client.args when run passes an array for client.args', - expected: ['user_arg1'], - rawMessage: '{"args": ["user_arg1"]}', - existingConfig: [] - }, - { - desc: 'should overwrite empty array client.args when run passes an object for client.args', - expected: {arg2: 'figs', arg3: 'chocolates'}, - rawMessage: '{"args": {"arg2": "figs", "arg3": "chocolates"}}', - existingConfig: [] - }, - { - desc: 'should overwrite empty object client.args when run passes an array for client.args', - expected: ['user_arg'], - rawMessage: '{"args": ["user_arg"]}', - existingConfig: {} - }, - { - desc: 'should not overwrite existing array client.args when run passes an empty array for client.args', - expected: ['user_arg'], - rawMessage: '{"args": []}', - existingConfig: ['user_arg'] - }, - { - desc: 'should not overwrite existing array client.args when run passes an empty object for client.args', - expected: ['user_arg'], - rawMessage: '{"args": {}}', - existingConfig: ['user_arg'] - }, - { - desc: 'should not overwrite existing array client.args when run passes no client.args', - expected: ['user_arg'], - rawMessage: '{}', - existingConfig: ['user_arg'] - }, - { - desc: 'should merge existing client.args with client.args passed by run', - expected: {arg1: 'cherry', arg2: 'fig', arg3: 'chocolate'}, - rawMessage: '{"args": {"arg2": "fig", "arg3": "chocolate"}}', - existingConfig: {arg1: 'cherry', arg2: 'mango'} - }, - { - desc: 'should merge empty client.args with client.args passed by run', - expected: {arg2: 'fig', arg3: 'chocolate'}, - rawMessage: '{"args": {"arg2": "fig", "arg3": "chocolate"}}', - existingConfig: {} - } - ] + response.once('end', () => { + expect(nextSpy).to.not.have.been.called + expect(response).to.beServedAs(200, 'No captured browser, open http://localhost:8877/\n') + expect(fileListMock.refresh).not.to.have.been.called + done() + }) - describe('', function () { - clientArgsRuns.forEach(function (run) { - it(run.desc, (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - if (run.existingConfig) { - config = _.merge(config, {client: {args: run.existingConfig}}) - } + handler(new HttpRequestMock('/__run__'), response, nextSpy) + }) - emitter.once('run_start', () => { - expect(config.client.args).to.deep.equal(run.expected) - done() - }) + it('should refresh explicit files if specified', (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + sinon.stub(fileListMock, 'refresh') + sinon.stub(fileListMock, 'addFile') + sinon.stub(fileListMock, 'changeFile') + sinon.stub(fileListMock, 'removeFile') + + var RAW_MESSAGE = JSON.stringify({ + addedFiles: ['/new.js'], + removedFiles: ['/foo.js', '/bar.js'], + changedFiles: ['/changed.js'] + }) - var RAW_MESSAGE = run.rawMessage + var request = new HttpRequestMock('/__run__', { + 'content-type': 'application/json', + 'content-length': RAW_MESSAGE.length + }) - var request = new HttpRequestMock('/__run__', { - 'content-type': 'application/json', - 'content-length': RAW_MESSAGE.length - }) + handler(request, response, nextSpy) - handler(request, response, nextSpy) + request.emit('data', RAW_MESSAGE) + request.emit('end') - request.emit('data', RAW_MESSAGE) - request.emit('end') + process.nextTick(() => { + expect(fileListMock.refresh).not.to.have.been.called + expect(fileListMock.addFile).to.have.been.calledWith(path.resolve('/new.js')) + expect(fileListMock.removeFile).to.have.been.calledWith(path.resolve('/foo.js')) + expect(fileListMock.removeFile).to.have.been.calledWith(path.resolve('/bar.js')) + expect(fileListMock.changeFile).to.have.been.calledWith(path.resolve('/changed.js')) + done() }) }) - }) - it('should refresh explicit files if specified', (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - sinon.stub(fileListMock, 'refresh') - sinon.stub(fileListMock, 'addFile') - sinon.stub(fileListMock, 'changeFile') - sinon.stub(fileListMock, 'removeFile') - - var RAW_MESSAGE = JSON.stringify({ - addedFiles: ['/new.js'], - removedFiles: ['/foo.js', '/bar.js'], - changedFiles: ['/changed.js'] - }) + it('should wait for refresh to finish if applicable before scheduling execution', (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - var request = new HttpRequestMock('/__run__', { - 'content-type': 'application/json', - 'content-length': RAW_MESSAGE.length - }) + var res = null + var fileListPromise = new Promise((resolve, reject) => { + res = resolve + }) + sinon.stub(fileListMock, 'refresh').returns(fileListPromise) + sinon.stub(executor, 'schedule') - handler(request, response, nextSpy) + var request = new HttpRequestMock('/__run__') + handler(request, response, nextSpy) - request.emit('data', RAW_MESSAGE) - request.emit('end') + process.nextTick(() => { + expect(fileListMock.refresh).to.have.been.called + expect(executor.schedule).to.not.have.been.called - process.nextTick(() => { - expect(fileListMock.refresh).not.to.have.been.called - expect(fileListMock.addFile).to.have.been.calledWith(path.resolve('/new.js')) - expect(fileListMock.removeFile).to.have.been.calledWith(path.resolve('/foo.js')) - expect(fileListMock.removeFile).to.have.been.calledWith(path.resolve('/bar.js')) - expect(fileListMock.changeFile).to.have.been.calledWith(path.resolve('/changed.js')) - done() + // Now try resolving the promise + res() + setTimeout(() => { + expect(executor.schedule).to.have.been.called + done() + }, 2) + }) }) - }) - it('should wait for refresh to finish if applicable before scheduling execution', (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + it('should schedule execution if no refresh', (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - var res = null - var fileListPromise = new Promise((resolve, reject) => { - res = resolve - }) - sinon.stub(fileListMock, 'refresh').returns(fileListPromise) - sinon.stub(executor, 'schedule') + sinon.spy(fileListMock, 'refresh') + sinon.stub(executor, 'schedule') + + var RAW_MESSAGE = JSON.stringify({refresh: false}) + + var request = new HttpRequestMock('/__run__', { + 'content-type': 'application/json', + 'content-length': RAW_MESSAGE.length + }) - var request = new HttpRequestMock('/__run__') - handler(request, response, nextSpy) + handler(request, response, nextSpy) - process.nextTick(() => { - expect(fileListMock.refresh).to.have.been.called - expect(executor.schedule).to.not.have.been.called + request.emit('data', RAW_MESSAGE) + request.emit('end') - // Now try resolving the promise - res() - setTimeout(() => { + process.nextTick(() => { + expect(fileListMock.refresh).not.to.have.been.called expect(executor.schedule).to.have.been.called done() - }, 2) + }) }) - }) - it('should schedule execution if no refresh', (done) => { - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + it('should not schedule execution if refreshing and autoWatch', (done) => { + config.autoWatch = true - sinon.spy(fileListMock, 'refresh') - sinon.stub(executor, 'schedule') + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - var RAW_MESSAGE = JSON.stringify({refresh: false}) + sinon.spy(fileListMock, 'refresh') + sinon.stub(executor, 'schedule') - var request = new HttpRequestMock('/__run__', { - 'content-type': 'application/json', - 'content-length': RAW_MESSAGE.length - }) + handler(new HttpRequestMock('/__run__'), response, nextSpy) - handler(request, response, nextSpy) - - request.emit('data', RAW_MESSAGE) - request.emit('end') + process.nextTick(() => { + expect(fileListMock.refresh).to.have.been.called + expect(executor.schedule).not.to.have.been.called + done() + }) + }) - process.nextTick(() => { - expect(fileListMock.refresh).not.to.have.been.called - expect(executor.schedule).to.have.been.called - done() + it('should ignore other urls', (done) => { + handler(new HttpRequestMock('/something'), response, () => { + expect(response).to.beNotServed() + done() + }) }) }) - it('should not schedule execution if refreshing and autoWatch', (done) => { - config.autoWatch = true + describe('', () => { + var clientArgsRuns = [ + { + desc: 'should parse body and set client.args', + expected: ['arg1', 'arg2'], + rawMessage: '{"args": ["arg1", "arg2"]}' + }, + { + desc: 'should set array client args passed by run when there are no existing client.args', + expected: ['my_args'], + rawMessage: '{"args": ["my_args"]}' + }, + { + desc: 'should set object client args passed by run when there are no existing client.args', + expected: {arg2: 'fig', arg3: 'chocolate'}, + rawMessage: '{"args": {"arg2": "fig", "arg3": "chocolate"}}' + }, + { + desc: 'should overwrite empty array client.args when run passes an array for client.args', + expected: ['user_arg1'], + rawMessage: '{"args": ["user_arg1"]}', + existingConfig: [] + }, + { + desc: 'should overwrite empty array client.args when run passes an object for client.args', + expected: {arg2: 'figs', arg3: 'chocolates'}, + rawMessage: '{"args": {"arg2": "figs", "arg3": "chocolates"}}', + existingConfig: [] + }, + { + desc: 'should overwrite empty object client.args when run passes an array for client.args', + expected: ['user_arg'], + rawMessage: '{"args": ["user_arg"]}', + existingConfig: {} + }, + { + desc: 'should not overwrite existing array client.args when run passes an empty array for client.args', + expected: ['user_arg'], + rawMessage: '{"args": []}', + existingConfig: ['user_arg'] + }, + { + desc: 'should not overwrite existing array client.args when run passes an empty object for client.args', + expected: ['user_arg'], + rawMessage: '{"args": {}}', + existingConfig: ['user_arg'] + }, + { + desc: 'should not overwrite existing array client.args when run passes no client.args', + expected: ['user_arg'], + rawMessage: '{}', + existingConfig: ['user_arg'] + }, + { + desc: 'should merge existing client.args with client.args passed by run', + expected: {arg1: 'cherry', arg2: 'fig', arg3: 'chocolate'}, + rawMessage: '{"args": {"arg2": "fig", "arg3": "chocolate"}}', + existingConfig: {arg1: 'cherry', arg2: 'mango'} + }, + { + desc: 'should merge empty client.args with client.args passed by run', + expected: {arg2: 'fig', arg3: 'chocolate'}, + rawMessage: '{"args": {"arg2": "fig", "arg3": "chocolate"}}', + existingConfig: {} + } + ] - capturedBrowsers.add(new Browser()) - sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + clientArgsRuns.forEach(function (run) { + it(run.desc, (done) => { + capturedBrowsers.add(new Browser()) + sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) + if (run.existingConfig) { + config = _.merge(config, {client: {args: run.existingConfig}}) + } + createHandler() - sinon.spy(fileListMock, 'refresh') - sinon.stub(executor, 'schedule') + emitter.once('run_start', () => { + expect(config.client.args).to.deep.equal(run.expected) + expect(config.client.originalArgs).to.deep.equal(run.existingConfig) + done() + }) - handler(new HttpRequestMock('/__run__'), response, nextSpy) + var RAW_MESSAGE = run.rawMessage - process.nextTick(() => { - expect(fileListMock.refresh).to.have.been.called - expect(executor.schedule).not.to.have.been.called - done() - }) - }) + var request = new HttpRequestMock('/__run__', { + 'content-type': 'application/json', + 'content-length': RAW_MESSAGE.length + }) + + handler(request, response, nextSpy) - it('should ignore other urls', (done) => { - handler(new HttpRequestMock('/something'), response, () => { - expect(response).to.beNotServed() - done() + request.emit('data', RAW_MESSAGE) + request.emit('end') + }) }) }) }) From 68b37d3c8909a9c999d40fe20543bffe33f1e096 Mon Sep 17 00:00:00 2001 From: Jonathan Felchlin Date: Thu, 6 Sep 2018 09:07:53 -0700 Subject: [PATCH 035/374] feat(server): Add support for encoded source files (#3123) --- docs/dev/05-plugins.md | 11 +++++++ lib/file.js | 4 +++ lib/middleware/source_files.js | 11 ++++++- test/unit/middleware/source_files.spec.js | 36 +++++++++++++++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/docs/dev/05-plugins.md b/docs/dev/05-plugins.md index 477fe607d..478b7303e 100644 --- a/docs/dev/05-plugins.md +++ b/docs/dev/05-plugins.md @@ -18,6 +18,17 @@ Karma can be extended through plugins. A plugin is essentially an NPM module. Ty - use NPM keywords `karma-plugin`, `karma-launcher` ## Preprocessors + +A preprocessor is a function that accepts three arguments (`content`, `file`, and `next`), mutates the content in some way, and passes it on to the next preprocessor. + +- arguments passed to preprocessor plugins: + - **`content`** of the file being processed + - **`file`** object describing the file being processed + - **path:** the current file, mutable file path. e. g. `some/file.coffee` -> `some/file.coffee.js` _This path is mutable and may not actually exist._ + - **originalPath:** the original, unmutated path + - **encodings:** A mutable, keyed object where the keys are a valid encoding type ('gzip', 'compress', 'br', etc.) and the values are the encoded content. Encoded content should be stored here and not resolved using `next(null, encodedContent)` + - **type:** the pattern used to match the file + - **`next`** function to be called when preprocessing is complete, should be called as `next(null, processedContent)` or `next(error)` - example plugins: [karma-coffee-preprocessor], [karma-ng-html2js-preprocessor] - use naming convention is `karma-*-preprocessor` - user NPM keywords `karma-plugin`, `karma-preprocessor` diff --git a/lib/file.js b/lib/file.js index 094df9e0e..8689db103 100644 --- a/lib/file.js +++ b/lib/file.js @@ -14,6 +14,10 @@ class File { // where the content is stored (processed) this.contentPath = path + // encodings format {[encodingType]: encodedContent} + // example: {gzip: } + this.encodings = Object.create(null) + this.mtime = mtime this.isUrl = false diff --git a/lib/middleware/source_files.js b/lib/middleware/source_files.js index 5fd236ccd..efe1f4a29 100644 --- a/lib/middleware/source_files.js +++ b/lib/middleware/source_files.js @@ -35,13 +35,22 @@ function createSourceFilesMiddleware (filesPromise, serveFile, basePath, urlRoot const rangeHeader = request.headers['range'] if (file) { + const acceptEncodingHeader = request.headers['accept-encoding'] + const matchedEncoding = Object.keys(file.encodings).find( + (encoding) => new RegExp(`(^|.*, ?)${encoding}(,|$)`).test(acceptEncodingHeader) + ) + const content = file.encodings[matchedEncoding] || file.content + serveFile(file.contentPath || file.path, rangeHeader, response, function () { if (/\?\w+/.test(request.url)) { common.setHeavyCacheHeaders(response) // files with timestamps - cache one year, rely on timestamps } else { common.setNoCacheHeaders(response) // without timestamps - no cache (debug) } - }, file.content, file.doNotCache) + if (matchedEncoding) { + response.setHeader('Content-Encoding', matchedEncoding) + } + }, content, file.doNotCache) } else { next() } diff --git a/test/unit/middleware/source_files.spec.js b/test/unit/middleware/source_files.spec.js index 540e9cf0b..64d481298 100644 --- a/test/unit/middleware/source_files.spec.js +++ b/test/unit/middleware/source_files.spec.js @@ -1,6 +1,7 @@ var http = require('http') var mocks = require('mocks') var request = require('supertest') +var zlib = require('zlib') var helper = require('../../../lib/helper') var File = require('../../../lib/file') @@ -109,6 +110,41 @@ describe('middleware.source_files', function () { }) }) + describe('file encoding', function () { + let file + beforeEach(function () { + file = new File('/src/some.js') + servedFiles([ + file + ]) + }) + + it('serves encoded files', function () { + file.encodings.gzip = zlib.gzipSync('gzipped-js-source') + return request(server) + .get('/absolute/src/some.js') + .set('Accept-Encoding', 'gzip, deflate') + .expect(200, 'gzipped-js-source') + .expect('Content-Encoding', 'gzip') + .expect('Content-Type', 'application/javascript') + }) + + it('serves unencoded files when request does not accept available encodings', function (done) { + file.encodings.gzip = zlib.gzipSync('gzipped-js-source') + request(server) + .get('/absolute/src/some.js') + .set('Accept-Encoding', 'gzippy, deflate') + .expect(200, 'js-source') + .end((error, res) => { + if (error) { + return done(error) + } + expect(res.headers).to.not.have.property('content-encoding') + return done() + }) + }) + }) + it('should serve absolute js source files ignoring timestamp', function () { servedFiles([ new File('/src/some.js') From d65e911c80f0ccb3d6dac5634c89d93ff45e9ca8 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 6 Sep 2018 12:12:18 -0700 Subject: [PATCH 036/374] fix(middleware): simplify stripHost. (#3115) The stripHost middleware only adds a modified url to the request. That modified url is only used one place. By converting the middleware to a module, the code is simpler and beforeMiddleware modules can reuse karma middleware. (One alternative considered was to move the stripHost in the chain before the beforeMiddleware, but this form seems better). Clean up regex per offline suggestion from zzo@ --- lib/middleware/karma.js | 7 ++- lib/middleware/strip_host.js | 15 ++---- lib/web-server.js | 2 - test/unit/middleware/strip_host.spec.js | 65 ++++++------------------- 4 files changed, 26 insertions(+), 63 deletions(-) diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 6ef06ef63..d47e898a0 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -17,6 +17,7 @@ var url = require('url') var _ = require('lodash') var log = require('../logger').create('middleware:karma') +var stripHost = require('./strip_host').stripHost function urlparse (urlStr) { var urlObj = url.parse(urlStr, true) @@ -90,7 +91,11 @@ function createKarmaMiddleware ( var customClientContextFile = injector.get('config.customClientContextFile') var includeCrossOriginAttribute = injector.get('config.crossOriginAttribute') - var requestUrl = request.normalizedUrl.replace(/\?.*/, '') + var normalizedUrl = stripHost(request.url) || request.url + // For backwards compatibility in middleware plugins, remove in v4. + request.normalizedUrl = normalizedUrl + + var requestUrl = normalizedUrl.replace(/\?.*/, '') var requestedRangeHeader = request.headers['range'] // redirect /__karma__ to /__karma__ (trailing slash) diff --git a/lib/middleware/strip_host.js b/lib/middleware/strip_host.js index 984f89f2d..539be0aad 100644 --- a/lib/middleware/strip_host.js +++ b/lib/middleware/strip_host.js @@ -1,18 +1,11 @@ /** - * Strip host middleware is responsible for stripping hostname from request path + * Strip hostname from request path * This to handle requests that uses (normally over proxies) an absoluteURI as request path */ -function createStripHostMiddleware () { - return function (request, response, next) { - function stripHostFromUrl (url) { - return url.replace(/^http[s]?:\/\/([a-z\-.:\d]+)\//, '/') - } - - request.normalizedUrl = stripHostFromUrl(request.url) || request.url - next() - } +function stripHostFromUrl (url) { + return url.replace(/^https?:\/\/[a-z.:\d-]+\//, '/') } // PUBLIC API -exports.create = createStripHostMiddleware +exports.stripHost = stripHostFromUrl diff --git a/lib/web-server.js b/lib/web-server.js index bd63481d7..3bda89827 100644 --- a/lib/web-server.js +++ b/lib/web-server.js @@ -10,7 +10,6 @@ const Promise = require('bluebird') const common = require('./middleware/common') const runnerMiddleware = require('./middleware/runner') const stopperMiddleware = require('./middleware/stopper') -const stripHostMiddleware = require('./middleware/strip_host') const karmaMiddleware = require('./middleware/karma') const sourceFilesMiddleware = require('./middleware/source_files') const proxyMiddleware = require('./middleware/proxy') @@ -65,7 +64,6 @@ function createWebServer (injector, config) { handler.use(injector.invoke(runnerMiddleware.create)) handler.use(injector.invoke(stopperMiddleware.create)) - handler.use(injector.invoke(stripHostMiddleware.create)) handler.use(injector.invoke(karmaMiddleware.create)) handler.use(injector.invoke(sourceFilesMiddleware.create)) // TODO(vojta): extract the proxy into a plugin diff --git a/test/unit/middleware/strip_host.spec.js b/test/unit/middleware/strip_host.spec.js index 5983e61c8..5315f08f1 100644 --- a/test/unit/middleware/strip_host.spec.js +++ b/test/unit/middleware/strip_host.spec.js @@ -1,61 +1,28 @@ -var mocks = require('mocks') - describe('middleware.strip_host', function () { - var nextSpy - var HttpRequestMock = mocks.http.ServerRequest - - var createStripHostMiddleware = require('../../../lib/middleware/strip_host').create - - var handler = nextSpy = null - - beforeEach(function () { - nextSpy = sinon.spy() - handler = createStripHostMiddleware(null, null, '/base/path') - return handler - }) + const stripHost = require('../../../lib/middleware/strip_host').stripHost - it('should strip request with IP number', function (done) { - var request = new HttpRequestMock('http://192.12.31.100/base/a.js?123345') - handler(request, null, nextSpy) - - expect(request.normalizedUrl).to.equal('/base/a.js?123345') - expect(nextSpy).to.have.been.called - return done() + it('should strip request with IP number', function () { + const normalizedUrl = stripHost('http://192.12.31.100/base/a.js?123345') + expect(normalizedUrl).to.equal('/base/a.js?123345') }) - it('should strip request with absoluteURI', function (done) { - var request = new HttpRequestMock('http://localhost/base/a.js?123345') - handler(request, null, nextSpy) - - expect(request.normalizedUrl).to.equal('/base/a.js?123345') - expect(nextSpy).to.have.been.called - return done() + it('should strip request with absoluteURI', function () { + const normalizedUrl = stripHost('http://localhost/base/a.js?123345') + expect(normalizedUrl).to.equal('/base/a.js?123345') }) - it('should strip request with absoluteURI and port', function (done) { - var request = new HttpRequestMock('http://localhost:9876/base/a.js?123345') - handler(request, null, nextSpy) - - expect(request.normalizedUrl).to.equal('/base/a.js?123345') - expect(nextSpy).to.have.been.called - return done() + it('should strip request with absoluteURI and port', function () { + const normalizedUrl = stripHost('http://localhost:9876/base/a.js?123345') + expect(normalizedUrl).to.equal('/base/a.js?123345') }) - it('should strip request with absoluteURI over HTTPS', function (done) { - var request = new HttpRequestMock('https://karma-runner.github.io/base/a.js?123345') - handler(request, null, nextSpy) - - expect(request.normalizedUrl).to.equal('/base/a.js?123345') - expect(nextSpy).to.have.been.called - return done() + it('should strip request with absoluteURI over HTTPS', function () { + const normalizedUrl = stripHost('https://karma-runner.github.io/base/a.js?123345') + expect(normalizedUrl).to.equal('/base/a.js?123345') }) - return it('should return same url as passed one', function (done) { - var request = new HttpRequestMock('/base/b.js?123345') - handler(request, null, nextSpy) - - expect(request.normalizedUrl).to.equal('/base/b.js?123345') - expect(nextSpy).to.have.been.called - return done() + it('should return same url as passed one', function () { + const normalizedUrl = stripHost('/base/b.js?123345') + expect(normalizedUrl).to.equal('/base/b.js?123345') }) }) From 6742ecfbc9501a454430cbb3b814be28f459cb38 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Sun, 23 Sep 2018 20:58:05 +0200 Subject: [PATCH 037/374] docs(config): customized typeScript configuration (#3140) --- docs/config/01-configuration-file.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/config/01-configuration-file.md b/docs/config/01-configuration-file.md index e16b70080..542b55a25 100644 --- a/docs/config/01-configuration-file.md +++ b/docs/config/01-configuration-file.md @@ -53,6 +53,20 @@ module.exports = (config) => { } ``` +### Customized TypeScript Configuration +Under the hood Karma uses ts-node to transpile TypeScript to JavaScript. If the resolved `tsconfig.json` has `module` configured as `ES` formats. You might get errors like `SyntaxError: Unexpected token`. This is due that in Node `ES` module formats are not supported. To overcome this issue you need to configure ts-node to use `commonjs` module format. + +Create a JavaScript configuration file that overrides the module format. +```javascript +// karma.conf.js +require('ts-node').register({ + compilerOptions: { + module: 'commonjs' + } +}); +require('./karma.conf.ts'); +``` + ## File Patterns All of the configuration options, which specify file paths, use the [minimatch][minimatch] library to facilitate flexible but concise file expressions so you can easily list all of the files you want to include and exclude. From 20eab32345a2e47334aada35ab6cf7c0a0000b7b Mon Sep 17 00:00:00 2001 From: Janderson Constantino Date: Tue, 25 Sep 2018 12:29:32 -0300 Subject: [PATCH 038/374] chore(license): change year to 2018 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index f94360e53..c39b326cd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (C) 2011-2016 Google, Inc. +Copyright (C) 2011-2018 Google, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From f71da205d779e208fcd4bdbcc9e9b35f93994d1f Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 3 Oct 2018 01:41:05 +0200 Subject: [PATCH 039/374] docs: Updated supported Node versions in the documentation (#3155) * docs: update information on supported node versions * docs: update links to point to latest version on the website --- CONTRIBUTING.md | 2 +- PULL_REQUEST_TEMPLATE.md | 2 +- docs/intro/01-installation.md | 2 +- docs/intro/04-faq.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ca4778555..9385e6943 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -18,7 +18,7 @@ with a fix. **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub][egghead_series] -[docs_contributing]: http://karma-runner.github.io/0.13/dev/contributing.html +[docs_contributing]: http://karma-runner.github.io/latest/dev/contributing.html [gitter]: https://gitter.im/karma-runner/karma [stackoverflow]: http://stackoverflow.com/questions/tagged/karma-runner [github_newissue]: https://github.com/karma-runner/karma/issues/new diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md index 648a3822d..816fbcb9d 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,3 @@ Check that your description matches the automatic change-log format: -http://karma-runner.github.io/2.0/dev/git-commit-msg.html +http://karma-runner.github.io/latest/dev/git-commit-msg.html then delete this reminder. diff --git a/docs/intro/01-installation.md b/docs/intro/01-installation.md index cfda43256..e55c62640 100644 --- a/docs/intro/01-installation.md +++ b/docs/intro/01-installation.md @@ -5,7 +5,7 @@ Karma runs on [Node.js] and is available as an [NPM] package. On Mac or Linux we recommend using [NVM](https://github.com/creationix/nvm). On Windows, download Node.js from [the official site](https://nodejs.org/) or use the [NVM PowerShell Module](https://www.powershellgallery.com/packages/nvm). -Note: Karma currently works on Node.js **4.x**, **5.x**, **6.x**, **7.x**, and **8.x**. See [FAQ] for more info. +Note: Karma currently works on Node.js **6.x**, **8.x**, and **10.x**. See [FAQ] for more info. ## Installing Karma and plugins diff --git a/docs/intro/04-faq.md b/docs/intro/04-faq.md index 4eae6586e..90ae63300 100644 --- a/docs/intro/04-faq.md +++ b/docs/intro/04-faq.md @@ -25,7 +25,7 @@ The latest stable version from NPM (`npm install karma`). See [versioning] for m ### Which version of Node.js does Karma run with? -Karma works on all LTS versions node in active maintenance state (see [LTS docs](https://github.com/nodejs/LTS/blob/master/README.md) for more info) as well as the latest stable version. That is **4.x**, **5.x**, **6.x**, and **8.x** at this point. +Karma works on all LTS versions node in active maintenance state (see [LTS docs](https://github.com/nodejs/Release/blob/master/README.md) for more info) as well as the latest stable version. That is **6.x**, **8.x** and **10.x** at this point. [mailing list]: https://groups.google.com/d/forum/karma-users From c67b90ab34ac8c3bc873a1861383cb561ad24de2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Wed, 3 Oct 2018 15:56:37 +0200 Subject: [PATCH 040/374] refactor(server): replace var with const/let (#3152) --- lib/init.js | 2 +- lib/init/color_schemes.js | 4 +- lib/init/state_machine.js | 14 +-- lib/launcher.js | 3 +- lib/launchers/base.js | 28 +++--- lib/launchers/capture_timeout.js | 6 +- lib/launchers/process.js | 22 ++--- lib/launchers/retry.js | 6 +- lib/logger.js | 14 +-- lib/middleware/karma.js | 98 ++++++++++----------- lib/middleware/proxy.js | 32 +++---- lib/middleware/runner.js | 23 +++-- lib/middleware/stopper.js | 2 +- lib/preprocessor.js | 2 +- lib/reporter.js | 2 +- lib/reporters/dots.js | 4 +- lib/reporters/dots_color.js | 4 +- lib/reporters/progress.js | 4 +- lib/reporters/progress_color.js | 4 +- lib/stopper.js | 14 +-- tasks/init-dev-env.js | 4 +- tasks/test.js | 8 +- test/client/karma.conf.js | 6 +- test/client/karma.spec.js | 80 ++++++++--------- test/client/mocks.js | 8 +- test/client/stringify.spec.js | 28 +++--- test/client/util.spec.js | 7 +- test/e2e/step_definitions/core_steps.js | 84 +++++++++--------- test/e2e/step_definitions/hooks.js | 4 +- test/e2e/support/env.js | 2 +- test/e2e/support/headers/test.js | 2 +- test/e2e/support/middleware/test.js | 2 +- test/e2e/support/proxy.js | 10 +-- test/e2e/support/proxy/test.js | 2 +- test/e2e/support/tag/tag.js | 4 +- test/e2e/support/world.js | 16 ++-- test/unit/events.spec.js | 34 +++---- test/unit/init.spec.js | 76 ++++++++-------- test/unit/init/formatters.spec.js | 16 ++-- test/unit/init/state_machine.spec.js | 34 +++---- test/unit/launcher.spec.js | 56 ++++++------ test/unit/launchers/base.spec.js | 56 ++++++------ test/unit/launchers/capture_timeout.spec.js | 10 +-- test/unit/launchers/process.spec.js | 56 ++++++------ test/unit/launchers/retry.spec.js | 18 ++-- test/unit/logger.spec.js | 10 +-- test/unit/middleware/karma.spec.js | 51 ++++++----- test/unit/middleware/proxy.spec.js | 93 ++++++++++--------- test/unit/middleware/runner.spec.js | 54 ++++++------ test/unit/middleware/source_files.spec.js | 32 +++---- test/unit/mocha-globals.js | 18 ++-- test/unit/mocks/timer.js | 4 +- test/unit/preprocessor.spec.js | 2 +- test/unit/reporter.spec.js | 82 ++++++++--------- test/unit/reporters/progress.spec.js | 6 +- test/unit/runner.spec.js | 28 +++--- test/unit/server.spec.js | 44 ++++----- test/unit/watcher.spec.js | 28 +++--- test/unit/web-server.spec.js | 48 +++++----- 59 files changed, 703 insertions(+), 708 deletions(-) diff --git a/lib/init.js b/lib/init.js index f744ec808..2257743ee 100755 --- a/lib/init.js +++ b/lib/init.js @@ -21,7 +21,7 @@ const formatters = require('./init/formatters') // TODO(vojta): SauceLabs // TODO(vojta): BrowserStack -var NODE_MODULES_DIR = path.resolve(__dirname, '../..') +let NODE_MODULES_DIR = path.resolve(__dirname, '../..') // Karma is not in node_modules, probably a symlink, // use current working dir. diff --git a/lib/init/color_schemes.js b/lib/init/color_schemes.js index 3ff78079f..5f265a871 100644 --- a/lib/init/color_schemes.js +++ b/lib/init/color_schemes.js @@ -1,4 +1,4 @@ -var COLORS_ON = { +const COLORS_ON = { RESET: '\x1B[39m', ANSWER: '\x1B[36m', // NYAN SUCCESS: '\x1B[32m', // GREEN @@ -11,7 +11,7 @@ var COLORS_ON = { } } -var COLORS_OFF = { +const COLORS_OFF = { RESET: '', ANSWER: '', SUCCESS: '', diff --git a/lib/init/state_machine.js b/lib/init/state_machine.js index 789087bd4..4097bee6a 100644 --- a/lib/init/state_machine.js +++ b/lib/init/state_machine.js @@ -2,13 +2,13 @@ const logQueue = require('./log-queue') -var questions -var currentQuestion -var answers -var currentOptions -var currentOptionsPointer -var currentQuestionId -var done +let questions +let currentQuestion +let answers +let currentOptions +let currentOptionsPointer +let currentQuestionId +let done class StateMachine { constructor (rli, colors) { diff --git a/lib/launcher.js b/lib/launcher.js index 80d5d1d30..f4707c4f7 100644 --- a/lib/launcher.js +++ b/lib/launcher.js @@ -41,6 +41,7 @@ function Launcher (server, emitter, injector) { } return (name) => { + let browser const locals = { id: ['value', Launcher.generateId()], name: ['value', name], @@ -58,7 +59,7 @@ function Launcher (server, emitter, injector) { } try { - var browser = injector.createChild([locals], ['launcher:' + name]).get('launcher:' + name) + browser = injector.createChild([locals], ['launcher:' + name]).get('launcher:' + name) } catch (e) { if (e.message.indexOf(`No provider for "launcher:${name}"`) !== -1) { log.error(`Cannot load browser "${name}": it is not registered! Perhaps you are missing some plugin?`) diff --git a/lib/launchers/base.js b/lib/launchers/base.js index 7a1c95ee3..865f86749 100644 --- a/lib/launchers/base.js +++ b/lib/launchers/base.js @@ -1,16 +1,16 @@ -var KarmaEventEmitter = require('../events').EventEmitter -var EventEmitter = require('events').EventEmitter -var Promise = require('bluebird') +const KarmaEventEmitter = require('../events').EventEmitter +const EventEmitter = require('events').EventEmitter +const Promise = require('bluebird') -var log = require('../logger').create('launcher') -var helper = require('../helper') +const log = require('../logger').create('launcher') +const helper = require('../helper') -var BEING_CAPTURED = 1 -var CAPTURED = 2 -var BEING_KILLED = 3 -var FINISHED = 4 -var RESTARTING = 5 -var BEING_FORCE_KILLED = 6 +const BEING_CAPTURED = 1 +const CAPTURED = 2 +const BEING_KILLED = 3 +const FINISHED = 4 +const RESTARTING = 5 +const BEING_FORCE_KILLED = 6 /** * Base launcher that any custom launcher extends. @@ -32,9 +32,9 @@ function BaseLauncher (id, emitter) { this.state = null this.error = null - var self = this - var killingPromise - var previousUrl + const self = this + let killingPromise + let previousUrl this.start = function (url) { previousUrl = url diff --git a/lib/launchers/capture_timeout.js b/lib/launchers/capture_timeout.js index d520fb57a..d195740c7 100644 --- a/lib/launchers/capture_timeout.js +++ b/lib/launchers/capture_timeout.js @@ -1,4 +1,4 @@ -var log = require('../logger').create('launcher') +const log = require('../logger').create('launcher') /** * Kill browser if it does not capture in given `captureTimeout`. @@ -8,8 +8,8 @@ function CaptureTimeoutLauncher (timer, captureTimeout) { return } - var self = this - var pendingTimeoutId = null + const self = this + let pendingTimeoutId = null this.on('start', function () { pendingTimeoutId = timer.setTimeout(function () { diff --git a/lib/launchers/process.js b/lib/launchers/process.js index 5975e5bf9..bc82d0cba 100644 --- a/lib/launchers/process.js +++ b/lib/launchers/process.js @@ -1,13 +1,13 @@ -var path = require('path') -var log = require('../logger').create('launcher') -var env = process.env +const path = require('path') +const log = require('../logger').create('launcher') +const env = process.env function ProcessLauncher (spawn, tempDir, timer, processKillTimeout) { - var self = this - var onExitCallback - var killTimeout = processKillTimeout || 2000 + const self = this + let onExitCallback + const killTimeout = processKillTimeout || 2000 // Will hold output from the spawned child process - var streamedOutputs = { + const streamedOutputs = { stdout: '', stderr: '' } @@ -74,7 +74,7 @@ function ProcessLauncher (spawn, tempDir, timer, processKillTimeout) { log.debug(cmd + ' ' + args.join(' ')) self._process = spawn(cmd, args) - var errorOutput = '' + let errorOutput = '' self._process.stdout.on('data', self._onStdout) @@ -102,7 +102,7 @@ function ProcessLauncher (spawn, tempDir, timer, processKillTimeout) { this._onProcessExit = function (code, errorOutput) { log.debug('Process %s exited with code %d', self.name, code) - var error = null + let error = null if (self.state === self.STATE_BEING_CAPTURED) { log.error('Cannot start %s\n\t%s', self.name, errorOutput) @@ -162,10 +162,10 @@ function ProcessLauncher (spawn, tempDir, timer, processKillTimeout) { ProcessLauncher.decoratorFactory = function (timer) { return function (launcher, processKillTimeout) { - var spawn = require('child_process').spawn + const spawn = require('child_process').spawn function spawnWithoutOutput () { - var proc = spawn.apply(null, arguments) + const proc = spawn.apply(null, arguments) proc.stdout.resume() proc.stderr.resume() diff --git a/lib/launchers/retry.js b/lib/launchers/retry.js index 257bde30a..646e90bd4 100644 --- a/lib/launchers/retry.js +++ b/lib/launchers/retry.js @@ -1,7 +1,7 @@ -var log = require('../logger').create('launcher') +const log = require('../logger').create('launcher') function RetryLauncher (retryLimit) { - var self = this + const self = this this._retryLimit = retryLimit @@ -11,7 +11,7 @@ function RetryLauncher (retryLimit) { } if (self._retryLimit > 0) { - var attempt = retryLimit - self._retryLimit + 1 + const attempt = retryLimit - self._retryLimit + 1 log.info('Trying to start %s again (%d/%d).', self.name, attempt, retryLimit) self.restart() self._retryLimit-- diff --git a/lib/logger.js b/lib/logger.js index 8c58ec22f..9ae3f48c8 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -4,9 +4,9 @@ // ### Helpers and Setup -var log4js = require('log4js') -var helper = require('./helper') -var constant = require('./constants') +let log4js = require('log4js') +const helper = require('./helper') +const constant = require('./constants') // #### Public Functions @@ -23,7 +23,7 @@ var constant = require('./constants') // *Array* is also accepted for backwards compatibility. function setup (level, colors, appenders) { // Turn color on/off on the console appenders with pattern layout - var pattern = colors ? constant.COLOR_PATTERN : constant.NO_COLOR_PATTERN + const pattern = colors ? constant.COLOR_PATTERN : constant.NO_COLOR_PATTERN if (appenders) { // Convert Array to Object for backwards compatibility. if (appenders['map']) { @@ -70,8 +70,8 @@ function setup (level, colors, appenders) { // see https://github.com/nomiddlename/log4js-node. // *Array* is also accepted for backwards compatibility. function setupFromConfig (config, appenders) { - var useColors = true - var logLevel = constant.LOG_INFO + let useColors = true + let logLevel = constant.LOG_INFO if (helper.isDefined(config.colors)) { useColors = config.colors @@ -92,7 +92,7 @@ const loggerCache = {} // * `level`, which defaults to the global level. function create (name, level) { name = name || 'karma' - var logger + let logger if (loggerCache.hasOwnProperty(name)) { logger = loggerCache[name] } else { diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index d47e898a0..32f6660d9 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -11,33 +11,33 @@ * - setting propert caching headers */ -var path = require('path') -var util = require('util') -var url = require('url') -var _ = require('lodash') +const path = require('path') +const util = require('util') +const url = require('url') +const _ = require('lodash') -var log = require('../logger').create('middleware:karma') -var stripHost = require('./strip_host').stripHost +const log = require('../logger').create('middleware:karma') +const stripHost = require('./strip_host').stripHost function urlparse (urlStr) { - var urlObj = url.parse(urlStr, true) + const urlObj = url.parse(urlStr, true) urlObj.query = urlObj.query || {} return urlObj } -var common = require('./common') +const common = require('./common') -var VERSION = require('../constants').VERSION -var SCRIPT_TAG = '' -var CROSSORIGIN_ATTRIBUTE = 'crossorigin="anonymous"' -var LINK_TAG_CSS = '' -var LINK_TAG_HTML = '' -var SCRIPT_TYPE = { +const VERSION = require('../constants').VERSION +const SCRIPT_TAG = '' +const CROSSORIGIN_ATTRIBUTE = 'crossorigin="anonymous"' +const LINK_TAG_CSS = '' +const LINK_TAG_HTML = '' +const SCRIPT_TYPE = { 'js': 'text/javascript', 'dart': 'application/dart', 'module': 'module' } -var FILE_TYPES = [ +const FILE_TYPES = [ 'css', 'html', 'js', @@ -54,8 +54,8 @@ function filePathToUrlPath (filePath, basePath, urlRoot, proxyPath) { } function getXUACompatibleMetaElement (url) { - var tag = '' - var urlObj = urlparse(url) + let tag = '' + const urlObj = urlparse(url) if (urlObj.query['x-ua-compatible']) { tag = '\n' @@ -64,8 +64,8 @@ function getXUACompatibleMetaElement (url) { } function getXUACompatibleUrl (url) { - var value = '' - var urlObj = urlparse(url) + let value = '' + const urlObj = urlparse(url) if (urlObj.query['x-ua-compatible']) { value = '?x-ua-compatible=' + encodeURIComponent(urlObj.query['x-ua-compatible']) } @@ -82,21 +82,21 @@ function createKarmaMiddleware ( upstreamProxy, browserSocketTimeout ) { - var proxyPath = upstreamProxy ? upstreamProxy.path : '/' + const proxyPath = upstreamProxy ? upstreamProxy.path : '/' return function (request, response, next) { // These config values should be up to date on every request - var client = injector.get('config.client') - var customContextFile = injector.get('config.customContextFile') - var customDebugFile = injector.get('config.customDebugFile') - var customClientContextFile = injector.get('config.customClientContextFile') - var includeCrossOriginAttribute = injector.get('config.crossOriginAttribute') + const client = injector.get('config.client') + const customContextFile = injector.get('config.customContextFile') + const customDebugFile = injector.get('config.customDebugFile') + const customClientContextFile = injector.get('config.customClientContextFile') + const includeCrossOriginAttribute = injector.get('config.crossOriginAttribute') - var normalizedUrl = stripHost(request.url) || request.url + const normalizedUrl = stripHost(request.url) || request.url // For backwards compatibility in middleware plugins, remove in v4. request.normalizedUrl = normalizedUrl - var requestUrl = normalizedUrl.replace(/\?.*/, '') - var requestedRangeHeader = request.headers['range'] + let requestUrl = normalizedUrl.replace(/\?.*/, '') + const requestedRangeHeader = request.headers['range'] // redirect /__karma__ to /__karma__ (trailing slash) if (requestUrl === urlRoot.substr(0, urlRoot.length - 1)) { @@ -128,8 +128,8 @@ function createKarmaMiddleware ( } // serve karma.js, context.js, and debug.js - var jsFiles = ['/karma.js', '/context.js', '/debug.js'] - var isRequestingJsFile = jsFiles.indexOf(requestUrl) !== -1 + const jsFiles = ['/karma.js', '/context.js', '/debug.js'] + const isRequestingJsFile = jsFiles.indexOf(requestUrl) !== -1 if (isRequestingJsFile) { return serveStaticFile(requestUrl, requestedRangeHeader, response, function (data) { return data.replace('%KARMA_URL_ROOT%', urlRoot) @@ -146,13 +146,13 @@ function createKarmaMiddleware ( // serve context.html - execution context within the iframe // or debug.html - execution context without channel to the server - var isRequestingContextFile = requestUrl === '/context.html' - var isRequestingDebugFile = requestUrl === '/debug.html' - var isRequestingClientContextFile = requestUrl === '/client_with_context.html' + const isRequestingContextFile = requestUrl === '/context.html' + const isRequestingDebugFile = requestUrl === '/debug.html' + const isRequestingClientContextFile = requestUrl === '/client_with_context.html' if (isRequestingContextFile || isRequestingDebugFile || isRequestingClientContextFile) { return filesPromise.then(function (files) { - var fileServer - var requestedFileUrl + let fileServer + let requestedFileUrl log.debug('custom files', customContextFile, customDebugFile, customClientContextFile) if (isRequestingContextFile && customContextFile) { log.debug('Serving customContextFile %s', customContextFile) @@ -175,13 +175,13 @@ function createKarmaMiddleware ( fileServer(requestedFileUrl, requestedRangeHeader, response, function (data) { common.setNoCacheHeaders(response) - var scriptTags = [] - var scriptUrls = [] - for (var i = 0; i < files.included.length; i++) { - var file = files.included[i] - var filePath = file.path - var fileExt = path.extname(filePath) - var fileType = file.type + const scriptTags = [] + const scriptUrls = [] + for (let i = 0; i < files.included.length; i++) { + const file = files.included[i] + let filePath = file.path + const fileExt = path.extname(filePath) + const fileType = file.type if (!files.included.hasOwnProperty(i)) { continue @@ -212,17 +212,17 @@ function createKarmaMiddleware ( } // The script tag to be placed - var scriptFileType = (fileType || fileExt.substring(1)) - var scriptType = (SCRIPT_TYPE[scriptFileType] || 'text/javascript') + const scriptFileType = (fileType || fileExt.substring(1)) + const scriptType = (SCRIPT_TYPE[scriptFileType] || 'text/javascript') - var crossOriginAttribute = includeCrossOriginAttribute ? CROSSORIGIN_ATTRIBUTE : '' + const crossOriginAttribute = includeCrossOriginAttribute ? CROSSORIGIN_ATTRIBUTE : '' scriptTags.push(util.format(SCRIPT_TAG, scriptType, filePath, crossOriginAttribute)) } // TODO(vojta): don't compute if it's not in the template - var mappings = files.served.map(function (file) { + let mappings = files.served.map(function (file) { // Windows paths contain backslashes and generate bad IDs if not escaped - var filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath).replace(/\\/g, '\\\\') + let filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath).replace(/\\/g, '\\\\') // Escape single quotes that might be in the filename - // double quotes should not be allowed! filePath = filePath.replace(/'/g, '\\\'') @@ -230,9 +230,9 @@ function createKarmaMiddleware ( return util.format(" '%s': '%s'", filePath, file.sha) }) - var clientConfig = 'window.__karma__.config = ' + JSON.stringify(client) + ';\n' + const clientConfig = 'window.__karma__.config = ' + JSON.stringify(client) + ';\n' - var scriptUrlsJS = 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n' + const scriptUrlsJS = 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n' mappings = 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n' diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index d493b2e3c..f1ced1373 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -1,8 +1,8 @@ -var url = require('url') -var httpProxy = require('http-proxy') -var _ = require('lodash') +const url = require('url') +const httpProxy = require('http-proxy') +const _ = require('lodash') -var log = require('../logger').create('proxy') +const log = require('../logger').create('proxy') function parseProxyConfig (proxies, config) { function endsWithSlash (str) { @@ -17,9 +17,9 @@ function parseProxyConfig (proxies, config) { if (typeof proxyConfiguration === 'string') { proxyConfiguration = {target: proxyConfiguration} } - var proxyUrl = proxyConfiguration.target - var proxyDetails = url.parse(proxyUrl) - var pathname = proxyDetails.pathname + let proxyUrl = proxyConfiguration.target + const proxyDetails = url.parse(proxyUrl) + let pathname = proxyDetails.pathname // normalize the proxies config // should we move this to lib/config.js ? @@ -38,10 +38,10 @@ function parseProxyConfig (proxies, config) { pathname = '' } - var hostname = proxyDetails.hostname || config.hostname - var protocol = proxyDetails.protocol || config.protocol - var https = proxyDetails.protocol === 'https:' - var port + const hostname = proxyDetails.hostname || config.hostname + const protocol = proxyDetails.protocol || config.protocol + const https = proxyDetails.protocol === 'https:' + let port if (proxyDetails.port) { port = proxyDetails.port } else if (proxyDetails.protocol) { @@ -49,8 +49,8 @@ function parseProxyConfig (proxies, config) { } else { port = config.port } - var changeOrigin = 'changeOrigin' in proxyConfiguration ? proxyConfiguration.changeOrigin : false - var proxy = httpProxy.createProxyServer({ + const changeOrigin = 'changeOrigin' in proxyConfiguration ? proxyConfiguration.changeOrigin : false + const proxy = httpProxy.createProxyServer({ target: { host: hostname, port: port, @@ -63,7 +63,7 @@ function parseProxyConfig (proxies, config) { }) ;['proxyReq', 'proxyRes'].forEach(function (name) { - var callback = proxyDetails[name] || config[name] + const callback = proxyDetails[name] || config[name] if (callback) { proxy.on(name, callback) } @@ -106,7 +106,7 @@ function createProxyHandler (proxies, urlRoot) { } function createProxy (request, response, next) { - var proxyRecord = _.find(proxies, function (p) { + const proxyRecord = _.find(proxies, function (p) { return request.url.indexOf(p.path) === 0 }) @@ -126,7 +126,7 @@ function createProxyHandler (proxies, urlRoot) { return } - var proxyRecord = _.find(proxies, function (p) { + const proxyRecord = _.find(proxies, function (p) { return request.url.indexOf(p.path) === 0 }) diff --git a/lib/middleware/runner.js b/lib/middleware/runner.js index a78134dbf..394c3d3e1 100644 --- a/lib/middleware/runner.js +++ b/lib/middleware/runner.js @@ -4,12 +4,12 @@ * It basically triggers a test run and streams stdout back. */ -var _ = require('lodash') -var path = require('path') -var helper = require('../helper') -var log = require('../logger').create() -var constant = require('../constants') -var json = require('body-parser').json() +const _ = require('lodash') +const path = require('path') +const helper = require('../helper') +const log = require('../logger').create() +const constant = require('../constants') +const json = require('body-parser').json() // TODO(vojta): disable when single-run mode function createRunnerMiddleware (emitter, fileList, capturedBrowsers, reporter, executor, @@ -25,8 +25,7 @@ function createRunnerMiddleware (emitter, fileList, capturedBrowsers, reporter, response.writeHead(200) if (!capturedBrowsers.length) { - var url = protocol + '//' + hostname + ':' + port + urlRoot - + const url = `${protocol}//${hostname}:${port}${urlRoot}` return response.end('No captured browser, open ' + url + '\n') } @@ -35,16 +34,16 @@ function createRunnerMiddleware (emitter, fileList, capturedBrowsers, reporter, response.write('Waiting for previous execution...\n') } - var data = request.body + const data = request.body emitter.once('run_start', function () { - var responseWrite = response.write.bind(response) + const responseWrite = response.write.bind(response) responseWrite.colors = data.colors reporter.addAdapter(responseWrite) // clean up, close runner response emitter.once('run_complete', function (browsers, results) { reporter.removeAdapter(responseWrite) - var emptyTestSuite = (results.failed + results.success) === 0 ? 0 : 1 + const emptyTestSuite = (results.failed + results.success) === 0 ? 0 : 1 response.end(constant.EXIT_CODE + emptyTestSuite + results.exitCode) }) }) @@ -61,7 +60,7 @@ function createRunnerMiddleware (emitter, fileList, capturedBrowsers, reporter, config.client.args = data.args } - var fullRefresh = true + let fullRefresh = true if (helper.isArray(data.changedFiles)) { data.changedFiles.forEach(function (filepath) { diff --git a/lib/middleware/stopper.js b/lib/middleware/stopper.js index 97d8c7523..784a7d443 100644 --- a/lib/middleware/stopper.js +++ b/lib/middleware/stopper.js @@ -2,7 +2,7 @@ * Stopper middleware is responsible for communicating with `karma stop`. */ -var log = require('../logger').create('middleware:stopper') +const log = require('../logger').create('middleware:stopper') function createStopperMiddleware (urlRoot) { return function (request, response, next) { diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 0728ecac1..713a04b06 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -89,7 +89,7 @@ function createPreprocessor (config, basePath, injector) { throw err } - var preprocessorNames = [] + let preprocessorNames = [] patterns.forEach((pattern) => { if (mm(file.originalPath, pattern, {dot: true})) { preprocessorNames = combineLists(preprocessorNames, config[pattern]) diff --git a/lib/reporter.js b/lib/reporter.js index 8b70f288c..925b12d41 100644 --- a/lib/reporter.js +++ b/lib/reporter.js @@ -47,7 +47,7 @@ function createErrorFormatter (config, emitter, SourceMapConsumer) { input = JSON.stringify(input, null, indentation) } - var msg = input.replace(URL_REGEXP, function (_, prefix, path, __, ___, line, ____, column) { + let msg = input.replace(URL_REGEXP, function (_, prefix, path, __, ___, line, ____, column) { const normalizedPath = prefix === 'base/' ? `${basePath}/${path}` : path const file = lastServedFiles.find((file) => file.path === normalizedPath) diff --git a/lib/reporters/dots.js b/lib/reporters/dots.js index 4a5dd84f1..2adc76006 100644 --- a/lib/reporters/dots.js +++ b/lib/reporters/dots.js @@ -1,9 +1,9 @@ -var BaseReporter = require('./base') +const BaseReporter = require('./base') function DotsReporter (formatError, reportSlow, useColors, browserConsoleLogOptions) { BaseReporter.call(this, formatError, reportSlow, useColors, browserConsoleLogOptions) - var DOTS_WRAP = 80 + const DOTS_WRAP = 80 this.EXCLUSIVELY_USE_COLORS = false this.onRunStart = function () { this._browsers = [] diff --git a/lib/reporters/dots_color.js b/lib/reporters/dots_color.js index 331bfe7a0..4a8924e79 100644 --- a/lib/reporters/dots_color.js +++ b/lib/reporters/dots_color.js @@ -1,5 +1,5 @@ -var DotsReporter = require('./dots') -var BaseColorReporter = require('./base_color') +const DotsReporter = require('./dots') +const BaseColorReporter = require('./base_color') function DotsColorReporter (formatError, reportSlow, useColors, browserConsoleLogOptions) { DotsReporter.call(this, formatError, reportSlow, useColors, browserConsoleLogOptions) diff --git a/lib/reporters/progress.js b/lib/reporters/progress.js index 1f99928f6..9e0f62510 100644 --- a/lib/reporters/progress.js +++ b/lib/reporters/progress.js @@ -1,4 +1,4 @@ -var BaseReporter = require('./base') +const BaseReporter = require('./base') function ProgressReporter (formatError, reportSlow, useColors, browserConsoleLogOptions) { BaseReporter.call(this, formatError, reportSlow, useColors, browserConsoleLogOptions) @@ -38,7 +38,7 @@ function ProgressReporter (formatError, reportSlow, useColors, browserConsoleLog return '' } - var cmd = '' + let cmd = '' this._browsers.forEach(function () { cmd += '\x1B[1A' + '\x1B[2K' }) diff --git a/lib/reporters/progress_color.js b/lib/reporters/progress_color.js index 572f2fa43..78a460f3b 100644 --- a/lib/reporters/progress_color.js +++ b/lib/reporters/progress_color.js @@ -1,5 +1,5 @@ -var ProgressReporter = require('./progress') -var BaseColorReporter = require('./base_color') +const ProgressReporter = require('./progress') +const BaseColorReporter = require('./base_color') function ProgressColorReporter (formatError, reportSlow, useColors, browserConsoleLogOptions) { ProgressReporter.call(this, formatError, reportSlow, useColors, browserConsoleLogOptions) diff --git a/lib/stopper.js b/lib/stopper.js index 3f0d72cfc..8b8ee0d57 100644 --- a/lib/stopper.js +++ b/lib/stopper.js @@ -1,24 +1,24 @@ -var http = require('http') +const http = require('http') -var cfg = require('./config') -var logger = require('./logger') -var helper = require('./helper') +const cfg = require('./config') +const logger = require('./logger') +const helper = require('./helper') exports.stop = function (config, done) { config = config || {} logger.setupFromConfig(config) done = helper.isFunction(done) ? done : process.exit - var log = logger.create('stopper') + const log = logger.create('stopper') config = cfg.parseConfig(config.configFile, config) - var options = { + const options = { hostname: config.hostname, path: config.urlRoot + 'stop', port: config.port, method: 'GET' } - var request = http.request(options) + const request = http.request(options) request.on('response', function (response) { if (response.statusCode !== 200) { diff --git a/tasks/init-dev-env.js b/tasks/init-dev-env.js index 86d2fcab7..adf0bf948 100644 --- a/tasks/init-dev-env.js +++ b/tasks/init-dev-env.js @@ -5,8 +5,8 @@ module.exports = function (grunt) { * - register git hooks (commit-msg) */ grunt.registerTask('init-dev-env', 'Initialize dev environment.', function () { - var fs = require('fs') - var done = this.async() + const fs = require('fs') + const done = this.async() fs.symlink('../../tasks/lib/validate-commit-msg.js', '.git/hooks/commit-msg', function (e) { if (!e) { diff --git a/tasks/test.js b/tasks/test.js index 9a2dd3a56..e999425f7 100644 --- a/tasks/test.js +++ b/tasks/test.js @@ -7,10 +7,10 @@ module.exports = function (grunt) { * grunt test:client */ grunt.registerMultiTask('test', 'Run tests.', function () { - var specDone = this.async() - var node = require('which').sync('node') - var path = require('path') - var cmd = path.join(__dirname, '..', 'bin', 'karma') + const specDone = this.async() + const node = require('which').sync('node') + const path = require('path') + const cmd = path.join(__dirname, '..', 'bin', 'karma') function spawnKarma (args, callback) { grunt.log.writeln(['Running', cmd].concat(args).join(' ')) diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index 4422ca7cb..4536e62e5 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -1,6 +1,6 @@ -var TRAVIS_WITHOUT_BS = process.env.TRAVIS_SECURE_ENV_VARS === 'false' +const TRAVIS_WITHOUT_BS = process.env.TRAVIS_SECURE_ENV_VARS === 'false' -var launchers = { +const launchers = { bs_chrome: { base: 'BrowserStack', browser: 'chrome', @@ -59,7 +59,7 @@ var launchers = { // } } -var browsers = [] +let browsers = [] if (process.env.TRAVIS) { if (TRAVIS_WITHOUT_BS) { diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index 776d1da06..13bd441ec 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -1,15 +1,15 @@ // shim all the things require('core-js/es5') global.JSON = require('json3') -var sinon = require('sinon') -var assert = require('assert') +const sinon = require('sinon') +const assert = require('assert') -var ClientKarma = require('../../client/karma') -var ContextKarma = require('../../context/karma') -var MockSocket = require('./mocks').Socket +const ClientKarma = require('../../client/karma') +const ContextKarma = require('../../context/karma') +const MockSocket = require('./mocks').Socket describe('Karma', function () { - var socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow + let socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow function setTransportTo (transportName) { socket._setTransportNameTo(transportName) @@ -33,7 +33,7 @@ describe('Karma', function () { }) it('should start execution when all files loaded and pass config', function () { - var config = ck.config = { + const config = ck.config = { useIframe: true } @@ -45,7 +45,7 @@ describe('Karma', function () { }) it('should open a new window when useIFrame is false', function () { - var config = ck.config = { + const config = ck.config = { useIframe: false, runInParent: false } @@ -85,13 +85,13 @@ describe('Karma', function () { }) it('should not set up context if there was an error', function () { - var config = ck.config = { + const config = ck.config = { clearContext: true } socket.emit('execute', config) - var mockWindow = {} + const mockWindow = {} ck.error('page reload') ck.setupContext(mockWindow) @@ -101,13 +101,13 @@ describe('Karma', function () { }) it('should setup context if there was error but clearContext config is false', function () { - var config = ck.config = { + const config = ck.config = { clearContext: false } socket.emit('execute', config) - var mockWindow = {} + const mockWindow = {} ck.error('page reload') ck.setupContext(mockWindow) @@ -118,11 +118,11 @@ describe('Karma', function () { it('should error out if a script attempted to reload the browser after setup', function () { // Perform setup - var config = ck.config = { + const config = ck.config = { clearContext: true } socket.emit('execute', config) - var mockWindow = {} + const mockWindow = {} ck.setupContext(mockWindow) // Spy on our error handler @@ -136,7 +136,7 @@ describe('Karma', function () { }) it('should report navigator name', function () { - var spyInfo = sinon.spy(function (info) { + const spyInfo = sinon.spy(function (info) { assert(info.name === 'Fake browser name') }) @@ -153,7 +153,7 @@ describe('Karma', function () { socket = new MockSocket() k = new ClientKarma(socket, {}, windowStub, windowNavigator, windowLocation) - var spyInfo = sinon.spy(function (info) { + const spyInfo = sinon.spy(function (info) { assert(info.id === '567') }) @@ -165,13 +165,13 @@ describe('Karma', function () { describe('result', function () { it('should buffer results when polling', function () { - var spyResult = sinon.stub() + const spyResult = sinon.stub() socket.on('result', spyResult) setTransportTo('polling') // emit 49 results - for (var i = 1; i < 50; i++) { + for (let i = 1; i < 50; i++) { ck.result({id: i}) } @@ -183,13 +183,13 @@ describe('Karma', function () { }) it('should buffer results when polling', function () { - var spyResult = sinon.stub() + const spyResult = sinon.stub() socket.on('result', spyResult) setTransportTo('polling') // emit 40 results - for (var i = 1; i <= 40; i++) { + for (let i = 1; i <= 40; i++) { ck.result({id: i}) } @@ -199,7 +199,7 @@ describe('Karma', function () { }) it('should emit "start" with total specs count first', function () { - var log = [] + const log = [] socket.on('result', function () { log.push('result') @@ -217,13 +217,13 @@ describe('Karma', function () { }) it('should not emit "start" if already done by the adapter', function () { - var log = [] + const log = [] - var spyStart = sinon.spy(function () { + const spyStart = sinon.spy(function () { log.push('start') }) - var spyResult = sinon.spy(function () { + const spyResult = sinon.spy(function () { log.push('result') }) @@ -243,7 +243,7 @@ describe('Karma', function () { it('should capture alert', function () { sinon.spy(ck, 'log') - var mockWindow = { + const mockWindow = { alert: function () { throw new Error('Alert was not patched!') } @@ -256,9 +256,9 @@ describe('Karma', function () { it('should capture confirm', function () { sinon.spy(ck, 'log') - var confirmCalled = false + let confirmCalled = false - var mockWindow = { + const mockWindow = { confirm: function () { confirmCalled = true return true @@ -266,7 +266,7 @@ describe('Karma', function () { } ck.setupContext(mockWindow) - var confirmResult = mockWindow.confirm('What?') + const confirmResult = mockWindow.confirm('What?') assert(ck.log.calledWith('confirm', ['What?'])) assert.equal(confirmCalled, true) assert.equal(confirmResult, true) @@ -274,9 +274,9 @@ describe('Karma', function () { it('should capture prompt', function () { sinon.spy(ck, 'log') - var promptCalled = false + let promptCalled = false - var mockWindow = { + const mockWindow = { prompt: function () { promptCalled = true return 'user-input' @@ -284,7 +284,7 @@ describe('Karma', function () { } ck.setupContext(mockWindow) - var promptResult = mockWindow.prompt('What is your favorite color?', 'blue') + const promptResult = mockWindow.prompt('What is your favorite color?', 'blue') assert(ck.log.calledWith('prompt', ['What is your favorite color?', 'blue'])) assert.equal(promptCalled, true) assert.equal(promptResult, 'user-input') @@ -292,7 +292,7 @@ describe('Karma', function () { }) describe('complete', function () { - var clock + let clock before(function () { clock = sinon.useFakeTimers() @@ -303,13 +303,13 @@ describe('Karma', function () { }) it('should clean the result buffer before completing', function () { - var spyResult = sinon.stub() + const spyResult = sinon.stub() socket.on('result', spyResult) setTransportTo('polling') // emit 40 results - for (var i = 0; i < 40; i++) { + for (let i = 0; i < 40; i++) { ck.result({id: i}) } @@ -347,7 +347,7 @@ describe('Karma', function () { sinon.spy(ck, 'log') ck.config.captureConsole = true - var mockWindow = { + const mockWindow = { console: { log: function () {} } @@ -363,7 +363,7 @@ describe('Karma', function () { sinon.spy(ck, 'log') ck.config.captureConsole = false - var mockWindow = { + const mockWindow = { console: { log: function () {} } @@ -375,12 +375,12 @@ describe('Karma', function () { }) it('should clear context window upon complete when clearContext config is true', function () { - var config = ck.config = { + const config = ck.config = { clearContext: true } socket.emit('execute', config) - var CURRENT_URL = iframe.src + const CURRENT_URL = iframe.src ck.complete() @@ -392,12 +392,12 @@ describe('Karma', function () { }) it('should not clear context window upon complete when clearContext config is false', function () { - var config = ck.config = { + const config = ck.config = { clearContext: false } socket.emit('execute', config) - var CURRENT_URL = iframe.src + const CURRENT_URL = iframe.src ck.complete() diff --git a/test/client/mocks.js b/test/client/mocks.js index f49357d21..5239acca8 100644 --- a/test/client/mocks.js +++ b/test/client/mocks.js @@ -1,5 +1,5 @@ function Emitter () { - var listeners = {} + const listeners = {} this.on = function (event, fn) { if (!listeners[event]) { @@ -10,11 +10,11 @@ function Emitter () { } this.emit = function (event) { - var eventListeners = listeners[event] + const eventListeners = listeners[event] if (!eventListeners) return - var i = 0 + let i = 0 while (i < eventListeners.length) { eventListeners[i].apply(null, Array.prototype.slice.call(arguments, 1)) i++ @@ -27,7 +27,7 @@ function MockSocket () { this.socket = {transport: {name: 'websocket'}} - var transportName = 'websocket' + let transportName = 'websocket' this.io = { engine: { diff --git a/test/client/stringify.spec.js b/test/client/stringify.spec.js index aaeea7dd0..01f57ff65 100644 --- a/test/client/stringify.spec.js +++ b/test/client/stringify.spec.js @@ -1,7 +1,7 @@ /* global __karma__ */ -var assert = require('assert') +const assert = require('assert') -var stringify = require('../../common/stringify') +const stringify = require('../../common/stringify') describe('stringify', function () { if (window && window.Symbol) { @@ -30,15 +30,15 @@ describe('stringify', function () { function abc (a, b, c) { return 'whatever' } function def (d, e, f) { return 'whatever' } - var abcString = stringify(abc) - var partsAbc = ['function', 'abc', '(a, b, c)', '{ ... }'] - var partsDef = ['function', '(d, e, f)', '{ ... }'] + const abcString = stringify(abc) + const partsAbc = ['function', 'abc', '(a, b, c)', '{ ... }'] + const partsDef = ['function', '(d, e, f)', '{ ... }'] partsAbc.forEach(function (part) { assert(abcString.indexOf(part) > -1) }) - var defString = stringify(def) + const defString = stringify(def) partsDef.forEach(function (part) { assert(defString.indexOf(part) > -1) }) @@ -48,7 +48,7 @@ describe('stringify', function () { // http://caniuse.com/#feat=proxy if (window.Proxy) { it('should serialize proxied functions', function () { - var defProxy = new Proxy(function (d, e, f) { return 'whatever' }, {}) + const defProxy = new Proxy(function (d, e, f) { return 'whatever' }, {}) assert.deepEqual(stringify(defProxy), 'function () { ... }') }) } @@ -58,7 +58,7 @@ describe('stringify', function () { }) it('should serialize objects', function () { - var obj + let obj obj = {a: 'a', b: 'b', c: null, d: true, e: false} assert(stringify(obj).indexOf("{a: 'a', b: 'b', c: null, d: true, e: false}") > -1) @@ -73,7 +73,7 @@ describe('stringify', function () { obj = {constructor: null} // IE 7 serializes this to Object{} - var s = stringify(obj) + const s = stringify(obj) assert(s.indexOf('{constructor: null}') > -1 || s.indexOf('Object{}') > -1) obj = Object.create(null) @@ -83,7 +83,7 @@ describe('stringify', function () { }) it('should serialize html', function () { - var div = document.createElement('div') + const div = document.createElement('div') assert.deepEqual(stringify(div).trim().toLowerCase(), '
    ') @@ -92,21 +92,21 @@ describe('stringify', function () { }) it('should serialize error', function () { - var error = new TypeError('Error description') + const error = new TypeError('Error description') assert(stringify(error).indexOf('Error description') > -1) }) it('should serialize DOMParser objects', function () { if (typeof DOMParser !== 'undefined') { // Test only works in IE 9 and above - var parser = new DOMParser() - var doc = parser.parseFromString('', 'application/xml') + const parser = new DOMParser() + const doc = parser.parseFromString('', 'application/xml') assert.deepEqual(stringify(doc), '') } }) it('should serialize across iframes', function () { - var div = document.createElement('div') + const div = document.createElement('div') assert.deepEqual(__karma__.stringify(div).trim().toLowerCase(), '
    ') assert.deepEqual(__karma__.stringify([1, 2]), '[1, 2]') diff --git a/test/client/util.spec.js b/test/client/util.spec.js index 035ffc49b..1d2377c05 100644 --- a/test/client/util.spec.js +++ b/test/client/util.spec.js @@ -1,10 +1,9 @@ -var assert = require('assert') - -var util = require('../../common/util') +const assert = require('assert') +const util = require('../../common/util') describe('util', function () { it('parseQueryParams', function () { - var params = util.parseQueryParams('?id=123&return_url=http://whatever.com') + const params = util.parseQueryParams('?id=123&return_url=http://whatever.com') assert.deepEqual(params, {id: '123', return_url: 'http://whatever.com'}) }) diff --git a/test/e2e/step_definitions/core_steps.js b/test/e2e/step_definitions/core_steps.js index 8c7ca3025..420a38551 100644 --- a/test/e2e/step_definitions/core_steps.js +++ b/test/e2e/step_definitions/core_steps.js @@ -1,23 +1,23 @@ -var cucumber = require('cucumber') -var fs = require('fs') -var path = require('path') -var ref = require('child_process') -var exec = ref.exec -var spawn = ref.spawn -var rimraf = require('rimraf') -var stopper = require('../../../lib/stopper') +const cucumber = require('cucumber') +const fs = require('fs') +const path = require('path') +const ref = require('child_process') +const exec = ref.exec +const spawn = ref.spawn +const rimraf = require('rimraf') +const stopper = require('../../../lib/stopper') cucumber.defineSupportCode((a) => { - var When = a.When - var Then = a.Then - var Given = a.Given - var defineParameterType = a.defineParameterType + const When = a.When + const Then = a.Then + const Given = a.Given + const defineParameterType = a.defineParameterType - var baseDir = fs.realpathSync(path.join(__dirname, '/../../..')) - var tmpDir = path.join(baseDir, 'tmp', 'sandbox') - var tmpConfigFile = 'karma.conf.js' - var cleansingNeeded = true - var additionalArgs = [] + const baseDir = fs.realpathSync(path.join(__dirname, '/../../..')) + const tmpDir = path.join(baseDir, 'tmp', 'sandbox') + const tmpConfigFile = 'karma.conf.js' + let cleansingNeeded = true + let additionalArgs = [] function cleanseIfNeeded () { if (cleansingNeeded) { @@ -35,7 +35,7 @@ cucumber.defineSupportCode((a) => { function execKarma (command, level, proxyPort, proxyPath, callback) { level = level || 'warn' - var startProxy = (done) => { + const startProxy = (done) => { if (proxyPort) { this.proxy.start(proxyPort, proxyPath, done) } else { @@ -52,21 +52,21 @@ cucumber.defineSupportCode((a) => { if (err) { return callback.fail(new Error(err)) } - var configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) - var runtimePath = path.join(baseDir, 'bin', 'karma') + const configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) + const runtimePath = path.join(baseDir, 'bin', 'karma') - var executor = (done) => { - var cmd = runtimePath + ' ' + command + ' --log-level ' + level + ' ' + configFile + ' ' + additionalArgs + const executor = (done) => { + const cmd = runtimePath + ' ' + command + ' --log-level ' + level + ' ' + configFile + ' ' + additionalArgs return exec(cmd, { cwd: baseDir }, done) } - var runOut = command === 'runOut' + const runOut = command === 'runOut' if (command === 'run' || command === 'runOut') { this.child = spawn('' + runtimePath, ['start', '--log-level', 'warn', configFile]) - var done = () => { + const done = () => { cleansingNeeded = true this.child && this.child.kill() callback() @@ -83,7 +83,7 @@ cucumber.defineSupportCode((a) => { this.child.stdout.on('data', (chunk) => { this.lastRun.stdout += chunk.toString() - var cmd = runtimePath + ' run ' + configFile + ' ' + additionalArgs + const cmd = runtimePath + ' run ' + configFile + ' ' + additionalArgs setTimeout(() => { exec(cmd, { cwd: baseDir @@ -125,7 +125,7 @@ cucumber.defineSupportCode((a) => { }) When('I stop a server programmatically', function (callback) { - var _this = this + const _this = this setTimeout(function () { stopper.stop(_this.configFile, function (exitCode) { _this.stopperExitCode = exitCode @@ -140,8 +140,8 @@ cucumber.defineSupportCode((a) => { if (err) { return callback.fail(new Error(err)) } - var configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) - var runtimePath = path.join(baseDir, 'bin', 'karma') + const configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) + const runtimePath = path.join(baseDir, 'bin', 'karma') _this.child = spawn('' + runtimePath, ['start', '--log-level', 'debug', configFile]) _this.child.stdout.on('data', function () { callback() @@ -183,10 +183,10 @@ cucumber.defineSupportCode((a) => { }) Then('it passes with( {exact}):', {timeout: 10 * 1000}, function (mode, expectedOutput, callback) { - var noDebug = mode === 'no debug' - var like = mode === 'like' - var actualOutput = this.lastRun.stdout.toString() - var lines + const noDebug = mode === 'no debug' + const like = mode === 'like' + let actualOutput = this.lastRun.stdout.toString() + let lines if (noDebug) { lines = actualOutput.split('\n').filter(function (line) { @@ -210,9 +210,9 @@ cucumber.defineSupportCode((a) => { }) Then('it fails with:', function (expectedOutput, callback) { - var actualOutput = this.lastRun.stdout.toString() - var actualError = this.lastRun.error - var actualStderr = this.lastRun.stderr.toString() + const actualOutput = this.lastRun.stdout.toString() + const actualError = this.lastRun.error + const actualStderr = this.lastRun.stderr.toString() if (actualOutput.match(expectedOutput)) { return callback() @@ -224,9 +224,9 @@ cucumber.defineSupportCode((a) => { }) Then('it fails with like:', function (expectedOutput, callback) { - var actualOutput = this.lastRun.stdout.toString() - var actualError = this.lastRun.error - var actualStderr = this.lastRun.stderr.toString() + const actualOutput = this.lastRun.stdout.toString() + const actualError = this.lastRun.error + const actualStderr = this.lastRun.stderr.toString() if (actualOutput.match(new RegExp(expectedOutput))) { return callback() } @@ -243,10 +243,10 @@ cucumber.defineSupportCode((a) => { Then('The {component} is dead( with exit code {int})', function (stopperOrServer, code, callback) { - var server = stopperOrServer === 'server' - var _this = this + const server = stopperOrServer === 'server' + const _this = this setTimeout(function () { - var actualExitCode = server ? _this.childExitCode : _this.stopperExitCode + const actualExitCode = server ? _this.childExitCode : _this.stopperExitCode if (actualExitCode === undefined) return callback(new Error('Server has not exited.')) if (code === undefined || parseInt(code, 10) === actualExitCode) return callback() callback(new Error('Exit-code mismatch')) @@ -255,7 +255,7 @@ cucumber.defineSupportCode((a) => { Then(/^the file at ([a-zA-Z0-9/\\_.]+) contains:$/, function (filePath, expectedOutput, callback) { - var data = fs.readFileSync(filePath, {encoding: 'UTF-8'}) + const data = fs.readFileSync(filePath, {encoding: 'UTF-8'}) if (data.match(expectedOutput)) { return callback() } diff --git a/test/e2e/step_definitions/hooks.js b/test/e2e/step_definitions/hooks.js index 48e0e30ad..21a04481e 100644 --- a/test/e2e/step_definitions/hooks.js +++ b/test/e2e/step_definitions/hooks.js @@ -1,8 +1,8 @@ -var cucumber = require('cucumber') +const cucumber = require('cucumber') cucumber.defineSupportCode((a) => { a.After(function (scenario, callback) { - var running = this.child != null && typeof this.child.kill === 'function' + const running = this.child != null && typeof this.child.kill === 'function' if (running) { this.child.kill() diff --git a/test/e2e/support/env.js b/test/e2e/support/env.js index 566e5e7cb..960cc6def 100644 --- a/test/e2e/support/env.js +++ b/test/e2e/support/env.js @@ -1,4 +1,4 @@ -var cucumber = require('cucumber') +const cucumber = require('cucumber') cucumber.defineSupportCode((a) => { a.setDefaultTimeout(60 * 1000) diff --git a/test/e2e/support/headers/test.js b/test/e2e/support/headers/test.js index 99e6ca581..be92bce00 100644 --- a/test/e2e/support/headers/test.js +++ b/test/e2e/support/headers/test.js @@ -1,5 +1,5 @@ function httpGet (url) { - var xmlHttp = new XMLHttpRequest() + const xmlHttp = new XMLHttpRequest() xmlHttp.open('GET', url, false) xmlHttp.send(null) diff --git a/test/e2e/support/middleware/test.js b/test/e2e/support/middleware/test.js index e07bca3b9..03cfbeddf 100644 --- a/test/e2e/support/middleware/test.js +++ b/test/e2e/support/middleware/test.js @@ -1,5 +1,5 @@ function httpGet (url) { - var xmlHttp = new XMLHttpRequest() + const xmlHttp = new XMLHttpRequest() xmlHttp.open('GET', url, false) xmlHttp.send(null) diff --git a/test/e2e/support/proxy.js b/test/e2e/support/proxy.js index 3a92e65c9..4a5757ca0 100644 --- a/test/e2e/support/proxy.js +++ b/test/e2e/support/proxy.js @@ -1,8 +1,8 @@ -var http = require('http') -var httpProxy = require('http-proxy') +const http = require('http') +const httpProxy = require('http-proxy') function Proxy () { - var self = this + const self = this self.running = false self.proxy = httpProxy.createProxyServer({ @@ -10,8 +10,8 @@ function Proxy () { }) self.server = http.createServer(function (req, res) { - var url = req.url - var match = url.match(self.proxyPathRegExp) + const url = req.url + const match = url.match(self.proxyPathRegExp) if (match) { req.url = '/' + match[1] self.proxy.web(req, res) diff --git a/test/e2e/support/proxy/test.js b/test/e2e/support/proxy/test.js index c8222c4be..42d8a782a 100644 --- a/test/e2e/support/proxy/test.js +++ b/test/e2e/support/proxy/test.js @@ -1,5 +1,5 @@ function httpGet (url) { - var xmlHttp = new XMLHttpRequest() + const xmlHttp = new XMLHttpRequest() xmlHttp.open('GET', url, false) xmlHttp.send(null) diff --git a/test/e2e/support/tag/tag.js b/test/e2e/support/tag/tag.js index 3f6b239c2..bef23803a 100644 --- a/test/e2e/support/tag/tag.js +++ b/test/e2e/support/tag/tag.js @@ -4,8 +4,8 @@ function isFirefoxBefore59 () { } function containsJsTag () { - var scripts = document.getElementsByTagName('script') - for (var i = 0; i < scripts.length; i++) { + const scripts = document.getElementsByTagName('script') + for (let i = 0; i < scripts.length; i++) { if (scripts[i].type.indexOf(';version=') > -1) { return true } diff --git a/test/e2e/support/world.js b/test/e2e/support/world.js index 69d28c185..1969e7b17 100644 --- a/test/e2e/support/world.js +++ b/test/e2e/support/world.js @@ -1,10 +1,10 @@ -var fs = require('fs') -var vm = require('vm') -var path = require('path') -var hasher = require('crypto').createHash -var mkdirp = require('mkdirp') -var _ = require('lodash') -var cucumber = require('cucumber') +const fs = require('fs') +const vm = require('vm') +const path = require('path') +const hasher = require('crypto').createHash +const mkdirp = require('mkdirp') +const _ = require('lodash') +const cucumber = require('cucumber') function World () { this.proxy = require('./proxy') @@ -35,7 +35,7 @@ function World () { this.writeConfigFile = (function (_this) { return function (dir, file, done) { return mkdirp(dir, 0x1ed, function (err) { - var content, hash + let content, hash if (err) { return done(err) } diff --git a/test/unit/events.spec.js b/test/unit/events.spec.js index 673b97e3f..8a604cebb 100644 --- a/test/unit/events.spec.js +++ b/test/unit/events.spec.js @@ -1,7 +1,7 @@ const e = require('../../lib/events') describe('events', () => { - var emitter + let emitter beforeEach(() => { emitter = new e.EventEmitter() @@ -9,7 +9,7 @@ describe('events', () => { describe('EventEmitter', () => { it('should emit events', () => { - var spy = sinon.spy() + const spy = sinon.spy() emitter.on('abc', spy) emitter.emit('abc') @@ -17,7 +17,7 @@ describe('events', () => { }) describe('bind', () => { - var object = null + let object = null beforeEach(() => { // Note: es6 class instances have non-enumerable prototype properties. @@ -66,7 +66,7 @@ describe('events', () => { }) describe('emitAsync', () => { - var object = null + let object = null beforeEach(() => { object = sinon.stub({ @@ -79,14 +79,14 @@ describe('events', () => { }) it('should resolve the promise once all listeners are done', (done) => { - var callbacks = [] - var eventDone = sinon.spy() + const callbacks = [] + const eventDone = sinon.spy() emitter.on('a', (d) => d()) emitter.on('a', (d) => callbacks.push(d)) emitter.on('a', (d) => callbacks.push(d)) - var promise = emitter.emitAsync('a') + const promise = emitter.emitAsync('a') expect(eventDone).not.to.have.been.called callbacks.pop()() @@ -101,7 +101,7 @@ describe('events', () => { }) it('should resolve asynchronously when no listener', (done) => { - var spyDone = sinon.spy(done) + const spyDone = sinon.spy(done) emitter.emitAsync('whatever').then(spyDone) expect(spyDone).to.not.have.been.called }) @@ -110,7 +110,7 @@ describe('events', () => { describe('bindAll', () => { it('should take emitter as second argument', () => { - var object = sinon.stub({onFoo: () => {}}) + const object = sinon.stub({onFoo: () => {}}) emitter.bind(object) emitter.emit('foo') @@ -120,7 +120,7 @@ describe('events', () => { }) it('should append "context" to event arguments', () => { - var object = sinon.stub({onFoo: () => {}}) + const object = sinon.stub({onFoo: () => {}}) emitter.bind(object) emitter.emit('foo', 'event-argument') @@ -131,8 +131,8 @@ describe('events', () => { describe('bufferEvents', () => { it('should reply all events', () => { - var spy = sinon.spy() - var replyEvents = e.bufferEvents(emitter, ['foo', 'bar']) + const spy = sinon.spy() + const replyEvents = e.bufferEvents(emitter, ['foo', 'bar']) emitter.emit('foo', 'foo-1') emitter.emit('bar', 'bar-2') @@ -149,8 +149,8 @@ describe('events', () => { }) it('should not buffer after reply()', () => { - var spy = sinon.spy() - var replyEvents = e.bufferEvents(emitter, ['foo', 'bar']) + const spy = sinon.spy() + const replyEvents = e.bufferEvents(emitter, ['foo', 'bar']) replyEvents() emitter.emit('foo', 'foo-1') @@ -168,11 +168,11 @@ describe('events', () => { // This is to make sure it works with socket.io sockets, // which overrides the emit() method to send the event through the wire, // instead of local emit. - var originalEmit = emitter.emit + const originalEmit = emitter.emit emitter.emit = () => null - var spy = sinon.spy() - var replyEvents = e.bufferEvents(emitter, ['foo']) + const spy = sinon.spy() + const replyEvents = e.bufferEvents(emitter, ['foo']) originalEmit.apply(emitter, ['foo', 'whatever']) diff --git a/test/unit/init.spec.js b/test/unit/init.spec.js index 3bcdd0ef6..e9e0f1445 100644 --- a/test/unit/init.spec.js +++ b/test/unit/init.spec.js @@ -1,8 +1,8 @@ -var path = require('path') +const path = require('path') describe('init', () => { - var loadFile = require('mocks').loadFile - var m = null + const loadFile = require('mocks').loadFile + let m = null beforeEach(() => { m = loadFile(path.join(__dirname, '/../../lib/init.js'), {glob: require('glob')}) @@ -11,7 +11,7 @@ describe('init', () => { describe('getBasePath', () => { // just for windows. - var replace = (p) => p.replace(/\//g, path.sep) + const replace = (p) => p.replace(/\//g, path.sep) it('should be empty if config file in cwd', () => { expect(m.getBasePath('some.conf', replace('/usr/local/whatever'))).to.equal('') @@ -23,30 +23,30 @@ describe('init', () => { it('should handle config file in subfolder', () => { // config /usr/local/sub/folder/file.conf - var file = replace('sub/folder/file.conf') + const file = replace('sub/folder/file.conf') expect(m.getBasePath(file, replace('/usr/local'))).to.equal(replace('../..')) }) it('should handle config in a parent path', () => { // config /home/file.js - var basePath = m.getBasePath(replace('../../../file.js'), replace('/home/vojta/tc/project')) + const basePath = m.getBasePath(replace('../../../file.js'), replace('/home/vojta/tc/project')) expect(basePath).to.equal(replace('vojta/tc/project')) }) it('should handle config in parent subfolder', () => { // config /home/vojta/other/f.js - var f = replace('../../other/f.js') + const f = replace('../../other/f.js') expect(m.getBasePath(f, replace('/home/vojta/tc/prj'))).to.equal(replace('../tc/prj')) }) it('should handle absolute paths', () => { - var basePath = m.getBasePath(replace('/Users/vojta/karma/conf.js'), replace('/Users/vojta')) + const basePath = m.getBasePath(replace('/Users/vojta/karma/conf.js'), replace('/Users/vojta')) expect(basePath).to.equal(replace('..')) }) }) describe('processAnswers', () => { - var answers = (obj) => { + const answers = (obj) => { obj = obj || {} obj.files = obj.files || [] obj.exclude = obj.exclude || [] @@ -55,7 +55,7 @@ describe('init', () => { } it('should add requirejs and set files non-included if requirejs used', () => { - var processedAnswers = m.processAnswers(answers({ + const processedAnswers = m.processAnswers(answers({ requirejs: true, includedFiles: ['test-main.js'], files: ['*.js'] @@ -67,7 +67,7 @@ describe('init', () => { }) it('should add coffee preprocessor', () => { - var processedAnswers = m.processAnswers(answers({ + const processedAnswers = m.processAnswers(answers({ files: ['src/*.coffee'] })) @@ -77,14 +77,14 @@ describe('init', () => { }) describe('scenario:', () => { - var formatter - var vm = require('vm') + let formatter + const vm = require('vm') - var StateMachine = require('../../lib/init/state_machine') - var JavaScriptFormatter = require('../../lib/init/formatters').JavaScript - var DefaultKarmaConfig = require('../../lib/config').Config + const StateMachine = require('../../lib/init/state_machine') + const JavaScriptFormatter = require('../../lib/init/formatters').JavaScript + const DefaultKarmaConfig = require('../../lib/config').Config - var mockRli = { + const mockRli = { close: () => null, write: () => null, prompt: () => null, @@ -92,16 +92,16 @@ describe('init', () => { _deleteLineRight: () => null } - var mockColors = { + const mockColors = { question: () => '' } - var machine = formatter = null + let machine = formatter = null - var evaluateConfigCode = (code) => { - var sandbox = {module: {}} + const evaluateConfigCode = (code) => { + const sandbox = {module: {}} vm.runInNewContext(code, sandbox) - var config = new DefaultKarmaConfig() + const config = new DefaultKarmaConfig() sandbox.module.exports(config) return config } @@ -113,10 +113,10 @@ describe('init', () => { it('should generate working config', (done) => { machine.process(m.questions, (answers) => { - var basePath = m.getBasePath('../karma.conf.js', path.normalize('/some/path')) - var processedAnswers = m.processAnswers(answers, basePath) - var generatedConfigCode = formatter.generateConfigFile(processedAnswers) - var config = evaluateConfigCode(generatedConfigCode) + const basePath = m.getBasePath('../karma.conf.js', path.normalize('/some/path')) + const processedAnswers = m.processAnswers(answers, basePath) + const generatedConfigCode = formatter.generateConfigFile(processedAnswers) + const config = evaluateConfigCode(generatedConfigCode) // expect correct configuration expect(config.basePath).to.equal('path') @@ -157,10 +157,10 @@ describe('init', () => { it('should generate config for requirejs', (done) => { machine.process(m.questions, (answers) => { - var basePath = m.getBasePath('../karma.conf.js', '/some/path') - var processedAnswers = m.processAnswers(answers, basePath) - var generatedConfigCode = formatter.generateConfigFile(processedAnswers) - var config = evaluateConfigCode(generatedConfigCode) + const basePath = m.getBasePath('../karma.conf.js', '/some/path') + const processedAnswers = m.processAnswers(answers, basePath) + const generatedConfigCode = formatter.generateConfigFile(processedAnswers) + const config = evaluateConfigCode(generatedConfigCode) // expect correct configuration expect(config.frameworks).to.contain('requirejs') @@ -205,10 +205,10 @@ describe('init', () => { it('should generate the test-main for requirejs', (done) => { machine.process(m.questions, (answers) => { - var basePath = m.getBasePath('../karma.conf.js', '/some/path') - var processedAnswers = m.processAnswers(answers, basePath, 'test-main.js') - var generatedConfigCode = formatter.generateConfigFile(processedAnswers) - var config = evaluateConfigCode(generatedConfigCode) + const basePath = m.getBasePath('../karma.conf.js', '/some/path') + const processedAnswers = m.processAnswers(answers, basePath, 'test-main.js') + const generatedConfigCode = formatter.generateConfigFile(processedAnswers) + const config = evaluateConfigCode(generatedConfigCode) // expect correct processedAnswers expect(processedAnswers.generateTestMain).to.be.ok @@ -252,10 +252,10 @@ describe('init', () => { it('should add coffee preprocessor', (done) => { machine.process(m.questions, (answers) => { - var basePath = m.getBasePath('karma.conf.js', '/cwd') - var processedAnswers = m.processAnswers(answers, basePath) - var generatedConfigCode = formatter.generateConfigFile(processedAnswers) - var config = evaluateConfigCode(generatedConfigCode) + const basePath = m.getBasePath('karma.conf.js', '/cwd') + const processedAnswers = m.processAnswers(answers, basePath) + const generatedConfigCode = formatter.generateConfigFile(processedAnswers) + const config = evaluateConfigCode(generatedConfigCode) // expect correct configuration expect(config.preprocessors).to.have.property('**/*.coffee') diff --git a/test/unit/init/formatters.spec.js b/test/unit/init/formatters.spec.js index d6f783782..ba0f98831 100644 --- a/test/unit/init/formatters.spec.js +++ b/test/unit/init/formatters.spec.js @@ -1,7 +1,7 @@ -var formatters = require('../../../lib/init/formatters') +const formatters = require('../../../lib/init/formatters') describe('init/formatters', () => { - var formatter + let formatter describe('JavaScript', () => { beforeEach(() => { @@ -21,12 +21,12 @@ describe('init/formatters', () => { } it('should format FRAMEWORKS', () => { - var replacements = formatter.formatAnswers(createAnswers({frameworks: ['jasmine', 'requirejs']})) + const replacements = formatter.formatAnswers(createAnswers({frameworks: ['jasmine', 'requirejs']})) expect(replacements.FRAMEWORKS).to.equal("'jasmine', 'requirejs'") }) it('should format FILES', () => { - var replacements = formatter.formatAnswers(createAnswers()) + let replacements = formatter.formatAnswers(createAnswers()) expect(replacements.FILES).to.equal('') replacements = formatter.formatAnswers(createAnswers({files: ['*.js', 'other/file.js']})) @@ -36,12 +36,12 @@ describe('init/formatters', () => { }) it('should format BROWSERS', () => { - var replacements = formatter.formatAnswers(createAnswers({browsers: ['Chrome', 'Firefox']})) + const replacements = formatter.formatAnswers(createAnswers({browsers: ['Chrome', 'Firefox']})) expect(replacements.BROWSERS).to.equal("'Chrome', 'Firefox'") }) it('should format AUTO_WATCH', () => { - var replacements = formatter.formatAnswers(createAnswers({autoWatch: true})) + let replacements = formatter.formatAnswers(createAnswers({autoWatch: true})) expect(replacements.AUTO_WATCH).to.equal('true') replacements = formatter.formatAnswers(createAnswers({autoWatch: false})) @@ -49,7 +49,7 @@ describe('init/formatters', () => { }) it('should format onlyServedFiles', () => { - var replacements = formatter.formatAnswers(createAnswers({ + const replacements = formatter.formatAnswers(createAnswers({ files: ['test-main.js'], onlyServedFiles: ['src/*.js'] })) @@ -60,7 +60,7 @@ describe('init/formatters', () => { }) it('should format PREPROCESSORS', () => { - var replacements = formatter.formatAnswers(createAnswers({preprocessors: {'*.coffee': ['coffee']}})) + const replacements = formatter.formatAnswers(createAnswers({preprocessors: {'*.coffee': ['coffee']}})) expect(replacements.PREPROCESSORS).to.equal( "\n '*.coffee': ['coffee']" diff --git a/test/unit/init/state_machine.spec.js b/test/unit/init/state_machine.spec.js index 5bd620211..d3a0bec8b 100644 --- a/test/unit/init/state_machine.spec.js +++ b/test/unit/init/state_machine.spec.js @@ -1,10 +1,10 @@ -var StateMachine = require('../../../lib/init/state_machine') +const StateMachine = require('../../../lib/init/state_machine') describe('init/StateMachine', () => { - var done - var machine + let done + let machine - var mockRli = { + const mockRli = { close: () => null, write: () => null, prompt: () => null, @@ -12,7 +12,7 @@ describe('init/StateMachine', () => { _deleteLineRight: () => null } - var mockColors = { + const mockColors = { question: () => '' } @@ -22,7 +22,7 @@ describe('init/StateMachine', () => { }) it('should go through all the questions', () => { - var questions = [ + const questions = [ {id: 'framework', options: ['jasmine', 'mocha']}, {id: 'other'} ] @@ -39,7 +39,7 @@ describe('init/StateMachine', () => { }) it('should allow multiple answers', () => { - var questions = [ + const questions = [ {id: 'browsers', multiple: true} ] @@ -55,7 +55,7 @@ describe('init/StateMachine', () => { }) it('should treat spaces as confirmation of multiple answers', () => { - var questions = [ + const questions = [ {id: 'browsers', multiple: true} ] @@ -70,7 +70,7 @@ describe('init/StateMachine', () => { }) it('should always return array for multiple', () => { - var questions = [ + const questions = [ {id: 'empty', multiple: true} ] @@ -84,8 +84,8 @@ describe('init/StateMachine', () => { }) it('should validate answers', () => { - var validator = sinon.spy() - var questions = [ + const validator = sinon.spy() + const questions = [ {id: 'validated', validate: validator} ] @@ -97,10 +97,10 @@ describe('init/StateMachine', () => { }) it('should allow conditional answers', () => { - var ifTrue = sinon.spy((answers) => { + const ifTrue = sinon.spy((answers) => { return answers.first === 'true' }) - var ifFalse = sinon.spy((answers) => { + const ifFalse = sinon.spy((answers) => { return answers.first === 'false' }) @@ -110,7 +110,7 @@ describe('init/StateMachine', () => { expect(answers.onlyIfFalse).to.not.exist }) - var questions = [ + const questions = [ {id: 'first'}, {id: 'onlyIfTrue', condition: ifTrue}, {id: 'onlyIfFalse', condition: ifFalse} @@ -129,7 +129,7 @@ describe('init/StateMachine', () => { expect(answers.no).to.equal(false) }) - var questions = [ + const questions = [ {id: 'yes', options: ['yes', 'no'], boolean: true}, {id: 'no', options: ['yes', 'no'], boolean: true} ] @@ -142,11 +142,11 @@ describe('init/StateMachine', () => { }) it('should parse booleans before validation', () => { - var validator = sinon.spy((value) => { + const validator = sinon.spy((value) => { expect(typeof value).to.equal('boolean') }) - var questions = [ + const questions = [ {id: 'what', options: ['yes', 'no'], boolean: true, validate: validator}, {id: 'really', options: ['yes', 'no'], boolean: true, validate: validator} ] diff --git a/test/unit/launcher.spec.js b/test/unit/launcher.spec.js index 129773295..ac4cd00e2 100644 --- a/test/unit/launcher.spec.js +++ b/test/unit/launcher.spec.js @@ -1,15 +1,15 @@ 'use strict' -var Promise = require('bluebird') -var di = require('di') +const Promise = require('bluebird') +const di = require('di') -var events = require('../../lib/events') -var launcher = require('../../lib/launcher') -var createMockTimer = require('./mocks/timer') +const events = require('../../lib/events') +const launcher = require('../../lib/launcher') +const createMockTimer = require('./mocks/timer') // promise mock -var stubPromise = (obj, method, stubAction) => { - var promise = new Promise((resolve) => { +const stubPromise = (obj, method, stubAction) => { + const promise = new Promise((resolve) => { obj[method].resolve = resolve }) @@ -62,7 +62,7 @@ function ScriptBrowser (id, name, baseBrowserDecorator) { describe('launcher', () => { // mock out id generator - var lastGeneratedId = null + let lastGeneratedId = null launcher.Launcher.generateId = () => ++lastGeneratedId before(() => { @@ -80,10 +80,10 @@ describe('launcher', () => { }) describe('Launcher', () => { - var emitter - var server - var config - var l + let emitter + let server + let config + let l beforeEach(() => { emitter = new events.EventEmitter() @@ -96,7 +96,7 @@ describe('launcher', () => { urlRoot: '/root/' } - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'launcher:Fake': ['type', FakeBrowser], 'launcher:Script': ['type', ScriptBrowser], 'server': ['value', server], @@ -111,7 +111,7 @@ describe('launcher', () => { it('should inject and start all browsers', (done) => { l.launch(['Fake'], 1) - var browser = FakeBrowser._instances.pop() + const browser = FakeBrowser._instances.pop() l.jobs.on('end', () => { expect(browser.start).to.have.been.calledWith('http://localhost:1234/root/') expect(browser.id).to.equal(lastGeneratedId) @@ -138,7 +138,7 @@ describe('launcher', () => { } } - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'launcher:Fake': ['type', FakeBrowser], 'launcher:Script': ['type', ScriptBrowser], 'server': ['value', server], @@ -152,7 +152,7 @@ describe('launcher', () => { it('should inject and start all browsers', (done) => { l.launch(['Fake'], 1) - var browser = FakeBrowser._instances.pop() + const browser = FakeBrowser._instances.pop() l.jobs.on('end', () => { expect(browser.start).to.have.been.calledWith('https://proxy:5678/__proxy__/root/') expect(browser.id).to.equal(lastGeneratedId) @@ -175,7 +175,7 @@ describe('launcher', () => { it('should allow launching a script', (done) => { l.launch(['/usr/local/bin/special-browser'], 1) - var script = ScriptBrowser._instances.pop() + const script = ScriptBrowser._instances.pop() l.jobs.on('end', () => { expect(script.start).to.have.been.calledWith('http://localhost:1234/root/') @@ -189,7 +189,7 @@ describe('launcher', () => { config.hostname = 'whatever' l.launch(['Fake'], 1) - var browser = FakeBrowser._instances.pop() + const browser = FakeBrowser._instances.pop() l.jobs.on('end', () => { expect(browser.start).to.have.been.calledWith('http://whatever:1234/root/') done() @@ -200,10 +200,9 @@ describe('launcher', () => { describe('restart', () => { it('should restart the browser', () => { l.launch(['Fake'], 1) - var browser = FakeBrowser._instances.pop() + const browser = FakeBrowser._instances.pop() - var returnedValue = l.restart(lastGeneratedId) - expect(returnedValue).to.equal(true) + expect(l.restart(lastGeneratedId)).to.equal(true) expect(browser.restart).to.have.been.called }) @@ -216,7 +215,7 @@ describe('launcher', () => { describe('kill', () => { it('should kill browser with given id', (done) => { l.launch(['Fake'], 1) - var browser = FakeBrowser._instances.pop() + const browser = FakeBrowser._instances.pop() l.kill(browser.id, done) expect(browser.forceKill).to.have.been.called @@ -226,10 +225,9 @@ describe('launcher', () => { it('should return false if browser does not exist, but still resolve the callback', (done) => { l.launch(['Fake'], 1) - var browser = FakeBrowser._instances.pop() + const browser = FakeBrowser._instances.pop() - var returnedValue = l.kill('weird-id', done) - expect(returnedValue).to.equal(false) + expect(l.kill('weird-id', done)).to.equal(false) expect(browser.forceKill).not.to.have.been.called }) @@ -247,7 +245,7 @@ describe('launcher', () => { l.launch(['Fake', 'Fake'], 1) l.killAll() - var browser = FakeBrowser._instances.pop() + let browser = FakeBrowser._instances.pop() expect(browser.forceKill).to.have.been.called browser = FakeBrowser._instances.pop() @@ -255,7 +253,7 @@ describe('launcher', () => { }) it('should call callback when all processes killed', () => { - var exitSpy = sinon.spy() + const exitSpy = sinon.spy() l.launch(['Fake', 'Fake'], 1) l.killAll(exitSpy) @@ -263,7 +261,7 @@ describe('launcher', () => { expect(exitSpy).not.to.have.been.called // finish the first browser - var browser = FakeBrowser._instances.pop() + let browser = FakeBrowser._instances.pop() browser.forceKill.resolve() scheduleNextTick(() => { @@ -318,7 +316,7 @@ describe('launcher', () => { emitter.emitAsync('exit').then(done) - var browser = FakeBrowser._instances.pop() + let browser = FakeBrowser._instances.pop() browser.forceKill.resolve() browser = FakeBrowser._instances.pop() diff --git a/test/unit/launchers/base.spec.js b/test/unit/launchers/base.spec.js index 89408defd..d9b383566 100644 --- a/test/unit/launchers/base.spec.js +++ b/test/unit/launchers/base.spec.js @@ -1,11 +1,11 @@ -var _ = require('lodash') +const _ = require('lodash') -var BaseLauncher = require('../../../lib/launchers/base') -var EventEmitter = require('../../../lib/events').EventEmitter +const BaseLauncher = require('../../../lib/launchers/base') +const EventEmitter = require('../../../lib/events').EventEmitter describe('launchers/base.js', () => { - var emitter - var launcher + let emitter + let launcher beforeEach(() => { emitter = new EventEmitter() @@ -23,7 +23,7 @@ describe('launchers/base.js', () => { describe('start', () => { it('should fire "start" event and pass url with id', () => { - var spyOnStart = sinon.spy() + const spyOnStart = sinon.spy() launcher.on('start', spyOnStart) launcher.start('http://localhost:9876/') @@ -33,8 +33,8 @@ describe('launchers/base.js', () => { describe('restart', () => { it('should kill running browser and start with previous url', (done) => { - var spyOnStart = sinon.spy() - var spyOnKill = sinon.spy() + const spyOnStart = sinon.spy() + const spyOnKill = sinon.spy() launcher.on('start', spyOnStart) launcher.on('kill', spyOnKill) @@ -56,9 +56,9 @@ describe('launchers/base.js', () => { }) it('should start when already finished (crashed)', (done) => { - var spyOnStart = sinon.spy() - var spyOnKill = sinon.spy() - var spyOnDone = sinon.spy() + const spyOnStart = sinon.spy() + const spyOnKill = sinon.spy() + const spyOnDone = sinon.spy() launcher.on('start', spyOnStart) launcher.on('kill', spyOnKill) @@ -82,15 +82,15 @@ describe('launchers/base.js', () => { }) it('should not restart when being force killed', (done) => { - var spyOnStart = sinon.spy() - var spyOnKill = sinon.spy() + const spyOnStart = sinon.spy() + const spyOnKill = sinon.spy() launcher.on('start', spyOnStart) launcher.on('kill', spyOnKill) launcher.start('http://host:9988/') spyOnStart.reset() - var onceKilled = launcher.forceKill() + const onceKilled = launcher.forceKill() launcher.restart() @@ -107,7 +107,7 @@ describe('launchers/base.js', () => { describe('kill', () => { it('should manage state', (done) => { - var onceKilled = launcher.kill() + const onceKilled = launcher.kill() expect(launcher.state).to.equal(launcher.STATE_BEING_KILLED) onceKilled.done(() => { @@ -117,9 +117,9 @@ describe('launchers/base.js', () => { }) it('should fire "kill" and wait for all listeners to finish', (done) => { - var spyOnKill1 = sinon.spy() - var spyOnKill2 = sinon.spy() - var spyKillDone = sinon.spy(done) + const spyOnKill1 = sinon.spy() + const spyOnKill2 = sinon.spy() + const spyKillDone = sinon.spy(done) launcher.on('kill', spyOnKill1) launcher.on('kill', spyOnKill2) @@ -137,7 +137,7 @@ describe('launchers/base.js', () => { }) // the second listener is done it('should not fire "kill" if already killed', (done) => { - var spyOnKill = sinon.spy() + const spyOnKill = sinon.spy() launcher.on('kill', spyOnKill) launcher.start('http://localhost:9876/') @@ -153,10 +153,10 @@ describe('launchers/base.js', () => { }) it('should not fire "kill" if already being killed, but wait for all listeners', (done) => { - var spyOnKill = sinon.spy() + const spyOnKill = sinon.spy() launcher.on('kill', spyOnKill) - var expectOnKillListenerIsAlreadyFinishedAndHasBeenOnlyCalledOnce = () => { + const expectOnKillListenerIsAlreadyFinishedAndHasBeenOnlyCalledOnce = () => { expect(spyOnKill).to.have.been.called expect(spyOnKill.callCount).to.equal(1) expect(spyOnKill.finished).to.equal(true) @@ -164,11 +164,11 @@ describe('launchers/base.js', () => { } launcher.start('http://localhost:9876/') - var firstKilling = launcher.kill().then(() => { + const firstKilling = launcher.kill().then(() => { expectOnKillListenerIsAlreadyFinishedAndHasBeenOnlyCalledOnce() }) - var secondKilling = launcher.kill().then(() => { + const secondKilling = launcher.kill().then(() => { expectOnKillListenerIsAlreadyFinishedAndHasBeenOnlyCalledOnce() }) @@ -184,7 +184,7 @@ describe('launchers/base.js', () => { }) it('should not kill already crashed browser', (done) => { - var spyOnKill = sinon.spy((killDone) => killDone()) + const spyOnKill = sinon.spy((killDone) => killDone()) launcher.on('kill', spyOnKill) launcher._done('crash') @@ -197,7 +197,7 @@ describe('launchers/base.js', () => { describe('forceKill', () => { it('should cancel restart', (done) => { - var spyOnStart = sinon.spy() + const spyOnStart = sinon.spy() launcher.on('start', spyOnStart) launcher.start('http://localhost:9876/') @@ -212,7 +212,7 @@ describe('launchers/base.js', () => { }) it('should not fire "browser_process_failure" even if browser crashes', (done) => { - var spyOnBrowserProcessFailure = sinon.spy() + const spyOnBrowserProcessFailure = sinon.spy() emitter.on('browser_process_failure', spyOnBrowserProcessFailure) launcher.on('kill', (killDone) => { @@ -240,7 +240,7 @@ describe('launchers/base.js', () => { describe('_done', () => { it('should emit "browser_process_failure" if there is an error', () => { - var spyOnBrowserProcessFailure = sinon.spy() + const spyOnBrowserProcessFailure = sinon.spy() emitter.on('browser_process_failure', spyOnBrowserProcessFailure) launcher._done('crashed') @@ -249,7 +249,7 @@ describe('launchers/base.js', () => { }) it('should not emit "browser_process_failure" when no error happend', () => { - var spyOnBrowserProcessFailure = sinon.spy() + const spyOnBrowserProcessFailure = sinon.spy() emitter.on('browser_process_failure', spyOnBrowserProcessFailure) launcher._done() diff --git a/test/unit/launchers/capture_timeout.spec.js b/test/unit/launchers/capture_timeout.spec.js index 46e62debc..a7881439f 100644 --- a/test/unit/launchers/capture_timeout.spec.js +++ b/test/unit/launchers/capture_timeout.spec.js @@ -1,10 +1,10 @@ -var BaseLauncher = require('../../../lib/launchers/base') -var CaptureTimeoutLauncher = require('../../../lib/launchers/capture_timeout') -var createMockTimer = require('../mocks/timer') +const BaseLauncher = require('../../../lib/launchers/base') +const CaptureTimeoutLauncher = require('../../../lib/launchers/capture_timeout') +const createMockTimer = require('../mocks/timer') describe('launchers/capture_timeout.js', () => { - var timer - var launcher + let timer + let launcher beforeEach(() => { timer = createMockTimer() diff --git a/test/unit/launchers/process.spec.js b/test/unit/launchers/process.spec.js index 746747007..e9b3a158d 100644 --- a/test/unit/launchers/process.spec.js +++ b/test/unit/launchers/process.spec.js @@ -1,27 +1,27 @@ -var path = require('path') -var _ = require('lodash') +const path = require('path') +const _ = require('lodash') -var BaseLauncher = require('../../../lib/launchers/base') -var RetryLauncher = require('../../../lib/launchers/retry') -var CaptureTimeoutLauncher = require('../../../lib/launchers/capture_timeout') -var ProcessLauncher = require('../../../lib/launchers/process') -var EventEmitter = require('../../../lib/events').EventEmitter -var createMockTimer = require('../mocks/timer') +const BaseLauncher = require('../../../lib/launchers/base') +const RetryLauncher = require('../../../lib/launchers/retry') +const CaptureTimeoutLauncher = require('../../../lib/launchers/capture_timeout') +const ProcessLauncher = require('../../../lib/launchers/process') +const EventEmitter = require('../../../lib/events').EventEmitter +const createMockTimer = require('../mocks/timer') describe('launchers/process.js', () => { - var emitter - var mockSpawn - var mockTempDir - var launcher + let emitter + let mockSpawn + let mockTempDir + let launcher - var BROWSER_PATH = path.normalize('/usr/bin/browser') + const BROWSER_PATH = path.normalize('/usr/bin/browser') beforeEach(() => { emitter = new EventEmitter() launcher = new BaseLauncher('fake-id', emitter) mockSpawn = sinon.spy(function (cmd, args) { - var process = new EventEmitter() + const process = new EventEmitter() process.stdout = new EventEmitter() process.stderr = new EventEmitter() process.kill = sinon.spy() @@ -79,7 +79,7 @@ describe('launchers/process.js', () => { RetryLauncher.call(launcher, 2) launcher._getCommand = () => BROWSER_PATH - var failureSpy = sinon.spy() + const failureSpy = sinon.spy() emitter.on('browser_process_failure', failureSpy) launcher.start('http://host:9876/') @@ -97,8 +97,8 @@ describe('launchers/process.js', () => { // higher level tests with Retry and CaptureTimeout launchers describe('flow', () => { - var failureSpy - var mockTimer = failureSpy = null + let failureSpy + let mockTimer = failureSpy = null beforeEach(() => { mockTimer = createMockTimer() @@ -122,7 +122,7 @@ describe('launchers/process.js', () => { launcher.markCaptured() // kill it - var killingLauncher = launcher.kill() + const killingLauncher = launcher.kill() expect(launcher.state).to.equal(launcher.STATE_BEING_KILLED) expect(mockSpawn._processes[0].kill).to.have.been.called @@ -138,18 +138,18 @@ describe('launchers/process.js', () => { // when the browser fails to get captured in default timeout, it should restart it('start -> timeout -> restart', (done) => { - var stdOutSpy = sinon.spy(launcher, '_onStdout') - var stdErrSpy = sinon.spy(launcher, '_onStderr') + const stdOutSpy = sinon.spy(launcher, '_onStdout') + const stdErrSpy = sinon.spy(launcher, '_onStderr') // start launcher.start('http://localhost/') // expect starting the process expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) - var browserProcess = mockSpawn._processes.shift() + const browserProcess = mockSpawn._processes.shift() - var expectedStdoutString = 'starting...' - var expectedStderrString = 'Oops...there was a problem' + const expectedStdoutString = 'starting...' + const expectedStderrString = 'Oops...there was a problem' browserProcess.stdout.emit('data', expectedStdoutString) browserProcess.stderr.emit('data', expectedStderrString) @@ -182,7 +182,7 @@ describe('launchers/process.js', () => { // expect starting expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) - var browserProcess = mockSpawn._processes.shift() + let browserProcess = mockSpawn._processes.shift() mockSpawn.reset() // timeout - first time @@ -242,7 +242,7 @@ describe('launchers/process.js', () => { // expect starting the process expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) - var browserProcess = mockSpawn._processes.shift() + let browserProcess = mockSpawn._processes.shift() mockSpawn.reset() // crash @@ -263,8 +263,8 @@ describe('launchers/process.js', () => { // higher level tests - process kill timeout describe('process-kill-timeout', () => { - var failureSpy - var mockTimer = null + let failureSpy + let mockTimer = null beforeEach(() => { mockTimer = createMockTimer() @@ -285,7 +285,7 @@ describe('launchers/process.js', () => { // expect starting the process expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) - var browserProcess = mockSpawn._processes.shift() + const browserProcess = mockSpawn._processes.shift() // timeout mockTimer.wind(101) diff --git a/test/unit/launchers/retry.spec.js b/test/unit/launchers/retry.spec.js index 90bd69579..58ebda7b6 100644 --- a/test/unit/launchers/retry.spec.js +++ b/test/unit/launchers/retry.spec.js @@ -1,12 +1,12 @@ -var _ = require('lodash') +const _ = require('lodash') -var BaseLauncher = require('../../../lib/launchers/base') -var RetryLauncher = require('../../../lib/launchers/retry') -var EventEmitter = require('../../../lib/events').EventEmitter +const BaseLauncher = require('../../../lib/launchers/base') +const RetryLauncher = require('../../../lib/launchers/retry') +const EventEmitter = require('../../../lib/events').EventEmitter describe('launchers/retry.js', () => { - var emitter - var launcher + let emitter + let launcher beforeEach(() => { emitter = new EventEmitter() @@ -19,7 +19,7 @@ describe('launchers/retry.js', () => { launcher.start('http://localhost:9876') sinon.spy(launcher, 'start') - var spyOnBrowserProcessFailure = sinon.spy() + const spyOnBrowserProcessFailure = sinon.spy() emitter.on('browser_process_failure', spyOnBrowserProcessFailure) // simulate crash @@ -38,7 +38,7 @@ describe('launchers/retry.js', () => { launcher.start('http://localhost:9876') sinon.spy(launcher, 'start') - var spyOnBrowserProcessFailure = sinon.spy() + const spyOnBrowserProcessFailure = sinon.spy() emitter.on('browser_process_failure', spyOnBrowserProcessFailure) // simulate first crash @@ -75,7 +75,7 @@ describe('launchers/retry.js', () => { launcher.start('http://localhost:9876') sinon.spy(launcher, 'start') - var spyOnBrowserProcessFailure = sinon.spy() + const spyOnBrowserProcessFailure = sinon.spy() emitter.on('browser_process_failure', spyOnBrowserProcessFailure) // process just exited normally diff --git a/test/unit/logger.spec.js b/test/unit/logger.spec.js index d3ea57fcd..bbc07bcef 100644 --- a/test/unit/logger.spec.js +++ b/test/unit/logger.spec.js @@ -1,12 +1,12 @@ -var loadFile = require('mocks').loadFile -var path = require('path') +const loadFile = require('mocks').loadFile +const path = require('path') describe('logger', () => { - var m - var configuration + let m + let configuration beforeEach(() => { - var mockLog4Js = { + const mockLog4Js = { configure: function (config) { configuration = config } diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js index 6d1eab8e1..76a8e3242 100644 --- a/test/unit/middleware/karma.spec.js +++ b/test/unit/middleware/karma.spec.js @@ -1,20 +1,20 @@ 'use strict' -var mocks = require('mocks') +const mocks = require('mocks') -var helper = require('../../../lib/helper') -var constants = require('../../../lib/constants') -var File = require('../../../lib/file') -var Url = require('../../../lib/url') +const helper = require('../../../lib/helper') +const constants = require('../../../lib/constants') +const File = require('../../../lib/file') +const Url = require('../../../lib/url') -var HttpResponseMock = mocks.http.ServerResponse -var HttpRequestMock = mocks.http.ServerRequest +const HttpResponseMock = mocks.http.ServerResponse +const HttpRequestMock = mocks.http.ServerRequest describe('middleware.karma', () => { - var serveFile - var filesDeferred - var nextSpy - var response + let serveFile + let filesDeferred + let nextSpy + let response class MockFile extends File { constructor (path, sha, type) { @@ -23,7 +23,7 @@ describe('middleware.karma', () => { } } - var fsMock = mocks.fs.create({ + const fsMock = mocks.fs.create({ karma: { static: { 'client.html': mocks.fs.file(0, 'CLIENT HTML\n%X_UA_COMPATIBLE%%X_UA_COMPATIBLE_URL%'), @@ -34,15 +34,14 @@ describe('middleware.karma', () => { } }) - var createServeFile = require('../../../lib/middleware/common').createServeFile - var createKarmaMiddleware = require('../../../lib/middleware/karma').create + const createServeFile = require('../../../lib/middleware/common').createServeFile + const createKarmaMiddleware = require('../../../lib/middleware/karma').create + let handler = serveFile = filesDeferred = nextSpy = response = null - var handler = serveFile = filesDeferred = nextSpy = response = null - - var clientConfig = { + const clientConfig = { foo: 'bar' } - var injector = { + const injector = { get (val) { switch (val) { case 'config.client': @@ -72,22 +71,22 @@ describe('middleware.karma', () => { }) // helpers - var includedFiles = (files) => { + const includedFiles = (files) => { return filesDeferred.resolve({included: files, served: []}) } - var servedFiles = (files) => { + const servedFiles = (files) => { return filesDeferred.resolve({included: [], served: files}) } - var normalizedHttpRequest = (urlPath) => { - var req = new HttpRequestMock(urlPath) + const normalizedHttpRequest = (urlPath) => { + const req = new HttpRequestMock(urlPath) req.normalizedUrl = req.url return req } function callHandlerWith (urlPath, next) { - var promise = handler(normalizedHttpRequest(urlPath), response, next || nextSpy) + const promise = handler(normalizedHttpRequest(urlPath), response, next || nextSpy) if (promise && promise.done) promise.done() } @@ -188,7 +187,7 @@ describe('middleware.karma', () => { callHandlerWith('/__karma__/debug.html?x-ua-compatible=xxx%3Dyyy') }) - it('should serve karma.js with version and urlRoot variables', (done) => { + it('should serve karma.js with version and urlRoot constiables', (done) => { response.once('end', () => { expect(nextSpy).not.to.have.been.called expect(response).to.beServedAs(200, 'root: /__karma__/, proxy: /__proxy__/, v: ' + constants.VERSION) @@ -315,7 +314,7 @@ describe('middleware.karma', () => { }) it('should send non-caching headers for context.html', (done) => { - var ZERO_DATE = (new Date(0)).toUTCString() + const ZERO_DATE = (new Date(0)).toUTCString() includedFiles([]) @@ -422,7 +421,7 @@ describe('middleware.karma', () => { }) it('should update handle updated configs', (done) => { - var i = 0 + let i = 0 handler = createKarmaMiddleware( filesDeferred.promise, serveFile, diff --git a/test/unit/middleware/proxy.spec.js b/test/unit/middleware/proxy.spec.js index d1047ac35..a23f9a58c 100644 --- a/test/unit/middleware/proxy.spec.js +++ b/test/unit/middleware/proxy.spec.js @@ -1,16 +1,15 @@ -var path = require('path') -var httpMock = require('mocks').http -var loadFile = require('mocks').loadFile +const path = require('path') +const httpMock = require('mocks').http +const loadFile = require('mocks').loadFile describe('middleware.proxy', () => { - var requestedUrl - var response - var nextSpy - var type + let requestedUrl + let response + let nextSpy + let type + let m = loadFile(path.join(__dirname, '/../../../lib/middleware/proxy.js')) - var m = loadFile(path.join(__dirname, '/../../../lib/middleware/proxy.js')) - - var mockProxies = [{ + const mockProxies = [{ path: '/proxy', baseUrl: '', host: 'localhost', @@ -88,7 +87,7 @@ describe('middleware.proxy', () => { }) it('should proxy requests', (done) => { - var proxy = m.createProxyHandler(mockProxies, true, '/', {}) + const proxy = m.createProxyHandler(mockProxies, true, '/', {}) proxy(new httpMock.ServerRequest('/proxy/test.html'), response, nextSpy) expect(nextSpy).not.to.have.been.called @@ -98,7 +97,7 @@ describe('middleware.proxy', () => { }) it('should proxy websocket requests', (done) => { - var proxy = m.createProxyHandler(mockProxies, true, '/', {}) + const proxy = m.createProxyHandler(mockProxies, true, '/', {}) proxy.upgrade(new httpMock.ServerRequest('/proxy/test.html'), response, nextSpy) expect(nextSpy).not.to.have.been.called @@ -108,7 +107,7 @@ describe('middleware.proxy', () => { }) it('should support multiple proxies', () => { - var proxy = m.createProxyHandler(mockProxies, true, '/', {}) + const proxy = m.createProxyHandler(mockProxies, true, '/', {}) proxy(new httpMock.ServerRequest('/static/test.html'), response, nextSpy) expect(nextSpy).not.to.have.been.called @@ -117,7 +116,7 @@ describe('middleware.proxy', () => { }) it('should handle nested proxies', () => { - var proxy = m.createProxyHandler(mockProxies, true, '/', {}) + const proxy = m.createProxyHandler(mockProxies, true, '/', {}) proxy(new httpMock.ServerRequest('/sub/some/Test.html'), response, nextSpy) expect(nextSpy).not.to.have.been.called @@ -126,22 +125,22 @@ describe('middleware.proxy', () => { }) it('should call next handler if the path is not proxied', () => { - var proxy = m.createProxyHandler(mockProxies, true, '/', {}) + const proxy = m.createProxyHandler(mockProxies, true, '/', {}) proxy(new httpMock.ServerRequest('/non/proxy/test.html'), response, nextSpy) expect(nextSpy).to.have.been.called }) it('should call next handler if no proxy defined', () => { - var proxy = m.createProxyHandler({}, true, '/', {}) + const proxy = m.createProxyHandler({}, true, '/', {}) proxy(new httpMock.ServerRequest('/non/proxy/test.html'), response, nextSpy) expect(nextSpy).to.have.been.called }) it('should parse a simple proxy config', () => { - var proxy = {'/base/': 'http://localhost:8000/'} - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const proxy = {'/base/': 'http://localhost:8000/'} + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -154,8 +153,8 @@ describe('middleware.proxy', () => { }) it('should set default http port', () => { - var proxy = {'/base/': 'http://localhost/'} - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const proxy = {'/base/': 'http://localhost/'} + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -168,8 +167,8 @@ describe('middleware.proxy', () => { }) it('should set default https port', () => { - var proxy = {'/base/': 'https://localhost/'} - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const proxy = {'/base/': 'https://localhost/'} + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -189,8 +188,8 @@ describe('middleware.proxy', () => { }) it('should handle proxy configs with paths', () => { - var proxy = {'/base': 'http://localhost:8000/proxy'} - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const proxy = {'/base': 'http://localhost:8000/proxy'} + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -203,8 +202,8 @@ describe('middleware.proxy', () => { }) it('should determine protocol', () => { - var proxy = {'/base': 'https://localhost:8000'} - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const proxy = {'/base': 'https://localhost:8000'} + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -224,9 +223,9 @@ describe('middleware.proxy', () => { }) it('should handle proxy configs with only basepaths', () => { - var proxy = {'/base': '/proxy/test'} - var config = {port: 9877, hostname: 'localhost'} - var parsedProxyConfig = m.parseProxyConfig(proxy, config) + const proxy = {'/base': '/proxy/test'} + const config = {port: 9877, hostname: 'localhost'} + const parsedProxyConfig = m.parseProxyConfig(proxy, config) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -239,9 +238,9 @@ describe('middleware.proxy', () => { }) it('should normalize proxy url with only basepaths', () => { - var proxy = {'/base/': '/proxy/test'} - var config = {port: 9877, hostname: 'localhost'} - var parsedProxyConfig = m.parseProxyConfig(proxy, config) + const proxy = {'/base/': '/proxy/test'} + const config = {port: 9877, hostname: 'localhost'} + const parsedProxyConfig = m.parseProxyConfig(proxy, config) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -254,9 +253,9 @@ describe('middleware.proxy', () => { }) it('should parse right port of proxy target', () => { - var proxy = { '/w': 'http://krinkle.dev/w' } - var config = {port: 9877, hostname: 'localhost'} - var parsedProxyConfig = m.parseProxyConfig(proxy, config) + const proxy = { '/w': 'http://krinkle.dev/w' } + const config = {port: 9877, hostname: 'localhost'} + const parsedProxyConfig = m.parseProxyConfig(proxy, config) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'krinkle.dev', @@ -269,9 +268,9 @@ describe('middleware.proxy', () => { }) it('should parse right port of proxy target w. https', () => { - var proxy = { '/w': 'https://krinkle.dev/w' } - var config = {port: 9877, hostname: 'localhost'} - var parsedProxyConfig = m.parseProxyConfig(proxy, config) + const proxy = { '/w': 'https://krinkle.dev/w' } + const config = {port: 9877, hostname: 'localhost'} + const parsedProxyConfig = m.parseProxyConfig(proxy, config) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'krinkle.dev', @@ -284,8 +283,8 @@ describe('middleware.proxy', () => { }) it('should normalize proxy url', () => { - var proxy = {'/base/': 'http://localhost:8000/proxy/test'} - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const proxy = {'/base/': 'http://localhost:8000/proxy/test'} + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -298,11 +297,11 @@ describe('middleware.proxy', () => { }) it('should parse nested proxy config', () => { - var proxy = { + const proxy = { '/sub': 'http://localhost:9000', '/sub/some': 'http://gstatic.com/something' } - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(2) expect(parsedProxyConfig[0]).to.containSubset({ host: 'gstatic.com', @@ -323,10 +322,10 @@ describe('middleware.proxy', () => { }) it('should accept object for proxy config', () => { - var proxy = { + const proxy = { '/base/': {target: 'http://localhost:8000/'} } - var parsedProxyConfig = m.parseProxyConfig(proxy, {}) + const parsedProxyConfig = m.parseProxyConfig(proxy, {}) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0]).to.containSubset({ host: 'localhost', @@ -339,12 +338,12 @@ describe('middleware.proxy', () => { }) it('should bind proxy event', () => { - var proxy = {'/base/': 'http://localhost:8000/'} - var config = { + const proxy = {'/base/': 'http://localhost:8000/'} + const config = { proxyReq: function proxyReq () {}, proxyRes: function proxyRes () {} } - var parsedProxyConfig = m.parseProxyConfig(proxy, config) + const parsedProxyConfig = m.parseProxyConfig(proxy, config) expect(parsedProxyConfig).to.have.length(1) expect(parsedProxyConfig[0].proxy.listeners('proxyReq')[0]).to.equal(config.proxyReq) expect(parsedProxyConfig[0].proxy.listeners('proxyRes')[0]).to.equal(config.proxyRes) diff --git a/test/unit/middleware/runner.spec.js b/test/unit/middleware/runner.spec.js index c2dd60c7c..3fc1beac2 100644 --- a/test/unit/middleware/runner.spec.js +++ b/test/unit/middleware/runner.spec.js @@ -1,27 +1,27 @@ -var path = require('path') -var EventEmitter = require('events').EventEmitter -var mocks = require('mocks') -var Promise = require('bluebird') -var _ = require('lodash') +const path = require('path') +const EventEmitter = require('events').EventEmitter +const mocks = require('mocks') +const Promise = require('bluebird') +const _ = require('lodash') -var Browser = require('../../../lib/browser') -var BrowserCollection = require('../../../lib/browser_collection') -var MultReporter = require('../../../lib/reporters/multi') -var createRunnerMiddleware = require('../../../lib/middleware/runner').create +const Browser = require('../../../lib/browser') +const BrowserCollection = require('../../../lib/browser_collection') +const MultReporter = require('../../../lib/reporters/multi') +const createRunnerMiddleware = require('../../../lib/middleware/runner').create -var HttpResponseMock = mocks.http.ServerResponse -var HttpRequestMock = mocks.http.ServerRequest +const HttpResponseMock = mocks.http.ServerResponse +const HttpRequestMock = mocks.http.ServerRequest describe('middleware.runner', () => { - var nextSpy - var response - var mockReporter - var capturedBrowsers - var emitter - var config - var executor - var handler - var fileListMock + let nextSpy + let response + let mockReporter + let capturedBrowsers + let emitter + let config + let executor + let handler + let fileListMock function createHandler () { handler = createRunnerMiddleware( @@ -162,13 +162,13 @@ describe('middleware.runner', () => { sinon.stub(fileListMock, 'changeFile') sinon.stub(fileListMock, 'removeFile') - var RAW_MESSAGE = JSON.stringify({ + const RAW_MESSAGE = JSON.stringify({ addedFiles: ['/new.js'], removedFiles: ['/foo.js', '/bar.js'], changedFiles: ['/changed.js'] }) - var request = new HttpRequestMock('/__run__', { + const request = new HttpRequestMock('/__run__', { 'content-type': 'application/json', 'content-length': RAW_MESSAGE.length }) @@ -192,14 +192,14 @@ describe('middleware.runner', () => { capturedBrowsers.add(new Browser()) sinon.stub(capturedBrowsers, 'areAllReady').callsFake(() => true) - var res = null - var fileListPromise = new Promise((resolve, reject) => { + let res = null + const fileListPromise = new Promise((resolve, reject) => { res = resolve }) sinon.stub(fileListMock, 'refresh').returns(fileListPromise) sinon.stub(executor, 'schedule') - var request = new HttpRequestMock('/__run__') + const request = new HttpRequestMock('/__run__') handler(request, response, nextSpy) process.nextTick(() => { @@ -222,9 +222,9 @@ describe('middleware.runner', () => { sinon.spy(fileListMock, 'refresh') sinon.stub(executor, 'schedule') - var RAW_MESSAGE = JSON.stringify({refresh: false}) + const RAW_MESSAGE = JSON.stringify({refresh: false}) - var request = new HttpRequestMock('/__run__', { + const request = new HttpRequestMock('/__run__', { 'content-type': 'application/json', 'content-length': RAW_MESSAGE.length }) diff --git a/test/unit/middleware/source_files.spec.js b/test/unit/middleware/source_files.spec.js index 64d481298..cab8cc8da 100644 --- a/test/unit/middleware/source_files.spec.js +++ b/test/unit/middleware/source_files.spec.js @@ -1,19 +1,19 @@ -var http = require('http') -var mocks = require('mocks') -var request = require('supertest') +const http = require('http') +const mocks = require('mocks') +const request = require('supertest') var zlib = require('zlib') -var helper = require('../../../lib/helper') -var File = require('../../../lib/file') -var createServeFile = require('../../../lib/middleware/common').createServeFile -var createSourceFilesMiddleware = require('../../../lib/middleware/source_files').create +const helper = require('../../../lib/helper') +const File = require('../../../lib/file') +const createServeFile = require('../../../lib/middleware/common').createServeFile +const createSourceFilesMiddleware = require('../../../lib/middleware/source_files').create describe('middleware.source_files', function () { - var next - var files - var server = next = files = null + let next + let files + let server = next = files = null - var fsMock = mocks.fs.create({ + const fsMock = mocks.fs.create({ base: { path: { 'a.js': mocks.fs.file(0, 'js-src-a'), @@ -31,10 +31,10 @@ describe('middleware.source_files', function () { } }) - var serveFile = createServeFile(fsMock, null) + const serveFile = createServeFile(fsMock, null) function createServer (f, s, basePath) { - var handler = createSourceFilesMiddleware(f.promise, s, basePath) + const handler = createSourceFilesMiddleware(f.promise, s, basePath) return http.createServer(function (req, res) { next = sinon.spy(function (err) { if (err) { @@ -194,7 +194,7 @@ describe('middleware.source_files', function () { }) it('should send no-caching headers for js source files without timestamps', function () { - var ZERO_DATE = new RegExp(new Date(0).toUTCString()) + const ZERO_DATE = new RegExp(new Date(0).toUTCString()) servedFiles([ new File('/src/some.js') @@ -272,7 +272,7 @@ describe('middleware.source_files', function () { }) it('should use cached content if available', function () { - var cachedFile = new File('/some/file.js') + const cachedFile = new File('/some/file.js') cachedFile.content = 'cached-content' servedFiles([ @@ -288,7 +288,7 @@ describe('middleware.source_files', function () { }) return it('should not use cached content if doNotCache is set', function () { - var cachedFile = new File('/src/some.js') + const cachedFile = new File('/src/some.js') cachedFile.content = 'cached-content' cachedFile.doNotCache = true diff --git a/test/unit/mocha-globals.js b/test/unit/mocha-globals.js index 089961ad7..d36874b32 100644 --- a/test/unit/mocha-globals.js +++ b/test/unit/mocha-globals.js @@ -1,6 +1,6 @@ -var sinon = require('sinon') -var chai = require('chai') -var logger = require('../../lib/logger') +const sinon = require('sinon') +const chai = require('chai') +const logger = require('../../lib/logger') require('bluebird').longStackTraces() @@ -29,7 +29,7 @@ afterEach(() => { // TODO(vojta): move to helpers or something chai.use((chai, utils) => { chai.Assertion.addMethod('beServedAs', function (expectedStatus, expectedBody) { - var response = utils.flag(this, 'object') + const response = utils.flag(this, 'object') this.assert(response._status === expectedStatus, `expected response status '${response._status}' to be '${expectedStatus}'`) @@ -38,7 +38,7 @@ chai.use((chai, utils) => { }) chai.Assertion.addMethod('beNotServed', function () { - var response = utils.flag(this, 'object') + const response = utils.flag(this, 'object') this.assert(response._status === null, `expected response status to not be set, it was '${response._status}'`) @@ -48,8 +48,8 @@ chai.use((chai, utils) => { }) // TODO(vojta): move it somewhere ;-) -var nextTickQueue = [] -var nextTickCallback = () => { +const nextTickQueue = [] +const nextTickCallback = () => { if (!nextTickQueue.length) throw new Error('Nothing scheduled!') nextTickQueue.shift()() @@ -60,8 +60,8 @@ global.scheduleNextTick = (action) => { if (nextTickQueue.length === 1) process.nextTick(nextTickCallback) } -var nextQueue = [] -var nextCallback = () => { +const nextQueue = [] +const nextCallback = () => { // if not nextQueue.length then throw new Error 'Nothing scheduled!' nextQueue.shift()() } diff --git a/test/unit/mocks/timer.js b/test/unit/mocks/timer.js index 8abb35e9b..65e6a20e6 100644 --- a/test/unit/mocks/timer.js +++ b/test/unit/mocks/timer.js @@ -1,7 +1,7 @@ -var Timer = require('timer-shim').Timer +const Timer = require('timer-shim').Timer module.exports = function () { - var timer = new Timer() + const timer = new Timer() timer.pause() return { diff --git a/test/unit/preprocessor.spec.js b/test/unit/preprocessor.spec.js index 1e4439a6c..10e1f2a00 100644 --- a/test/unit/preprocessor.spec.js +++ b/test/unit/preprocessor.spec.js @@ -318,7 +318,7 @@ describe('preprocessor', () => { }) fakePreprocessor.handleBinaryFiles = true - var injector = new di.Injector([{ + const injector = new di.Injector([{ 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] }, emitterSetting]) diff --git a/test/unit/reporter.spec.js b/test/unit/reporter.spec.js index 02f3d0acf..b74f90cd1 100644 --- a/test/unit/reporter.spec.js +++ b/test/unit/reporter.spec.js @@ -1,24 +1,24 @@ 'use strict' -var EventEmitter = require('events').EventEmitter -var loadFile = require('mocks').loadFile -var path = require('path') -var _ = require('lodash') -var sinon = require('sinon') +const EventEmitter = require('events').EventEmitter +const loadFile = require('mocks').loadFile +const path = require('path') +const _ = require('lodash') +const sinon = require('sinon') -var File = require('../../lib/file') +const File = require('../../lib/file') describe('reporter', () => { - var m + let m beforeEach(() => { m = loadFile(path.join(__dirname, '/../../lib/reporter.js')) }) describe('formatError', () => { - var emitter - var formatError = emitter = null - var sandbox + let emitter + let formatError = emitter = null + let sandbox beforeEach(() => { emitter = new EventEmitter() @@ -27,7 +27,7 @@ describe('reporter', () => { }) it('should call config.formatError if defined', () => { - var spy = sandbox.spy() + const spy = sandbox.spy() formatError = m.createErrorFormatter({ basePath: '', formatError: spy }, emitter) formatError() @@ -35,15 +35,15 @@ describe('reporter', () => { }) it('should not call config.formatError if not defined', () => { - var spy = sandbox.spy() + const spy = sandbox.spy() formatError() expect(spy).not.to.have.been.calledOnce }) it('should pass the error message as the first config.formatError argument', () => { - var ERROR = 'foo bar' - var spy = sandbox.spy() + const ERROR = 'foo bar' + const spy = sandbox.spy() formatError = m.createErrorFormatter({ basePath: '', formatError: spy }, emitter) formatError(ERROR) @@ -51,7 +51,7 @@ describe('reporter', () => { }) it('should display the exact error returned by config.formatError', () => { - var formattedError = 'A new error' + const formattedError = 'A new error' formatError = m.createErrorFormatter({ basePath: '', formatError: () => formattedError }, emitter) expect(formatError('Something', '\t')).to.equal(formattedError) @@ -86,7 +86,7 @@ describe('reporter', () => { }) it('should remove shas', () => { - var ERROR = 'file http://localhost:8080/base/usr/file.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9 and http://127.0.0.1:8080/absolute/home/file.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9' + const ERROR = 'file http://localhost:8080/base/usr/file.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9 and http://127.0.0.1:8080/absolute/home/file.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9' expect(formatError(ERROR)).to.be.equal('file usr/file.js and http://127.0.0.1:8080/home/file.js\n') }) @@ -105,28 +105,28 @@ describe('reporter', () => { }) it('should restore absolute paths', () => { - var ERROR = 'at http://localhost:8080/absolute/usr/path.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9' + const ERROR = 'at http://localhost:8080/absolute/usr/path.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9' expect(formatError(ERROR)).to.equal('at /usr/path.js\n') }) it('should preserve line numbers', () => { - var ERROR = 'at http://localhost:8080/absolute/usr/path.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9:2' + const ERROR = 'at http://localhost:8080/absolute/usr/path.js?6e31cb249ee5b32d91f37ea516ca0f84bddc5aa9:2' expect(formatError(ERROR)).to.equal('at /usr/path.js:2\n') }) it('should preserve absolute word', () => { - var ERROR = 'contains absolute' + const ERROR = 'contains absolute' expect(formatError(ERROR)).to.equal('contains absolute\n') }) it('should preserve base word', () => { - var ERROR = 'contains base' + const ERROR = 'contains base' expect(formatError(ERROR)).to.equal('contains base\n') }) describe('source maps', () => { - var originalPositionForCallCount = 0 - var sourceMappingPath = null + let originalPositionForCallCount = 0 + let sourceMappingPath = null class MockSourceMapConsumer { constructor (sourceMap) { @@ -157,14 +157,14 @@ describe('reporter', () => { it('should rewrite stack traces', (done) => { formatError = m.createErrorFormatter({ basePath: '/some/base', hostname: 'localhost', port: 123 }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] + const servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at http://localhost:123/base/b.js:2:6' + const ERROR = 'at http://localhost:123/base/b.js:2:6' expect(formatError(ERROR)).to.equal('at /original/b.js:4:8 <- b.js:2:6\n') done() }) @@ -172,14 +172,14 @@ describe('reporter', () => { it('should rewrite stack traces (when basePath is empty)', (done) => { formatError = m.createErrorFormatter({ basePath: '', hostname: 'localhost', port: 123 }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/a.js'), new File('/b.js')] + const servedFiles = [new File('/a.js'), new File('/b.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at http://localhost:123/base/b.js:2:6' + const ERROR = 'at http://localhost:123/base/b.js:2:6' expect(formatError(ERROR)).to.equal('at /original/b.js:4:8 <- b.js:2:6\n') done() }) @@ -187,14 +187,14 @@ describe('reporter', () => { it('should rewrite stack traces to the first column when no column is given', (done) => { formatError = m.createErrorFormatter({ basePath: '/some/base', hostname: 'localhost', port: 123 }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] + const servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at http://localhost:123/base/b.js:2' + const ERROR = 'at http://localhost:123/base/b.js:2' expect(formatError(ERROR)).to.equal('at /original/b.js:4:2 <- b.js:2\n') done() }) @@ -202,14 +202,14 @@ describe('reporter', () => { it('should rewrite relative url stack traces', (done) => { formatError = m.createErrorFormatter({ basePath: '/some/base', hostname: 'localhost', port: 123 }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] + const servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at /base/b.js:2:6' + const ERROR = 'at /base/b.js:2:6' expect(formatError(ERROR)).to.equal('at /original/b.js:4:8 <- b.js:2:6\n') done() }) @@ -218,13 +218,13 @@ describe('reporter', () => { it('should resolve relative urls from source maps', (done) => { sourceMappingPath = 'original/' // Note: relative path. formatError = m.createErrorFormatter({ basePath: '/some/base' }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/some/base/path/a.js')] + const servedFiles = [new File('/some/base/path/a.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.fancyjs'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at /base/path/a.js:2:6' + const ERROR = 'at /base/path/a.js:2:6' expect(formatError(ERROR)).to.equal('at path/original/a.fancyjs:4:8 <- path/a.js:2:6\n') done() }) @@ -232,14 +232,14 @@ describe('reporter', () => { it('should fall back to non-source-map format if originalPositionFor throws', (done) => { formatError = m.createErrorFormatter({ basePath: '/some/base', hostname: 'localhost', port: 123 }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] + const servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at http://localhost:123/base/b.js:0:0' + const ERROR = 'at http://localhost:123/base/b.js:0:0' expect(formatError(ERROR)).to.equal('at b.js\n') done() }) @@ -247,14 +247,14 @@ describe('reporter', () => { it('should not try to use source maps when no line is given', (done) => { formatError = m.createErrorFormatter({ basePath: '/some/base', hostname: 'localhost', port: 123 }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] + const servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at http://localhost:123/base/b.js' + const ERROR = 'at http://localhost:123/base/b.js' expect(formatError(ERROR)).to.equal('at b.js\n') expect(originalPositionForCallCount).to.equal(0) done() @@ -263,14 +263,14 @@ describe('reporter', () => { it('should not try to match domains with spaces', (done) => { formatError = m.createErrorFormatter({ basePath: '/some/base', hostname: 'localhost', port: 9876 }, emitter, MockSourceMapConsumer) - var servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] + const servedFiles = [new File('/some/base/a.js'), new File('/some/base/b.js')] servedFiles[0].sourceMap = {content: 'SOURCE MAP a.js'} servedFiles[1].sourceMap = {content: 'SOURCE MAP b.js'} emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = '"http://localhost:9876"\n at /base/b.js:2:6' + const ERROR = '"http://localhost:9876"\n at /base/b.js:2:6' expect(formatError(ERROR)).to.equal('"http://localhost:9876"\n at /original/b.js:4:8 <- b.js:2:6\n') done() }) @@ -278,7 +278,7 @@ describe('reporter', () => { describe('Windows', () => { formatError = null - var servedFiles = null + let servedFiles = null beforeEach(() => { formatError = m.createErrorFormatter({ basePath: '/some/base', hostname: 'localhost', port: 123 }, emitter, MockSourceMapConsumer) @@ -290,7 +290,7 @@ describe('reporter', () => { emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at http://localhost:123/absoluteC:/a/b/c.js:2:6' + const ERROR = 'at http://localhost:123/absoluteC:/a/b/c.js:2:6' expect(formatError(ERROR)).to.equal('at c:/original/b.js:4:8 <- C:/a/b/c.js:2:6\n') done() }) @@ -300,7 +300,7 @@ describe('reporter', () => { emitter.emit('file_list_modified', {served: servedFiles}) _.defer(() => { - var ERROR = 'at http://localhost:123/absoluteC:/a/b/c.js?da39a3ee5e6:2:6' + const ERROR = 'at http://localhost:123/absoluteC:/a/b/c.js?da39a3ee5e6:2:6' expect(formatError(ERROR)).to.equal('at c:/original/b.js:4:8 <- C:/a/b/c.js:2:6\n') done() }) diff --git a/test/unit/reporters/progress.spec.js b/test/unit/reporters/progress.spec.js index 6459c6bea..6d924bd15 100644 --- a/test/unit/reporters/progress.spec.js +++ b/test/unit/reporters/progress.spec.js @@ -1,9 +1,9 @@ describe('reporter', function () { - var ProgressReporter = require('../../../lib/reporters/progress') + const ProgressReporter = require('../../../lib/reporters/progress') describe('Progress', function () { - var reporter - var formatError + let reporter + let formatError beforeEach(function () { formatError = sinon.spy() diff --git a/test/unit/runner.spec.js b/test/unit/runner.spec.js index 064be9aea..5c05fa044 100644 --- a/test/unit/runner.spec.js +++ b/test/unit/runner.spec.js @@ -1,35 +1,35 @@ -var loadFile = require('mocks').loadFile -var path = require('path') +const loadFile = require('mocks').loadFile +const path = require('path') -var constant = require('../../lib/constants') +const constant = require('../../lib/constants') describe('runner', () => { - var m + let m beforeEach(() => { m = loadFile(path.join(__dirname, '/../../lib/runner.js')) }) describe('parseExitCode', () => { - var EXIT = constant.EXIT_CODE + const EXIT = constant.EXIT_CODE it('should return 0 exit code if present in the buffer', () => { - var result = m.parseExitCode(new Buffer(`something\nfake${EXIT}10`)) // eslint-disable-line node/no-deprecated-api + const result = m.parseExitCode(new Buffer(`something\nfake${EXIT}10`)) // eslint-disable-line node/no-deprecated-api expect(result.exitCode).to.equal(0) }) it('should remove the exit code part of the returned buffer', () => { - var buffer = new Buffer(`some${EXIT}01`) // eslint-disable-line node/no-deprecated-api - var result = m.parseExitCode(buffer) + const buffer = new Buffer(`some${EXIT}01`) // eslint-disable-line node/no-deprecated-api + const result = m.parseExitCode(buffer) expect(buffer.toString()).to.equal(`some${EXIT}01`) expect(result.buffer.toString()).to.equal('some') }) it('should not touch buffer without exit code and return default', () => { - var msg = 'some nice \n messgae {}' - var buffer = new Buffer(msg) // eslint-disable-line node/no-deprecated-api - var result = m.parseExitCode(buffer, 10) + const msg = 'some nice \n messgae {}' + const buffer = new Buffer(msg) // eslint-disable-line node/no-deprecated-api + const result = m.parseExitCode(buffer, 10) expect(result.buffer.toString()).to.equal(msg) expect(result.buffer).to.equal(buffer) @@ -38,7 +38,7 @@ describe('runner', () => { it('should not slice buffer if smaller than exit code msg', () => { // regression - var fakeBuffer = {length: 1, slice: () => null} + const fakeBuffer = {length: 1, slice: () => null} sinon.stub(fakeBuffer, 'slice') m.parseExitCode(fakeBuffer, 10) @@ -47,8 +47,8 @@ describe('runner', () => { it('should return same buffer if smaller than exit code msg', () => { // regression - var fakeBuffer = {length: 1, slice: () => null} - var result = m.parseExitCode(fakeBuffer, 10) + const fakeBuffer = {length: 1, slice: () => null} + const result = m.parseExitCode(fakeBuffer, 10) expect(fakeBuffer).to.equal(result.buffer) }) diff --git a/test/unit/server.spec.js b/test/unit/server.spec.js index fcd2f9b61..3f0b7f909 100644 --- a/test/unit/server.spec.js +++ b/test/unit/server.spec.js @@ -1,22 +1,22 @@ -var Server = require('../../lib/server') -var BundleUtils = require('../../lib/utils/bundle-utils') -var NetUtils = require('../../lib/utils/net-utils') -var BrowserCollection = require('../../lib/browser_collection') +const Server = require('../../lib/server') +const BundleUtils = require('../../lib/utils/bundle-utils') +const NetUtils = require('../../lib/utils/net-utils') +const BrowserCollection = require('../../lib/browser_collection') describe('server', () => { - var mockConfig - var browserCollection - var webServerOnError - var fileListOnReject - var mockLauncher - var mockWebServer - var mockSocketServer - var mockBoundServer - var mockExecutor - var doneSpy - var server = mockConfig = browserCollection = webServerOnError = null - var fileListOnResolve = fileListOnReject = mockLauncher = null - var mockFileList = mockWebServer = mockSocketServer = mockExecutor = doneSpy = null + let mockConfig + let browserCollection + let webServerOnError + let fileListOnReject + let mockLauncher + let mockWebServer + let mockSocketServer + let mockBoundServer + let mockExecutor + let doneSpy + let server = mockConfig = browserCollection = webServerOnError = null + let fileListOnResolve = fileListOnReject = mockLauncher = null + let mockFileList = mockWebServer = mockSocketServer = mockExecutor = doneSpy = null // Use regular function not arrow so 'this' is mocha 'this'. beforeEach(function () { @@ -94,7 +94,7 @@ describe('server', () => { } }, listen: sinon.spy((port, arg2, arg3) => { - var callback = null + let callback = null if (typeof arg2 === 'function') { callback = arg2 } else if (typeof arg3 === 'function') { @@ -115,7 +115,7 @@ describe('server', () => { }) describe('start', () => { - var config + let config beforeEach(() => { config = { port: 9876, listenAddress: '127.0.0.1' } sinon.spy(BundleUtils, 'bundleResourceIfNotExist') @@ -203,7 +203,7 @@ describe('server', () => { it('should emit a listening event once server begin accepting connections', () => { server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) - var listening = sinon.spy() + const listening = sinon.spy() server.on('listening', listening) expect(listening).not.to.have.been.called @@ -215,7 +215,7 @@ describe('server', () => { it('should emit a browsers_ready event once all the browsers are captured', () => { server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) - var browsersReady = sinon.spy() + const browsersReady = sinon.spy() server.on('browsers_ready', browsersReady) mockLauncher.areAllCaptured = () => false @@ -230,7 +230,7 @@ describe('server', () => { it('should emit a browser_register event for each browser added', () => { server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) - var browsersReady = sinon.spy() + const browsersReady = sinon.spy() server.on('browsers_ready', browsersReady) mockLauncher.areAllCaptured = () => false diff --git a/test/unit/watcher.spec.js b/test/unit/watcher.spec.js index a3bec71bd..9a9dc5e6c 100644 --- a/test/unit/watcher.spec.js +++ b/test/unit/watcher.spec.js @@ -1,13 +1,13 @@ -var mocks = require('mocks') -var path = require('path') +const mocks = require('mocks') +const path = require('path') describe('watcher', () => { - var config = require('../../lib/config') + const config = require('../../lib/config') - var m = null + let m = null beforeEach(() => { - var mocks_ = {chokidar: mocks.chokidar} + const mocks_ = {chokidar: mocks.chokidar} m = mocks.loadFile(path.join(__dirname, '/../../lib/watcher.js'), mocks_) }) @@ -43,7 +43,7 @@ describe('watcher', () => { }) describe('watchPatterns', () => { - var chokidarWatcher = null + let chokidarWatcher = null beforeEach(() => { chokidarWatcher = new mocks.chokidar.FSWatcher() @@ -88,7 +88,7 @@ describe('watcher', () => { describe('getWatchedPatterns', () => { it('should return list of watched patterns (strings)', () => { - var watchedPatterns = m.getWatchedPatterns([ + const watchedPatterns = m.getWatchedPatterns([ config.createPatternObject('/watched.js'), config.createPatternObject({pattern: 'non/*.js', watched: false}) ]) @@ -97,24 +97,24 @@ describe('watcher', () => { }) describe('ignore', () => { - var FILE_STAT = { + const FILE_STAT = { isDirectory: () => false, isFile: () => true } - var DIRECTORY_STAT = { + const DIRECTORY_STAT = { isDirectory: () => true, isFile: () => false } it('should ignore all files', () => { - var ignore = m.createIgnore(['**/*'], ['**/*']) + const ignore = m.createIgnore(['**/*'], ['**/*']) expect(ignore('/some/files/deep/nested.js', FILE_STAT)).to.equal(true) expect(ignore('/some/files', FILE_STAT)).to.equal(true) }) it('should ignore .# files', () => { - var ignore = m.createIgnore(['**/*'], ['**/.#*']) + const ignore = m.createIgnore(['**/*'], ['**/.#*']) expect(ignore('/some/files/deep/nested.js', FILE_STAT)).to.equal(false) expect(ignore('/some/files', FILE_STAT)).to.equal(false) expect(ignore('/some/files/deep/.npm', FILE_STAT)).to.equal(false) @@ -123,20 +123,20 @@ describe('watcher', () => { }) it('should ignore files that do not match any pattern', () => { - var ignore = m.createIgnore(['/some/*.js'], []) + const ignore = m.createIgnore(['/some/*.js'], []) expect(ignore('/a.js', FILE_STAT)).to.equal(true) expect(ignore('/some.js', FILE_STAT)).to.equal(true) expect(ignore('/some/a.js', FILE_STAT)).to.equal(false) }) it('should not ignore directories', () => { - var ignore = m.createIgnore(['**/*'], ['**/*']) + const ignore = m.createIgnore(['**/*'], ['**/*']) expect(ignore('/some/dir', DIRECTORY_STAT)).to.equal(false) }) it('should not ignore items without stat', () => { // before we know whether it's a directory or file, we can't ignore - var ignore = m.createIgnore(['**/*'], ['**/*']) + const ignore = m.createIgnore(['**/*'], ['**/*']) expect(ignore('/some.js', undefined)).to.equal(false) expect(ignore('/what/ever', undefined)).to.equal(false) }) diff --git a/test/unit/web-server.spec.js b/test/unit/web-server.spec.js index e7ceadc60..0959748b7 100644 --- a/test/unit/web-server.spec.js +++ b/test/unit/web-server.spec.js @@ -1,18 +1,18 @@ -var EventEmitter = require('events').EventEmitter -var request = require('supertest') -var di = require('di') -var mocks = require('mocks') -var fs = require('fs') -var mime = require('mime') -var path = require('path') +const EventEmitter = require('events').EventEmitter +const request = require('supertest') +const di = require('di') +const mocks = require('mocks') +const fs = require('fs') +const mime = require('mime') +const path = require('path') describe('web-server', () => { - var server - var emitter - var File = require('../../lib/file') + let server + let emitter + const File = require('../../lib/file') - var _mocks = {} - var _globals = {__dirname: '/karma/lib'} + const _mocks = {} + const _globals = {__dirname: '/karma/lib'} _mocks['graceful-fs'] = mocks.fs.create({ karma: { @@ -30,11 +30,11 @@ describe('web-server', () => { // NOTE(vojta): only loading once, to speed things up // this relies on the fact that none of these tests mutate fs - var m = mocks.loadFile(path.join(__dirname, '/../../lib/web-server.js'), _mocks, _globals) - var customFileHandlers = server = emitter = null - var beforeMiddlewareActive = false - var middlewareActive = false - var servedFiles = (files) => { + const m = mocks.loadFile(path.join(__dirname, '/../../lib/web-server.js'), _mocks, _globals) + let customFileHandlers = server = emitter = null + let beforeMiddlewareActive = false + let middlewareActive = false + const servedFiles = (files) => { emitter.emit('file_list_modified', {included: [], served: files}) } @@ -42,7 +42,7 @@ describe('web-server', () => { beforeEach(() => { customFileHandlers = [] emitter = new EventEmitter() - var config = { + const config = { basePath: '/base/path', urlRoot: '/', beforeMiddleware: ['beforeCustom'], @@ -55,7 +55,7 @@ describe('web-server', () => { } } - var injector = new di.Injector([{ + const injector = new di.Injector([{ config: ['value', config], customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], @@ -210,7 +210,7 @@ describe('web-server', () => { describe('https', () => { beforeEach(() => { - var credentials = { + const credentials = { key: fs.readFileSync(path.join(__dirname, '/certificates/server.key')), cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } @@ -218,7 +218,7 @@ describe('web-server', () => { customFileHandlers = [] emitter = new EventEmitter() - var injector = new di.Injector([{ + const injector = new di.Injector([{ config: ['value', { basePath: '/base/path', urlRoot: '/', @@ -258,10 +258,10 @@ describe('web-server', () => { }) describe('http2', () => { - var http2 = require('http2/') + const http2 = require('http2/') beforeEach(() => { - var credentials = { + const credentials = { key: fs.readFileSync(path.join(__dirname, '/certificates/server.key')), cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } @@ -269,7 +269,7 @@ describe('web-server', () => { customFileHandlers = [] emitter = new EventEmitter() - var injector = new di.Injector([{ + const injector = new di.Injector([{ config: ['value', {basePath: '/base/path', urlRoot: '/', httpModule: http2, protocol: 'https:', httpsServerOptions: credentials}], customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], From f68087c0f243dba2abe6f2164635eb6dce6fa02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Wed, 3 Oct 2018 20:09:24 +0200 Subject: [PATCH 041/374] refactor(launcher): use this directly instead assign to self variable in base launcher (#3157) --- lib/launchers/base.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/launchers/base.js b/lib/launchers/base.js index 865f86749..84db9d926 100644 --- a/lib/launchers/base.js +++ b/lib/launchers/base.js @@ -32,7 +32,6 @@ function BaseLauncher (id, emitter) { this.state = null this.error = null - const self = this let killingPromise let previousUrl @@ -41,7 +40,7 @@ function BaseLauncher (id, emitter) { this.error = null this.state = BEING_CAPTURED - this.emit('start', url + '?id=' + this.id + (helper.isDefined(self.displayName) ? '&displayName=' + encodeURIComponent(self.displayName) : '')) + this.emit('start', url + '?id=' + this.id + (helper.isDefined(this.displayName) ? '&displayName=' + encodeURIComponent(this.displayName) : '')) } this.kill = function () { @@ -50,8 +49,8 @@ function BaseLauncher (id, emitter) { return killingPromise } - killingPromise = this.emitAsync('kill').then(function () { - self.state = FINISHED + killingPromise = this.emitAsync('kill').then(() => { + this.state = FINISHED }) this.state = BEING_KILLED @@ -75,17 +74,17 @@ function BaseLauncher (id, emitter) { killingPromise = this.emitAsync('kill') } - killingPromise.then(function () { - if (self.state === BEING_FORCE_KILLED) { - self.state = FINISHED + killingPromise.then(() => { + if (this.state === BEING_FORCE_KILLED) { + this.state = FINISHED } else { killingPromise = null - log.debug('Restarting %s', self.name) - self.start(previousUrl) + log.debug('Restarting %s', this.name) + this.start(previousUrl) } }) - self.state = RESTARTING + this.state = RESTARTING } this.markCaptured = function () { From cb19de67b00a54d4886dbedc2468280d0d2dbe73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Thu, 4 Oct 2018 01:34:15 +0200 Subject: [PATCH 042/374] refactor(launcher): use this directly instead assign to self variable in capture_timeout launcher (#3158) --- lib/launchers/capture_timeout.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/launchers/capture_timeout.js b/lib/launchers/capture_timeout.js index d195740c7..549623ffb 100644 --- a/lib/launchers/capture_timeout.js +++ b/lib/launchers/capture_timeout.js @@ -8,23 +8,22 @@ function CaptureTimeoutLauncher (timer, captureTimeout) { return } - const self = this let pendingTimeoutId = null - this.on('start', function () { - pendingTimeoutId = timer.setTimeout(function () { + this.on('start', () => { + pendingTimeoutId = timer.setTimeout(() => { pendingTimeoutId = null - if (self.state !== self.STATE_BEING_CAPTURED) { + if (this.state !== this.STATE_BEING_CAPTURED) { return } - log.warn('%s have not captured in %d ms, killing.', self.name, captureTimeout) - self.error = 'timeout' - self.kill() + log.warn('%s have not captured in %d ms, killing.', this.name, captureTimeout) + this.error = 'timeout' + this.kill() }, captureTimeout) }) - this.on('done', function () { + this.on('done', () => { if (pendingTimeoutId) { timer.clearTimeout(pendingTimeoutId) pendingTimeoutId = null From 18a750d936936366cadc241613ee536ba67701f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Thu, 4 Oct 2018 01:35:09 +0200 Subject: [PATCH 043/374] refactor(launcher): use this directly instead assign to self variable in retry launcher (#3159) --- lib/launchers/retry.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/launchers/retry.js b/lib/launchers/retry.js index 646e90bd4..143430571 100644 --- a/lib/launchers/retry.js +++ b/lib/launchers/retry.js @@ -1,24 +1,22 @@ const log = require('../logger').create('launcher') function RetryLauncher (retryLimit) { - const self = this - this._retryLimit = retryLimit - this.on('done', function () { - if (!self.error) { + this.on('done', () => { + if (!this.error) { return } - if (self._retryLimit > 0) { - const attempt = retryLimit - self._retryLimit + 1 - log.info('Trying to start %s again (%d/%d).', self.name, attempt, retryLimit) - self.restart() - self._retryLimit-- - } else if (self._retryLimit === 0) { - log.error('%s failed %d times (%s). Giving up.', self.name, retryLimit, self.error) + if (this._retryLimit > 0) { + const attempt = retryLimit - this._retryLimit + 1 + log.info('Trying to start %s again (%d/%d).', this.name, attempt, retryLimit) + this.restart() + this._retryLimit-- + } else if (this._retryLimit === 0) { + log.error('%s failed %d times (%s). Giving up.', this.name, retryLimit, this.error) } else { - log.debug('%s failed (%s). Not restarting.', self.name, self.error) + log.debug('%s failed (%s). Not restarting.', this.name, this.error) } }) } From 637b55310db4de42f0f0902d0820fdbfdf7bbe48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Thu, 4 Oct 2018 01:38:08 +0200 Subject: [PATCH 044/374] refactor(middleware): get rid of util.format (#3160) --- lib/middleware/karma.js | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 32f6660d9..7b14463be 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -12,7 +12,6 @@ */ const path = require('path') -const util = require('util') const url = require('url') const _ = require('lodash') @@ -28,10 +27,6 @@ function urlparse (urlStr) { const common = require('./common') const VERSION = require('../constants').VERSION -const SCRIPT_TAG = '' -const CROSSORIGIN_ATTRIBUTE = 'crossorigin="anonymous"' -const LINK_TAG_CSS = '' -const LINK_TAG_HTML = '' const SCRIPT_TYPE = { 'js': 'text/javascript', 'dart': 'application/dart', @@ -202,12 +197,12 @@ function createKarmaMiddleware ( scriptUrls.push(filePath) if (fileType === 'css' || (!fileType && fileExt === '.css')) { - scriptTags.push(util.format(LINK_TAG_CSS, filePath)) + scriptTags.push(``) continue } if (fileType === 'html' || (!fileType && fileExt === '.html')) { - scriptTags.push(util.format(LINK_TAG_HTML, filePath)) + scriptTags.push(``) continue } @@ -215,8 +210,8 @@ function createKarmaMiddleware ( const scriptFileType = (fileType || fileExt.substring(1)) const scriptType = (SCRIPT_TYPE[scriptFileType] || 'text/javascript') - const crossOriginAttribute = includeCrossOriginAttribute ? CROSSORIGIN_ATTRIBUTE : '' - scriptTags.push(util.format(SCRIPT_TAG, scriptType, filePath, crossOriginAttribute)) + const crossOriginAttribute = includeCrossOriginAttribute ? 'crossorigin="anonymous"' : '' + scriptTags.push(``) } // TODO(vojta): don't compute if it's not in the template @@ -227,7 +222,7 @@ function createKarmaMiddleware ( // double quotes should not be allowed! filePath = filePath.replace(/'/g, '\\\'') - return util.format(" '%s': '%s'", filePath, file.sha) + return ` '${filePath}': '${file.sha}'` }) const clientConfig = 'window.__karma__.config = ' + JSON.stringify(client) + ';\n' From c097ecfecac2b4a2f7998e7b27c5beb99a88fc3b Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 4 Oct 2018 16:43:10 -0700 Subject: [PATCH 045/374] fix(test/client): revert const/let changes. We still test in IE9/10 where the var is king. --- test/client/karma.conf.js | 6 +-- test/client/karma.spec.js | 80 +++++++++++++++++------------------ test/client/mocks.js | 8 ++-- test/client/stringify.spec.js | 28 ++++++------ test/client/util.spec.js | 7 +-- 5 files changed, 65 insertions(+), 64 deletions(-) diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index 4536e62e5..4422ca7cb 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -1,6 +1,6 @@ -const TRAVIS_WITHOUT_BS = process.env.TRAVIS_SECURE_ENV_VARS === 'false' +var TRAVIS_WITHOUT_BS = process.env.TRAVIS_SECURE_ENV_VARS === 'false' -const launchers = { +var launchers = { bs_chrome: { base: 'BrowserStack', browser: 'chrome', @@ -59,7 +59,7 @@ const launchers = { // } } -let browsers = [] +var browsers = [] if (process.env.TRAVIS) { if (TRAVIS_WITHOUT_BS) { diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index 13bd441ec..776d1da06 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -1,15 +1,15 @@ // shim all the things require('core-js/es5') global.JSON = require('json3') -const sinon = require('sinon') -const assert = require('assert') +var sinon = require('sinon') +var assert = require('assert') -const ClientKarma = require('../../client/karma') -const ContextKarma = require('../../context/karma') -const MockSocket = require('./mocks').Socket +var ClientKarma = require('../../client/karma') +var ContextKarma = require('../../context/karma') +var MockSocket = require('./mocks').Socket describe('Karma', function () { - let socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow + var socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow function setTransportTo (transportName) { socket._setTransportNameTo(transportName) @@ -33,7 +33,7 @@ describe('Karma', function () { }) it('should start execution when all files loaded and pass config', function () { - const config = ck.config = { + var config = ck.config = { useIframe: true } @@ -45,7 +45,7 @@ describe('Karma', function () { }) it('should open a new window when useIFrame is false', function () { - const config = ck.config = { + var config = ck.config = { useIframe: false, runInParent: false } @@ -85,13 +85,13 @@ describe('Karma', function () { }) it('should not set up context if there was an error', function () { - const config = ck.config = { + var config = ck.config = { clearContext: true } socket.emit('execute', config) - const mockWindow = {} + var mockWindow = {} ck.error('page reload') ck.setupContext(mockWindow) @@ -101,13 +101,13 @@ describe('Karma', function () { }) it('should setup context if there was error but clearContext config is false', function () { - const config = ck.config = { + var config = ck.config = { clearContext: false } socket.emit('execute', config) - const mockWindow = {} + var mockWindow = {} ck.error('page reload') ck.setupContext(mockWindow) @@ -118,11 +118,11 @@ describe('Karma', function () { it('should error out if a script attempted to reload the browser after setup', function () { // Perform setup - const config = ck.config = { + var config = ck.config = { clearContext: true } socket.emit('execute', config) - const mockWindow = {} + var mockWindow = {} ck.setupContext(mockWindow) // Spy on our error handler @@ -136,7 +136,7 @@ describe('Karma', function () { }) it('should report navigator name', function () { - const spyInfo = sinon.spy(function (info) { + var spyInfo = sinon.spy(function (info) { assert(info.name === 'Fake browser name') }) @@ -153,7 +153,7 @@ describe('Karma', function () { socket = new MockSocket() k = new ClientKarma(socket, {}, windowStub, windowNavigator, windowLocation) - const spyInfo = sinon.spy(function (info) { + var spyInfo = sinon.spy(function (info) { assert(info.id === '567') }) @@ -165,13 +165,13 @@ describe('Karma', function () { describe('result', function () { it('should buffer results when polling', function () { - const spyResult = sinon.stub() + var spyResult = sinon.stub() socket.on('result', spyResult) setTransportTo('polling') // emit 49 results - for (let i = 1; i < 50; i++) { + for (var i = 1; i < 50; i++) { ck.result({id: i}) } @@ -183,13 +183,13 @@ describe('Karma', function () { }) it('should buffer results when polling', function () { - const spyResult = sinon.stub() + var spyResult = sinon.stub() socket.on('result', spyResult) setTransportTo('polling') // emit 40 results - for (let i = 1; i <= 40; i++) { + for (var i = 1; i <= 40; i++) { ck.result({id: i}) } @@ -199,7 +199,7 @@ describe('Karma', function () { }) it('should emit "start" with total specs count first', function () { - const log = [] + var log = [] socket.on('result', function () { log.push('result') @@ -217,13 +217,13 @@ describe('Karma', function () { }) it('should not emit "start" if already done by the adapter', function () { - const log = [] + var log = [] - const spyStart = sinon.spy(function () { + var spyStart = sinon.spy(function () { log.push('start') }) - const spyResult = sinon.spy(function () { + var spyResult = sinon.spy(function () { log.push('result') }) @@ -243,7 +243,7 @@ describe('Karma', function () { it('should capture alert', function () { sinon.spy(ck, 'log') - const mockWindow = { + var mockWindow = { alert: function () { throw new Error('Alert was not patched!') } @@ -256,9 +256,9 @@ describe('Karma', function () { it('should capture confirm', function () { sinon.spy(ck, 'log') - let confirmCalled = false + var confirmCalled = false - const mockWindow = { + var mockWindow = { confirm: function () { confirmCalled = true return true @@ -266,7 +266,7 @@ describe('Karma', function () { } ck.setupContext(mockWindow) - const confirmResult = mockWindow.confirm('What?') + var confirmResult = mockWindow.confirm('What?') assert(ck.log.calledWith('confirm', ['What?'])) assert.equal(confirmCalled, true) assert.equal(confirmResult, true) @@ -274,9 +274,9 @@ describe('Karma', function () { it('should capture prompt', function () { sinon.spy(ck, 'log') - let promptCalled = false + var promptCalled = false - const mockWindow = { + var mockWindow = { prompt: function () { promptCalled = true return 'user-input' @@ -284,7 +284,7 @@ describe('Karma', function () { } ck.setupContext(mockWindow) - const promptResult = mockWindow.prompt('What is your favorite color?', 'blue') + var promptResult = mockWindow.prompt('What is your favorite color?', 'blue') assert(ck.log.calledWith('prompt', ['What is your favorite color?', 'blue'])) assert.equal(promptCalled, true) assert.equal(promptResult, 'user-input') @@ -292,7 +292,7 @@ describe('Karma', function () { }) describe('complete', function () { - let clock + var clock before(function () { clock = sinon.useFakeTimers() @@ -303,13 +303,13 @@ describe('Karma', function () { }) it('should clean the result buffer before completing', function () { - const spyResult = sinon.stub() + var spyResult = sinon.stub() socket.on('result', spyResult) setTransportTo('polling') // emit 40 results - for (let i = 0; i < 40; i++) { + for (var i = 0; i < 40; i++) { ck.result({id: i}) } @@ -347,7 +347,7 @@ describe('Karma', function () { sinon.spy(ck, 'log') ck.config.captureConsole = true - const mockWindow = { + var mockWindow = { console: { log: function () {} } @@ -363,7 +363,7 @@ describe('Karma', function () { sinon.spy(ck, 'log') ck.config.captureConsole = false - const mockWindow = { + var mockWindow = { console: { log: function () {} } @@ -375,12 +375,12 @@ describe('Karma', function () { }) it('should clear context window upon complete when clearContext config is true', function () { - const config = ck.config = { + var config = ck.config = { clearContext: true } socket.emit('execute', config) - const CURRENT_URL = iframe.src + var CURRENT_URL = iframe.src ck.complete() @@ -392,12 +392,12 @@ describe('Karma', function () { }) it('should not clear context window upon complete when clearContext config is false', function () { - const config = ck.config = { + var config = ck.config = { clearContext: false } socket.emit('execute', config) - const CURRENT_URL = iframe.src + var CURRENT_URL = iframe.src ck.complete() diff --git a/test/client/mocks.js b/test/client/mocks.js index 5239acca8..f49357d21 100644 --- a/test/client/mocks.js +++ b/test/client/mocks.js @@ -1,5 +1,5 @@ function Emitter () { - const listeners = {} + var listeners = {} this.on = function (event, fn) { if (!listeners[event]) { @@ -10,11 +10,11 @@ function Emitter () { } this.emit = function (event) { - const eventListeners = listeners[event] + var eventListeners = listeners[event] if (!eventListeners) return - let i = 0 + var i = 0 while (i < eventListeners.length) { eventListeners[i].apply(null, Array.prototype.slice.call(arguments, 1)) i++ @@ -27,7 +27,7 @@ function MockSocket () { this.socket = {transport: {name: 'websocket'}} - let transportName = 'websocket' + var transportName = 'websocket' this.io = { engine: { diff --git a/test/client/stringify.spec.js b/test/client/stringify.spec.js index 01f57ff65..aaeea7dd0 100644 --- a/test/client/stringify.spec.js +++ b/test/client/stringify.spec.js @@ -1,7 +1,7 @@ /* global __karma__ */ -const assert = require('assert') +var assert = require('assert') -const stringify = require('../../common/stringify') +var stringify = require('../../common/stringify') describe('stringify', function () { if (window && window.Symbol) { @@ -30,15 +30,15 @@ describe('stringify', function () { function abc (a, b, c) { return 'whatever' } function def (d, e, f) { return 'whatever' } - const abcString = stringify(abc) - const partsAbc = ['function', 'abc', '(a, b, c)', '{ ... }'] - const partsDef = ['function', '(d, e, f)', '{ ... }'] + var abcString = stringify(abc) + var partsAbc = ['function', 'abc', '(a, b, c)', '{ ... }'] + var partsDef = ['function', '(d, e, f)', '{ ... }'] partsAbc.forEach(function (part) { assert(abcString.indexOf(part) > -1) }) - const defString = stringify(def) + var defString = stringify(def) partsDef.forEach(function (part) { assert(defString.indexOf(part) > -1) }) @@ -48,7 +48,7 @@ describe('stringify', function () { // http://caniuse.com/#feat=proxy if (window.Proxy) { it('should serialize proxied functions', function () { - const defProxy = new Proxy(function (d, e, f) { return 'whatever' }, {}) + var defProxy = new Proxy(function (d, e, f) { return 'whatever' }, {}) assert.deepEqual(stringify(defProxy), 'function () { ... }') }) } @@ -58,7 +58,7 @@ describe('stringify', function () { }) it('should serialize objects', function () { - let obj + var obj obj = {a: 'a', b: 'b', c: null, d: true, e: false} assert(stringify(obj).indexOf("{a: 'a', b: 'b', c: null, d: true, e: false}") > -1) @@ -73,7 +73,7 @@ describe('stringify', function () { obj = {constructor: null} // IE 7 serializes this to Object{} - const s = stringify(obj) + var s = stringify(obj) assert(s.indexOf('{constructor: null}') > -1 || s.indexOf('Object{}') > -1) obj = Object.create(null) @@ -83,7 +83,7 @@ describe('stringify', function () { }) it('should serialize html', function () { - const div = document.createElement('div') + var div = document.createElement('div') assert.deepEqual(stringify(div).trim().toLowerCase(), '
    ') @@ -92,21 +92,21 @@ describe('stringify', function () { }) it('should serialize error', function () { - const error = new TypeError('Error description') + var error = new TypeError('Error description') assert(stringify(error).indexOf('Error description') > -1) }) it('should serialize DOMParser objects', function () { if (typeof DOMParser !== 'undefined') { // Test only works in IE 9 and above - const parser = new DOMParser() - const doc = parser.parseFromString('', 'application/xml') + var parser = new DOMParser() + var doc = parser.parseFromString('', 'application/xml') assert.deepEqual(stringify(doc), '') } }) it('should serialize across iframes', function () { - const div = document.createElement('div') + var div = document.createElement('div') assert.deepEqual(__karma__.stringify(div).trim().toLowerCase(), '
    ') assert.deepEqual(__karma__.stringify([1, 2]), '[1, 2]') diff --git a/test/client/util.spec.js b/test/client/util.spec.js index 1d2377c05..035ffc49b 100644 --- a/test/client/util.spec.js +++ b/test/client/util.spec.js @@ -1,9 +1,10 @@ -const assert = require('assert') -const util = require('../../common/util') +var assert = require('assert') + +var util = require('../../common/util') describe('util', function () { it('parseQueryParams', function () { - const params = util.parseQueryParams('?id=123&return_url=http://whatever.com') + var params = util.parseQueryParams('?id=123&return_url=http://whatever.com') assert.deepEqual(params, {id: '123', return_url: 'http://whatever.com'}) }) From 873e4f9dc6b0ff4e6117f101ce8b93ea254d7d2b Mon Sep 17 00:00:00 2001 From: Georgii Dolzhykov Date: Wed, 25 Jul 2018 11:58:22 +0300 Subject: [PATCH 046/374] fix: work around broken console methods Sometimes console methods are broken, but this shouldn't break tests. See https://github.com/angular/angular.js/pull/16644#issuecomment-407680658 --- context/karma.js | 6 ++- test/client/karma.spec.js | 82 ++++++++++++++++++++++++--------------- 2 files changed, 56 insertions(+), 32 deletions(-) diff --git a/context/karma.js b/context/karma.js index 4ce54cb52..a013b2adb 100644 --- a/context/karma.js +++ b/context/karma.js @@ -122,7 +122,11 @@ function ContextKarma (callParentKarmaMethod) { } localConsole[method] = function () { self.log(method, arguments) - return Function.prototype.apply.call(orig, localConsole, arguments) + try { + return Function.prototype.apply.call(orig, localConsole, arguments) + } catch (error) { + self.log('warn', ['Console method ' + method + ' threw: ' + error]) + } } } for (var i = 0; i < logMethods.length; i++) { diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index 776d1da06..bb933c0f6 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -289,6 +289,57 @@ describe('Karma', function () { assert.equal(promptCalled, true) assert.equal(promptResult, 'user-input') }) + + it('should patch the console if captureConsole is true', function () { + sinon.spy(ck, 'log') + ck.config.captureConsole = true + + var mockWindow = { + console: { + log: function () {} + } + } + + ck.setupContext(mockWindow) + mockWindow.console.log('What?') + assert(ck.log.calledWith('log')) + assert(ck.log.args[0][1][0] === 'What?') + }) + + it('should not patch the console if captureConsole is false', function () { + sinon.spy(ck, 'log') + ck.config.captureConsole = false + + var mockWindow = { + console: { + log: function () {} + } + } + + ck.setupContext(mockWindow) + mockWindow.console.log('hello') + assert(!ck.log.called) + }) + + it('should not allow broken console methods to break tests (if captureConsole is true)', function () { + sinon.spy(ck, 'log') + ck.config.captureConsole = true + + var mockWindow = { + console: { + log: function () { + throw new Error('I am a broken console.log method.') + } + } + } + + ck.setupContext(mockWindow) + mockWindow.console.log('What?') + assert(ck.log.calledWith('log')) + assert.equal(ck.log.args[0][1][0], 'What?') + assert(ck.log.calledWith('warn')) + assert(/^Console method log threw:[\s\S]+I am a broken console\.log method/.test(ck.log.args[1][1][0])) + }) }) describe('complete', function () { @@ -343,37 +394,6 @@ describe('Karma', function () { clock.tick(10) }) - it('should patch the console if captureConsole is true', function () { - sinon.spy(ck, 'log') - ck.config.captureConsole = true - - var mockWindow = { - console: { - log: function () {} - } - } - - ck.setupContext(mockWindow) - mockWindow.console.log('What?') - assert(ck.log.calledWith('log')) - assert(ck.log.args[0][1][0] === 'What?') - }) - - it('should not patch the console if captureConsole is false', function () { - sinon.spy(ck, 'log') - ck.config.captureConsole = false - - var mockWindow = { - console: { - log: function () {} - } - } - - ck.setupContext(mockWindow) - mockWindow.console.log('hello') - assert(!ck.log.called) - }) - it('should clear context window upon complete when clearContext config is true', function () { var config = ck.config = { clearContext: true From 6d96d8e4305b40149b1cae8253887b9a73f25fc5 Mon Sep 17 00:00:00 2001 From: Filipe Silva Date: Fri, 5 Oct 2018 15:32:59 +0100 Subject: [PATCH 047/374] feat(server): Add stop method (#3153) Fix #3149 --- lib/server.js | 26 +++++++++++++++++++------- test/unit/server.spec.js | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/server.js b/lib/server.js index 045c4fee0..426f49e27 100644 --- a/lib/server.js +++ b/lib/server.js @@ -263,6 +263,11 @@ class Server extends KarmaEventEmitter { } }) + this.on('stop', function (done) { + this.log.debug('Received stop event, exiting.') + return disconnectBrowsers().then(done) + }) + if (config.singleRun) { this.on('browser_restart_failure', (completedBrowser) => { singleRunDoneBrowsers[completedBrowser.id] = true @@ -327,14 +332,17 @@ class Server extends KarmaEventEmitter { done(code || 0) } - this.emitAsync('exit').then(() => { - socketServer.sockets.removeAllListeners() - socketServer.close() - const closeTimeout = setTimeout(removeAllListeners, webServerCloseTimeout) + return this.emitAsync('exit').then(() => { + return new Promise((resolve, reject) => { + socketServer.sockets.removeAllListeners() + socketServer.close() + const closeTimeout = setTimeout(removeAllListeners, webServerCloseTimeout) - webServer.close(() => { - clearTimeout(closeTimeout) - removeAllListeners() + webServer.close(() => { + clearTimeout(closeTimeout) + removeAllListeners() + resolve() + }) }) }) } @@ -373,6 +381,10 @@ class Server extends KarmaEventEmitter { child.unref() } + stop () { + return this.emitAsync('stop') + } + static start (cliOptions, done) { console.warn('Deprecated static method to be removed in v3.0') return new Server(cliOptions, done).start() diff --git a/test/unit/server.spec.js b/test/unit/server.spec.js index 3f0b7f909..276618b12 100644 --- a/test/unit/server.spec.js +++ b/test/unit/server.spec.js @@ -152,6 +152,25 @@ describe('server', () => { }) }) + describe('start on watch mode', () => { + var config + beforeEach(() => { + config = { port: 9876, listenAddress: '127.0.0.1', singleRun: false } + sinon.spy(BundleUtils, 'bundleResourceIfNotExist') + sinon.stub(NetUtils, 'bindAvailablePort').resolves(mockBoundServer) + sinon.stub(mockBoundServer, 'address').returns({ port: 9877 }) + sinon + .stub(server, 'get') + .withArgs('config').returns(config) + }) + + it('should exit gracefully', (done) => { + server.start() + .then(() => server.stop()) + .then(() => done()) + }) + }) + // ============================================================================ // server._start() // ============================================================================ From 65ae574ef4be5a9d7fcc5022e9d8d12daed0a80f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Fri, 5 Oct 2018 16:36:10 +0200 Subject: [PATCH 048/374] refactor(server): use Array.prototype.includes/startsWitch methods instead of indexOf (#3161) --- lib/cli.js | 2 +- lib/completion.js | 4 ++-- lib/config.js | 2 +- lib/launcher.js | 4 ++-- lib/launchers/process.js | 2 +- lib/middleware/karma.js | 11 ++++------- lib/middleware/proxy.js | 10 +++------- lib/plugin.js | 6 +++--- lib/preprocessor.js | 2 +- lib/reporter.js | 6 +++--- 10 files changed, 21 insertions(+), 28 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 0d70273b8..bdfa87a55 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -23,7 +23,7 @@ function processArgs (argv, options, fs, path) { Object.getOwnPropertyNames(argv).forEach(function (name) { let argumentValue = argv[name] if (name !== '_' && name !== '$0') { - if (name.indexOf('_') !== -1) { + if (name.includes('_')) { throw new Error('Bad argument: ' + name + ' did you mean ' + name.replace('_', '-')) } if (Array.isArray(argumentValue)) { diff --git a/lib/completion.js b/lib/completion.js index 157c81611..7410502f1 100644 --- a/lib/completion.js +++ b/lib/completion.js @@ -56,8 +56,8 @@ function sendCompletionNoOptions () {} function sendCompletion (possibleWords, env) { const regexp = new RegExp('^' + env.last) const filteredWords = possibleWords.filter(function (word) { - return regexp.test(word) && env.words.indexOf(word) === -1 && - env.words.indexOf(opositeWord(word)) === -1 + return regexp.test(word) && !env.words.includes(word) && + !env.words.includes(opositeWord(word)) }) if (!filteredWords.length) { diff --git a/lib/config.js b/lib/config.js index 91ef8c76c..eee6f30a8 100644 --- a/lib/config.js +++ b/lib/config.js @@ -382,7 +382,7 @@ function parseConfig (configFilePath, cliOptions) { configModule = configModule.default } } catch (e) { - if (e.code === 'MODULE_NOT_FOUND' && e.message.indexOf(configFilePath) !== -1) { + if (e.code === 'MODULE_NOT_FOUND' && e.message.includes(configFilePath)) { log.error('File %s does not exist!', configFilePath) } else { log.error('Invalid config file!\n ' + e.stack) diff --git a/lib/launcher.js b/lib/launcher.js index f4707c4f7..2423b44e8 100644 --- a/lib/launcher.js +++ b/lib/launcher.js @@ -54,14 +54,14 @@ function Launcher (server, emitter, injector) { } // TODO(vojta): determine script from name - if (name.indexOf('/') !== -1) { + if (name.includes('/')) { name = 'Script' } try { browser = injector.createChild([locals], ['launcher:' + name]).get('launcher:' + name) } catch (e) { - if (e.message.indexOf(`No provider for "launcher:${name}"`) !== -1) { + if (e.message.includes(`No provider for "launcher:${name}"`)) { log.error(`Cannot load browser "${name}": it is not registered! Perhaps you are missing some plugin?`) } else { log.error(`Cannot load browser "${name}"!\n ` + e.stack) diff --git a/lib/launchers/process.js b/lib/launchers/process.js index bc82d0cba..78c2db3b4 100644 --- a/lib/launchers/process.js +++ b/lib/launchers/process.js @@ -43,7 +43,7 @@ function ProcessLauncher (spawn, tempDir, timer, processKillTimeout) { // Normalize the command, remove quotes (spawn does not like them). this._normalizeCommand = function (cmd) { - if (cmd.charAt(0) === cmd.charAt(cmd.length - 1) && '\'`"'.indexOf(cmd.charAt(0)) !== -1) { + if (cmd.charAt(0) === cmd.charAt(cmd.length - 1) && '\'`"'.includes(cmd.charAt(0))) { cmd = cmd.substring(1, cmd.length - 1) log.warn('The path should not be quoted.\n Normalized the path to %s', cmd) } diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 7b14463be..55a8e453d 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -41,7 +41,7 @@ const FILE_TYPES = [ ] function filePathToUrlPath (filePath, basePath, urlRoot, proxyPath) { - if (filePath.indexOf(basePath) === 0) { + if (filePath.startsWith(basePath)) { return proxyPath + urlRoot.substr(1) + 'base' + filePath.substr(basePath.length) } @@ -101,7 +101,7 @@ function createKarmaMiddleware ( } // ignore urls outside urlRoot - if (requestUrl.indexOf(urlRoot) !== 0) { + if (!requestUrl.startsWith(urlRoot)) { return next() } @@ -122,10 +122,7 @@ function createKarmaMiddleware ( } } - // serve karma.js, context.js, and debug.js - const jsFiles = ['/karma.js', '/context.js', '/debug.js'] - const isRequestingJsFile = jsFiles.indexOf(requestUrl) !== -1 - if (isRequestingJsFile) { + if (['/karma.js', '/context.js', '/debug.js'].includes(requestUrl)) { return serveStaticFile(requestUrl, requestedRangeHeader, response, function (data) { return data.replace('%KARMA_URL_ROOT%', urlRoot) .replace('%KARMA_VERSION%', VERSION) @@ -182,7 +179,7 @@ function createKarmaMiddleware ( continue } - if (!_.isUndefined(fileType) && FILE_TYPES.indexOf(fileType) === -1) { + if (!_.isUndefined(fileType) && !FILE_TYPES.includes(fileType)) { log.warn('Invalid file type, defaulting to js.', fileType) } diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index f1ced1373..c3a59b783 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -106,9 +106,7 @@ function createProxyHandler (proxies, urlRoot) { } function createProxy (request, response, next) { - const proxyRecord = _.find(proxies, function (p) { - return request.url.indexOf(p.path) === 0 - }) + const proxyRecord = _.find(proxies, (p) => request.url.startsWith(p.path)) if (!proxyRecord) { return next() @@ -121,14 +119,12 @@ function createProxyHandler (proxies, urlRoot) { createProxy.upgrade = function upgradeProxy (request, socket, head) { // special-case karma's route to avoid upgrading it - if (request.url.indexOf(urlRoot) === 0) { + if (request.url.startsWith(urlRoot)) { log.debug('NOT upgrading proxyWebSocketRequest %s', request.url) return } - const proxyRecord = _.find(proxies, function (p) { - return request.url.indexOf(p.path) === 0 - }) + const proxyRecord = _.find(proxies, (p) => request.url.startsWith(p.path)) if (!proxyRecord) { return diff --git a/lib/plugin.js b/lib/plugin.js index 253de0ef0..60a1cd24e 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -16,7 +16,7 @@ function resolve (plugins, emitter) { try { modules.push(require(name)) } catch (e) { - if (e.code === 'MODULE_NOT_FOUND' && e.message.indexOf(name) !== -1) { + if (e.code === 'MODULE_NOT_FOUND' && e.message.includes(name)) { log.error(`Cannot find plugin "${name}".\n Did you forget to install it?\n npm install ${name} --save-dev`) } else { log.error(`Error during loading "${name}" plugin:\n ${e.message}`) @@ -27,7 +27,7 @@ function resolve (plugins, emitter) { plugins.forEach(function (plugin) { if (helper.isString(plugin)) { - if (plugin.indexOf('*') === -1) { + if (!plugin.includes('*')) { requirePlugin(plugin) return } @@ -36,7 +36,7 @@ function resolve (plugins, emitter) { log.debug(`Loading ${plugin} from ${pluginDirectory}`) fs.readdirSync(pluginDirectory) - .filter((pluginName) => IGNORED_PACKAGES.indexOf(pluginName) === -1 && regexp.test(pluginName)) + .filter((pluginName) => !IGNORED_PACKAGES.includes(pluginName) && regexp.test(pluginName)) .forEach((pluginName) => requirePlugin(pluginDirectory + '/' + pluginName)) } else if (helper.isObject(plugin)) { log.debug(`Loading inlined plugin (defining ${Object.keys(plugin).join(', ')}).`) diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 713a04b06..8e1ab4f58 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -49,7 +49,7 @@ function createPreprocessor (config, basePath, injector) { try { p = injector.get('preprocessor:' + name) } catch (e) { - if (e.message.indexOf(`No provider for "preprocessor:${name}"`) !== -1) { + if (e.message.includes(`No provider for "preprocessor:${name}"`)) { log.error(`Can not load "${name}", it is not registered!\n Perhaps you are missing some plugin?`) } else { log.error(`Can not load "${name}"!\n ` + e.stack) diff --git a/lib/reporter.js b/lib/reporter.js index 925b12d41..b87898e7d 100644 --- a/lib/reporter.js +++ b/lib/reporter.js @@ -86,7 +86,7 @@ function createReporters (names, config, emitter, injector) { const reporters = [] names.forEach((name) => { - if (['dots', 'progress'].indexOf(name) !== -1) { + if (['dots', 'progress'].includes(name)) { [ require('./reporters/' + name), require('./reporters/' + name + '_color') @@ -105,7 +105,7 @@ function createReporters (names, config, emitter, injector) { log.debug('Trying to load reporter: %s', name) reporters.push(injector.createChild([locals], ['reporter:' + name]).get('reporter:' + name)) } catch (e) { - if (e.message.indexOf(`No provider for "reporter:${name}"`) !== -1) { + if (e.message.includes(`No provider for "reporter:${name}"`)) { log.error(`Can not load reporter "${name}", it is not registered!\n Perhaps you are missing some plugin?`) } else { log.error(`Can not load "${name}"!\n ${e.stack}`) @@ -115,7 +115,7 @@ function createReporters (names, config, emitter, injector) { } const colorName = name + '_color' - if (names.indexOf(colorName) === -1) { + if (!names.includes(colorName)) { try { log.debug(`Trying to load color-version of reporter: ${name} (${colorName})`) reporters.push(injector.createChild([locals], ['reporter:' + colorName]).get('reporter:' + name)) From 6db1df1117b0b2b658bbf4506ee751df9fbe86b6 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Sat, 6 Oct 2018 09:30:39 -0700 Subject: [PATCH 049/374] chore(deps): update sinon 3.x->6.x (#3114) --- package.json | 2 +- test/unit/file-list.spec.js | 30 ++++++++++----------- test/unit/launchers/base.spec.js | 10 +++---- test/unit/launchers/capture_timeout.spec.js | 2 +- test/unit/launchers/process.spec.js | 23 ++++++++-------- test/unit/launchers/retry.spec.js | 4 +-- test/unit/middleware/karma.spec.js | 6 ++--- test/unit/middleware/source_files.spec.js | 2 +- test/unit/mocha-globals.js | 2 +- test/unit/reporter.spec.js | 2 +- test/unit/utils/bundle-utils.spec.js | 2 +- 11 files changed, 43 insertions(+), 42 deletions(-) diff --git a/package.json b/package.json index 64fe2363a..38a59e6e5 100644 --- a/package.json +++ b/package.json @@ -448,7 +448,7 @@ "proxyquire": "^1.7.11", "qunitjs": "^2.1.1", "requirejs": "^2.1.20", - "sinon": "^3.0.0", + "sinon": "^6.1.5", "sinon-chai": "^2.7.0", "supertest": "^3.0.0", "timer-shim": "^0.3.0", diff --git a/test/unit/file-list.spec.js b/test/unit/file-list.spec.js index b4a99d3b6..f9eef1d51 100644 --- a/test/unit/file-list.spec.js +++ b/test/unit/file-list.spec.js @@ -506,7 +506,7 @@ describe('FileList', () => { emitter.on('file_list_modified', modified) return list.refresh().then(() => { - modified.reset() + modified.resetHistory() return list.addFile('/some/d.js').then(() => { clock.tick(101) @@ -520,7 +520,7 @@ describe('FileList', () => { // This checks that we only stat and preprocess the file once. return list.refresh().then(() => { - preprocess.reset() + preprocess.resetHistory() sinon.spy(mockFs, 'stat') return Promise.all([ @@ -547,7 +547,7 @@ describe('FileList', () => { // MATCH: /a.txt list = new List(patterns('/a.*'), [], emitter, preprocess) return list.refresh().then((files) => { - preprocess.reset() + preprocess.resetHistory() return list.addFile('/a.js').then(() => { expect(preprocess).to.have.been.calledOnce expect(preprocess.args[0][0].originalPath).to.eql('/a.js') @@ -605,7 +605,7 @@ describe('FileList', () => { return list.refresh().then((files) => { mockFs._touchFile('/some/b.js', '2020-01-01') - modified.reset() + modified.resetHistory() return list.changeFile('/some/b.js').then((files) => { clock.tick(101) @@ -624,7 +624,7 @@ describe('FileList', () => { return list.refresh().then((files) => { mockFs._touchFile('/some/b.js', '2020-01-01') - modified.reset() + modified.resetHistory() return list.changeFile('/some/b.js').then(() => { expect(modified).to.not.have.been.called @@ -642,7 +642,7 @@ describe('FileList', () => { return list.refresh().then((files) => { // not touching the file, stat will return still the same - modified.reset() + modified.resetHistory() return list.changeFile('/some/b.js').then(() => { expect(modified).not.to.have.been.called @@ -655,7 +655,7 @@ describe('FileList', () => { list = new List(patterns('/some/*.js', '/a.*'), [], emitter, preprocess) return list.refresh().then((files) => { - preprocess.reset() + preprocess.resetHistory() mockFs._touchFile('/some/a.js', '2020-01-01') return list.changeFile('/some/a.js').then(() => { expect(preprocess).to.have.been.called @@ -714,7 +714,7 @@ describe('FileList', () => { emitter.on('file_list_modified', modified) return list.refresh().then((files) => { - modified.reset() + modified.resetHistory() return list.removeFile('/some/a.js') }).then((files) => { expect(pathsFrom(files.served)).to.be.eql([ @@ -731,7 +731,7 @@ describe('FileList', () => { list = new List(patterns('/some/*.js', '/a.*'), [], emitter, preprocess) return list.refresh().then((files) => { - modified.reset() + modified.resetHistory() return list.removeFile('/a.js').then(() => { expect(modified).to.not.have.been.called }) @@ -793,7 +793,7 @@ describe('FileList', () => { list = new List(patterns(), [], emitter, preprocess, 100) return list.refresh().then(() => { - modified.reset() + modified.resetHistory() list._emitModified() clock.tick(99) expect(modified).to.not.have.been.called @@ -818,7 +818,7 @@ describe('FileList', () => { list = new List(patterns('/some/*.js', '/a.*'), [], emitter, preprocess, 100) return list.refresh().then((files) => { - modified.reset() + modified.resetHistory() // Even with no changes, all these files are served list.addFile('/some/0.js').then(() => { clock.tick(99) @@ -842,7 +842,7 @@ describe('FileList', () => { list = new List(patterns('/some/*.js', '/a.*'), [], emitter, preprocess, 100) return list.refresh().then((files) => { - modified.reset() + modified.resetHistory() list.addFile('/some/0.js').then(() => { clock.tick(99) expect(modified).to.not.have.been.called @@ -884,7 +884,7 @@ describe('FileList', () => { list = new List(patterns('/some/*.js', '/a.*'), [], emitter, preprocess, 100) return list.refresh().then((files) => { - modified.reset() + modified.resetHistory() mockFs._touchFile('/some/b.js', '2020-01-01') list.changeFile('/some/b.js') list.removeFile('/some/a.js') // /some/b.js, /a.txt @@ -920,8 +920,8 @@ describe('FileList', () => { list = new List(patterns('/a.*'), [], emitter, preprocess, 100) list.refresh().then((files) => { - preprocess.reset() - modified.reset() + preprocess.resetHistory() + modified.resetHistory() // Remove and then immediately add file to the bucket list.removeFile('/a.txt') diff --git a/test/unit/launchers/base.spec.js b/test/unit/launchers/base.spec.js index d9b383566..f6a85794d 100644 --- a/test/unit/launchers/base.spec.js +++ b/test/unit/launchers/base.spec.js @@ -39,7 +39,7 @@ describe('launchers/base.js', () => { launcher.on('kill', spyOnKill) launcher.start('http://host:9988/') - spyOnStart.reset() + spyOnStart.resetHistory() launcher.restart() expect(spyOnKill).to.have.been.called @@ -66,7 +66,7 @@ describe('launchers/base.js', () => { launcher.on('done', spyOnDone) launcher.start('http://host:9988/') - spyOnStart.reset() + spyOnStart.resetHistory() // simulate crash // the first onDone will restart @@ -88,7 +88,7 @@ describe('launchers/base.js', () => { launcher.on('kill', spyOnKill) launcher.start('http://host:9988/') - spyOnStart.reset() + spyOnStart.resetHistory() const onceKilled = launcher.forceKill() @@ -142,7 +142,7 @@ describe('launchers/base.js', () => { launcher.start('http://localhost:9876/') launcher.kill().then(() => { - spyOnKill.reset() + spyOnKill.resetHistory() launcher.kill().then(() => { expect(spyOnKill).to.not.have.been.called done() @@ -201,7 +201,7 @@ describe('launchers/base.js', () => { launcher.on('start', spyOnStart) launcher.start('http://localhost:9876/') - spyOnStart.reset() + spyOnStart.resetHistory() launcher.restart() launcher.forceKill().done(() => { diff --git a/test/unit/launchers/capture_timeout.spec.js b/test/unit/launchers/capture_timeout.spec.js index a7881439f..f5f0c6cc7 100644 --- a/test/unit/launchers/capture_timeout.spec.js +++ b/test/unit/launchers/capture_timeout.spec.js @@ -50,7 +50,7 @@ describe('launchers/capture_timeout.js', () => { launcher.start() timer.wind(8) launcher.kill().done(() => { - launcher.kill.reset() + launcher.kill.resetHistory() launcher.start() timer.wind(8) expect(launcher.kill).not.to.have.been.called diff --git a/test/unit/launchers/process.spec.js b/test/unit/launchers/process.spec.js index e9b3a158d..1cd9f0791 100644 --- a/test/unit/launchers/process.spec.js +++ b/test/unit/launchers/process.spec.js @@ -166,7 +166,7 @@ describe('launchers/process.js', () => { expect(browserProcess.kill).to.have.been.called browserProcess.emit('exit', 0) mockTempDir.remove.callArg(1) - mockSpawn.reset() + mockSpawn.resetHistory() _.defer(() => { // expect re-starting @@ -182,8 +182,9 @@ describe('launchers/process.js', () => { // expect starting expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) + let browserProcess = mockSpawn._processes.shift() - mockSpawn.reset() + mockSpawn.resetHistory() // timeout - first time mockTimer.wind(101) @@ -192,14 +193,14 @@ describe('launchers/process.js', () => { expect(browserProcess.kill).to.have.been.called browserProcess.emit('exit', 0) mockTempDir.remove.callArg(1) - mockTempDir.remove.reset() + mockTempDir.remove.resetHistory() _.defer(() => { // expect re-starting expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) browserProcess = mockSpawn._processes.shift() expect(failureSpy).not.to.have.been.called - mockSpawn.reset() + mockSpawn.resetHistory() // timeout - second time mockTimer.wind(101) @@ -208,14 +209,14 @@ describe('launchers/process.js', () => { expect(browserProcess.kill).to.have.been.called browserProcess.emit('exit', 0) mockTempDir.remove.callArg(1) - mockTempDir.remove.reset() + mockTempDir.remove.resetHistory() _.defer(() => { // expect re-starting expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) browserProcess = mockSpawn._processes.shift() expect(failureSpy).not.to.have.been.called - mockSpawn.reset() + mockSpawn.resetHistory() // timeout - third time mockTimer.wind(201) @@ -224,7 +225,7 @@ describe('launchers/process.js', () => { expect(browserProcess.kill).to.have.been.called browserProcess.emit('exit', 0) mockTempDir.remove.callArg(1) - mockTempDir.remove.reset() + mockTempDir.remove.resetHistory() _.defer(() => { expect(mockSpawn).to.not.have.been.called @@ -243,12 +244,12 @@ describe('launchers/process.js', () => { // expect starting the process expect(mockSpawn).to.have.been.calledWith(BROWSER_PATH, ['http://localhost/?id=fake-id']) let browserProcess = mockSpawn._processes.shift() - mockSpawn.reset() + mockSpawn.resetHistory() // crash browserProcess.emit('exit', 1) mockTempDir.remove.callArg(1) - mockTempDir.remove.reset() + mockTempDir.remove.resetHistory() _.defer(() => { // expect re-starting @@ -307,8 +308,8 @@ describe('launchers/process.js', () => { browserProcess.emit('exit', 0) mockTempDir.remove.callArg(1) - mockTempDir.remove.reset() - mockSpawn.reset() + mockTempDir.remove.resetHistory() + mockSpawn.resetHistory() }) }) }) diff --git a/test/unit/launchers/retry.spec.js b/test/unit/launchers/retry.spec.js index 58ebda7b6..916570224 100644 --- a/test/unit/launchers/retry.spec.js +++ b/test/unit/launchers/retry.spec.js @@ -47,7 +47,7 @@ describe('launchers/retry.js', () => { _.defer(() => { expect(launcher.start).to.have.been.called expect(spyOnBrowserProcessFailure).not.to.have.been.called - launcher.start.reset() + launcher.start.resetHistory() // simulate second crash launcher._done('crash') @@ -55,7 +55,7 @@ describe('launchers/retry.js', () => { _.defer(() => { expect(launcher.start).to.have.been.called expect(spyOnBrowserProcessFailure).not.to.have.been.called - launcher.start.reset() + launcher.start.resetHistory() // simulate third crash launcher._done('crash') diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js index 76a8e3242..6440511e0 100644 --- a/test/unit/middleware/karma.spec.js +++ b/test/unit/middleware/karma.spec.js @@ -104,15 +104,15 @@ describe('middleware.karma', () => { it('should not serve outside of urlRoot', () => { handler(normalizedHttpRequest('/'), null, nextSpy) expect(nextSpy).to.have.been.called - nextSpy.reset() + nextSpy.resetHistory() handler(normalizedHttpRequest('/client.html'), null, nextSpy) expect(nextSpy).to.have.been.called - nextSpy.reset() + nextSpy.resetHistory() handler(normalizedHttpRequest('/debug.html'), null, nextSpy) expect(nextSpy).to.have.been.called - nextSpy.reset() + nextSpy.resetHistory() handler(normalizedHttpRequest('/context.html'), null, nextSpy) expect(nextSpy).to.have.been.called diff --git a/test/unit/middleware/source_files.spec.js b/test/unit/middleware/source_files.spec.js index cab8cc8da..afa1e671c 100644 --- a/test/unit/middleware/source_files.spec.js +++ b/test/unit/middleware/source_files.spec.js @@ -57,7 +57,7 @@ describe('middleware.source_files', function () { }) afterEach(function () { - return next.reset() + return next.resetHistory() }) function servedFiles (list) { diff --git a/test/unit/mocha-globals.js b/test/unit/mocha-globals.js index d36874b32..d2905e56e 100644 --- a/test/unit/mocha-globals.js +++ b/test/unit/mocha-globals.js @@ -15,7 +15,7 @@ chai.use(require('sinon-chai')) chai.use(require('chai-subset')) beforeEach(() => { - global.sinon = sinon.sandbox.create() + global.sinon = sinon.createSandbox() // set logger to log INFO, but do not append to console // so that we can assert logs by logger.on('info', ...) diff --git a/test/unit/reporter.spec.js b/test/unit/reporter.spec.js index b74f90cd1..993e087d1 100644 --- a/test/unit/reporter.spec.js +++ b/test/unit/reporter.spec.js @@ -23,7 +23,7 @@ describe('reporter', () => { beforeEach(() => { emitter = new EventEmitter() formatError = m.createErrorFormatter({ basePath: '', hostname: 'localhost', port: 8080 }, emitter) - sandbox = sinon.sandbox.create() + sandbox = sinon.createSandbox() }) it('should call config.formatError if defined', () => { diff --git a/test/unit/utils/bundle-utils.spec.js b/test/unit/utils/bundle-utils.spec.js index 8972e502d..88aebefa7 100644 --- a/test/unit/utils/bundle-utils.spec.js +++ b/test/unit/utils/bundle-utils.spec.js @@ -5,7 +5,7 @@ const PathUtils = require('../../../lib/utils/path-utils') const FileUtils = require('../../../lib/utils/file-utils') const fs = require('fs') -const sandbox = sinon.sandbox.create() +const sandbox = sinon.createSandbox() describe('BundleUtils.bundleResource', () => { beforeEach(() => FileUtils.removeFileIfExists(PathUtils.calculateAbsolutePath('test/unit/fixtures/bundled.js'))) From 4ba83e273a6b78694e9a58a5bd2ff13032b7e09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Sat, 6 Oct 2018 18:40:46 +0200 Subject: [PATCH 050/374] refactor(middleware): small refactoring of middleware/karma (#3165) --- lib/middleware/karma.js | 110 ++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 71 deletions(-) diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 55a8e453d..f00fa9014 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -13,17 +13,10 @@ const path = require('path') const url = require('url') -const _ = require('lodash') +const helper = require('../helper') const log = require('../logger').create('middleware:karma') const stripHost = require('./strip_host').stripHost - -function urlparse (urlStr) { - const urlObj = url.parse(urlStr, true) - urlObj.query = urlObj.query || {} - return urlObj -} - const common = require('./common') const VERSION = require('../constants').VERSION @@ -44,27 +37,27 @@ function filePathToUrlPath (filePath, basePath, urlRoot, proxyPath) { if (filePath.startsWith(basePath)) { return proxyPath + urlRoot.substr(1) + 'base' + filePath.substr(basePath.length) } - return proxyPath + urlRoot.substr(1) + 'absolute' + filePath } +function getQuery (urlStr) { + return url.parse(urlStr, true).query || {} +} + function getXUACompatibleMetaElement (url) { - let tag = '' - const urlObj = urlparse(url) - if (urlObj.query['x-ua-compatible']) { - tag = '\n' + const query = getQuery(url) + if (query['x-ua-compatible']) { + return `\n` } - return tag + return '' } function getXUACompatibleUrl (url) { - let value = '' - const urlObj = urlparse(url) - if (urlObj.query['x-ua-compatible']) { - value = '?x-ua-compatible=' + encodeURIComponent(urlObj.query['x-ua-compatible']) + const query = getQuery(url) + if (query['x-ua-compatible']) { + return '?x-ua-compatible=' + encodeURIComponent(query['x-ua-compatible']) } - return value + return '' } function createKarmaMiddleware ( @@ -114,21 +107,20 @@ function createKarmaMiddleware ( if (!client.useIframe && client.runInParent) { requestUrl = '/client_with_context.html' } else { // serve client.html - return serveStaticFile('/client.html', requestedRangeHeader, response, function (data) { - return data + return serveStaticFile('/client.html', requestedRangeHeader, response, (data) => + data .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) - .replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url)) - }) + .replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url))) } } if (['/karma.js', '/context.js', '/debug.js'].includes(requestUrl)) { - return serveStaticFile(requestUrl, requestedRangeHeader, response, function (data) { - return data.replace('%KARMA_URL_ROOT%', urlRoot) + return serveStaticFile(requestUrl, requestedRangeHeader, response, (data) => + data + .replace('%KARMA_URL_ROOT%', urlRoot) .replace('%KARMA_VERSION%', VERSION) .replace('%KARMA_PROXY_PATH%', proxyPath) - .replace('%BROWSER_SOCKET_TIMEOUT%', browserSocketTimeout) - }) + .replace('%BROWSER_SOCKET_TIMEOUT%', browserSocketTimeout)) } // serve the favicon @@ -169,17 +161,11 @@ function createKarmaMiddleware ( const scriptTags = [] const scriptUrls = [] - for (let i = 0; i < files.included.length; i++) { - const file = files.included[i] + for (const file of files.included) { let filePath = file.path - const fileExt = path.extname(filePath) - const fileType = file.type + const fileType = file.type || path.extname(filePath).substring(1) - if (!files.included.hasOwnProperty(i)) { - continue - } - - if (!_.isUndefined(fileType) && !FILE_TYPES.includes(fileType)) { + if (helper.isDefined(fileType) && !FILE_TYPES.includes(fileType)) { log.warn('Invalid file type, defaulting to js.', fileType) } @@ -193,57 +179,39 @@ function createKarmaMiddleware ( scriptUrls.push(filePath) - if (fileType === 'css' || (!fileType && fileExt === '.css')) { + if (fileType === 'css') { scriptTags.push(``) - continue - } - - if (fileType === 'html' || (!fileType && fileExt === '.html')) { + } else if (fileType === 'html') { scriptTags.push(``) - continue + } else { + const scriptType = (SCRIPT_TYPE[fileType] || 'text/javascript') + const crossOriginAttribute = includeCrossOriginAttribute ? 'crossorigin="anonymous"' : '' + scriptTags.push(``) } - - // The script tag to be placed - const scriptFileType = (fileType || fileExt.substring(1)) - const scriptType = (SCRIPT_TYPE[scriptFileType] || 'text/javascript') - - const crossOriginAttribute = includeCrossOriginAttribute ? 'crossorigin="anonymous"' : '' - scriptTags.push(``) } - // TODO(vojta): don't compute if it's not in the template - let mappings = files.served.map(function (file) { - // Windows paths contain backslashes and generate bad IDs if not escaped - let filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath).replace(/\\/g, '\\\\') - // Escape single quotes that might be in the filename - - // double quotes should not be allowed! - filePath = filePath.replace(/'/g, '\\\'') + const mappings = data.includes('%MAPPINGS%') ? files.served.map((file) => { + const filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath) + .replace(/\\/g, '\\\\') // Windows paths contain backslashes and generate bad IDs if not escaped + .replace(/'/g, '\\\'') // Escape single quotes - double quotes should not be allowed! return ` '${filePath}': '${file.sha}'` - }) - - const clientConfig = 'window.__karma__.config = ' + JSON.stringify(client) + ';\n' - - const scriptUrlsJS = 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n' - - mappings = 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n' + }) : [] return data .replace('%SCRIPTS%', scriptTags.join('\n')) - .replace('%CLIENT_CONFIG%', clientConfig) - .replace('%SCRIPT_URL_ARRAY%', scriptUrlsJS) - .replace('%MAPPINGS%', mappings) + .replace('%CLIENT_CONFIG%', 'window.__karma__.config = ' + JSON.stringify(client) + ';\n') + .replace('%SCRIPT_URL_ARRAY%', 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n') + .replace('%MAPPINGS%', 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n') .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) }) }) } else if (requestUrl === '/context.json') { - return filesPromise.then(function (files) { + return filesPromise.then((files) => { common.setNoCacheHeaders(response) response.writeHead(200) response.end(JSON.stringify({ - files: files.included.map(function (file) { - return filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath) - }) + files: files.included.map((file) => filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath)) })) }) } From 5e5fdaea9cd49646a86830054d770d449003139e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Sat, 6 Oct 2018 18:41:00 +0200 Subject: [PATCH 051/374] refactor(server): use helper.arrayRemove in appropriate places (#3162) --- lib/browser.js | 10 +++++----- lib/browser_collection.js | 14 +++++--------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/browser.js b/lib/browser.js index 6abad4b64..3c914613d 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -142,8 +142,8 @@ class Browser { this.clearNoActivityTimeout() } - onDisconnect (disconnectedSocket) { - this.activeSockets.splice(this.activeSockets.indexOf(disconnectedSocket), 1) + onDisconnect (reason, disconnectedSocket) { + helper.arrayRemove(this.activeSockets, disconnectedSocket) if (this.activeSockets.length) { this.log.debug('Disconnected %s, still have %s', disconnectedSocket.id, this.getActiveSocketsIds()) @@ -151,7 +151,7 @@ class Browser { } if (this.state === CONNECTED) { - this.disconnect('client disconnected from CONNECTED state') + this.disconnect(`client disconnected from CONNECTED state (${reason})`) } else if (this.state === CONFIGURING || this.state === EXECUTING) { this.log.debug('Disconnected during run, waiting %sms for reconnecting.', this.disconnectDelay) this.state = EXECUTING_DISCONNECTED @@ -159,7 +159,7 @@ class Browser { this.pendingDisconnect = this.timer.setTimeout(() => { this.lastResult.totalTimeEnd() this.lastResult.disconnected = true - this.disconnect(`reconnect failed before timeout of ${this.disconnectDelay}ms`) + this.disconnect(`reconnect failed before timeout of ${this.disconnectDelay}ms (${reason})`) this.emitter.emit('browser_complete', this) }, this.disconnectDelay) @@ -265,7 +265,7 @@ class Browser { bindSocketEvents (socket) { // TODO: check which of these events are actually emitted by socket - socket.on('disconnect', () => this.onDisconnect(socket)) + socket.on('disconnect', (reason) => this.onDisconnect(reason, socket)) socket.on('start', (info) => this.onStart(info)) socket.on('karma_error', (error) => this.onKarmaError(error)) socket.on('complete', (result) => this.onComplete(result)) diff --git a/lib/browser_collection.js b/lib/browser_collection.js index d3fff4d8c..981f75608 100644 --- a/lib/browser_collection.js +++ b/lib/browser_collection.js @@ -1,6 +1,7 @@ 'use strict' const Result = require('./browser_result') +const helper = require('./helper') class BrowserCollection { constructor (emitter, browsers) { @@ -14,16 +15,11 @@ class BrowserCollection { } remove (browser) { - const index = this.browsers.indexOf(browser) - - if (index === -1) { - return false + if (helper.arrayRemove(this.browsers, browser)) { + this.emitter.emit('browsers_change', this) + return true } - - this.browsers.splice(index, 1) - this.emitter.emit('browsers_change', this) - - return true + return false } getById (browserId) { From 7af46b9c18eed4ff215e0377374aae1bcef7533c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Wed, 10 Oct 2018 23:32:39 +0200 Subject: [PATCH 052/374] refactor(completion): small refactoring of lib/completion (#3167) --- lib/completion.js | 88 +++++++++++++---------------------------------- 1 file changed, 24 insertions(+), 64 deletions(-) diff --git a/lib/completion.js b/lib/completion.js index 7410502f1..32e5dc8a6 100644 --- a/lib/completion.js +++ b/lib/completion.js @@ -1,5 +1,7 @@ 'use strict' +const glob = require('glob') + const CUSTOM = [''] const BOOLEAN = false @@ -32,54 +34,28 @@ const options = { } } -function parseEnv (argv, env) { - const words = argv.slice(5) - - return { - words: words, - count: parseInt(env.COMP_CWORD, 10), - last: words[words.length - 1], - prev: words[words.length - 2] - } -} - function opositeWord (word) { - if (word.charAt(0) !== '-') { + if (!word.startsWith('-')) { return null } return word.substr(0, 5) === '--no-' ? '--' + word.substr(5) : '--no-' + word.substr(2) } -function sendCompletionNoOptions () {} - function sendCompletion (possibleWords, env) { const regexp = new RegExp('^' + env.last) - const filteredWords = possibleWords.filter(function (word) { - return regexp.test(word) && !env.words.includes(word) && - !env.words.includes(opositeWord(word)) - }) - - if (!filteredWords.length) { - return sendCompletionNoOptions(env) - } - - filteredWords.forEach(function (word) { - console.log(word) - }) -} - -const glob = require('glob') -const globOpts = { - mark: true, - nocase: true + possibleWords + .filter((word) => regexp.test(word) && !env.words.includes(word) && !env.words.includes(opositeWord(word))) + .forEach((word) => { + console.log(word) + }) } function sendCompletionFiles (env) { - glob(env.last + '*', globOpts, function (err, files) { + glob(env.last + '*', { mark: true, nocase: true }, (err, files) => { if (err) return console.error(err) - if (files.length === 1 && files[0].charAt(files[0].length - 1) === '/') { + if (files.length === 1 && files[0].endsWith('/')) { sendCompletionFiles({last: files[0]}) } else { console.log(files.join('\n')) @@ -87,48 +63,32 @@ function sendCompletionFiles (env) { }) } -function sendCompletionConfirmLast (env) { - console.log(env.last) -} - function complete (env) { if (env.count === 1) { - if (env.words[0].charAt(0) === '-') { - return sendCompletion(['--help', '--version'], env) - } - - return sendCompletion(Object.keys(options), env) - } - - if (env.count === 2 && env.words[1].charAt(0) !== '-') { - // complete files (probably karma.conf.js) + return sendCompletion(env.words[0].startsWith('-') ? ['--help', '--version'] : Object.keys(options), env) + } else if (env.count === 2 && !env.words[1].startsWith('-')) { return sendCompletionFiles(env) } const cmdOptions = options[env.words[0]] - const previousOption = cmdOptions[env.prev] - if (!cmdOptions) { - // no completion, wrong command - return sendCompletionNoOptions() - } - - if (previousOption === CUSTOM && env.last) { - // custom value with already filled something - return sendCompletionConfirmLast(env) - } - - if (previousOption) { - // custom options - return sendCompletion(previousOption, env) + if (cmdOptions) { + if (cmdOptions[env.prev] === CUSTOM && env.last) { + console.log(env.last) + } else { + return sendCompletion(cmdOptions[env.prev] || Object.keys(cmdOptions), env) + } } - - return sendCompletion(Object.keys(cmdOptions), env) } function completion () { if (process.argv[3] === '--') { - return complete(parseEnv(process.argv, process.env)) + return complete({ + words: process.argv.slice(5), + count: parseInt(process.env.COMP_CWORD, 10), + last: process.argv[process.argv.length - 1], + prev: process.argv[process.argv.length - 2] + }) } // just print out the karma-completion.sh From 29523ff55567b1f7296bf3adc9c3a0f3088c94bd Mon Sep 17 00:00:00 2001 From: lukasz Date: Wed, 10 Oct 2018 21:43:53 +0200 Subject: [PATCH 053/374] refactor(config): small refactoring of lib/config --- lib/config.js | 105 ++++++++++++++------------------------- test/unit/config.spec.js | 2 +- 2 files changed, 38 insertions(+), 69 deletions(-) diff --git a/lib/config.js b/lib/config.js index eee6f30a8..919782a88 100644 --- a/lib/config.js +++ b/lib/config.js @@ -62,36 +62,25 @@ class UrlPattern extends Pattern { function createPatternObject (pattern) { if (pattern && helper.isString(pattern)) { - return helper.isUrlAbsolute(pattern) ? new UrlPattern(pattern) : new Pattern(pattern) - } - - if (helper.isObject(pattern)) { - if (pattern.pattern && helper.isString(pattern.pattern)) { - return helper.isUrlAbsolute(pattern.pattern) - ? new UrlPattern(pattern.pattern, pattern.type) - : new Pattern( - pattern.pattern, - pattern.served, - pattern.included, - pattern.watched, - pattern.nocache, - pattern.type) - } - - log.warn('Invalid pattern %s!\n\tObject is missing "pattern" property.', pattern) + return helper.isUrlAbsolute(pattern) + ? new UrlPattern(pattern) + : new Pattern(pattern) + } else if (helper.isObject(pattern) && pattern.pattern && helper.isString(pattern.pattern)) { + return helper.isUrlAbsolute(pattern.pattern) + ? new UrlPattern(pattern.pattern, pattern.type) + : new Pattern(pattern.pattern, pattern.served, pattern.included, pattern.watched, pattern.nocache, pattern.type) + } else { + log.warn(`Invalid pattern ${pattern}!\n\tExpected string or object with "pattern" property.`) return new Pattern(null, false, false, false, false) } - - log.warn('Invalid pattern %s!\n\tExpected string or object with "pattern" property.', pattern) - return new Pattern(null, false, false, false, false) } function normalizeUrl (url) { - if (url.charAt(0) !== '/') { - url = '/' + url + if (!url.startsWith('/')) { + url = `/${url}` } - if (url.charAt(url.length - 1) !== '/') { + if (!url.endsWith('/')) { url = url + '/' } @@ -102,7 +91,7 @@ function normalizeUrlRoot (urlRoot) { const normalizedUrlRoot = normalizeUrl(urlRoot) if (normalizedUrlRoot !== urlRoot) { - log.warn('urlRoot normalized to "%s"', normalizedUrlRoot) + log.warn(`urlRoot normalized to "${normalizedUrlRoot}"`) } return normalizedUrlRoot @@ -112,7 +101,7 @@ function normalizeProxyPath (proxyPath) { const normalizedProxyPath = normalizeUrl(proxyPath) if (normalizedProxyPath !== proxyPath) { - log.warn('proxyPath normalized to "%s"', normalizedProxyPath) + log.warn(`proxyPath normalized to "${normalizedProxyPath}"`) } return normalizedProxyPath @@ -122,28 +111,20 @@ function normalizeConfig (config, configFilePath) { function basePathResolve (relativePath) { if (helper.isUrlAbsolute(relativePath)) { return relativePath - } - - if (!helper.isDefined(config.basePath) || !helper.isDefined(relativePath)) { + } else if (helper.isDefined(config.basePath) && helper.isDefined(relativePath)) { + return path.resolve(config.basePath, relativePath) + } else { return '' } - return path.resolve(config.basePath, relativePath) } function createPatternMapper (resolve) { - return (objectPattern) => { - objectPattern.pattern = resolve(objectPattern.pattern) - - return objectPattern - } + return (objectPattern) => Object.assign(objectPattern, { pattern: resolve(objectPattern.pattern) }) } if (helper.isString(configFilePath)) { - // resolve basePath - config.basePath = path.resolve(path.dirname(configFilePath), config.basePath) - - // always ignore the config file itself - config.exclude.push(configFilePath) + config.basePath = path.resolve(path.dirname(configFilePath), config.basePath) // resolve basePath + config.exclude.push(configFilePath) // always ignore the config file itself } else { config.basePath = path.resolve(config.basePath || '.') } @@ -168,15 +149,14 @@ function normalizeConfig (config, configFilePath) { // normalize and default upstream proxy settings if given if (config.upstreamProxy) { const proxy = config.upstreamProxy - proxy.path = _.isUndefined(proxy.path) ? '/' : normalizeProxyPath(proxy.path) - proxy.hostname = _.isUndefined(proxy.hostname) ? 'localhost' : proxy.hostname - proxy.port = _.isUndefined(proxy.port) ? 9875 : proxy.port + proxy.path = helper.isDefined(proxy.path) ? normalizeProxyPath(proxy.path) : '/' + proxy.hostname = helper.isDefined(proxy.hostname) ? proxy.hostname : 'localhost' + proxy.port = helper.isDefined(proxy.port) ? proxy.port : 9875 // force protocol to end with ':' proxy.protocol = (proxy.protocol || 'http').split(':')[0] + ':' if (proxy.protocol.match(/https?:/) === null) { - log.warn('"%s" is not a supported upstream proxy protocol, defaulting to "http:"', - proxy.protocol) + log.warn(`"${proxy.protocol}" is not a supported upstream proxy protocol, defaulting to "http:"`) proxy.protocol = 'http:' } } @@ -184,14 +164,12 @@ function normalizeConfig (config, configFilePath) { // force protocol to end with ':' config.protocol = (config.protocol || 'http').split(':')[0] + ':' if (config.protocol.match(/https?:/) === null) { - log.warn('"%s" is not a supported protocol, defaulting to "http:"', - config.protocol) + log.warn(`"${config.protocol}" is not a supported protocol, defaulting to "http:"`) config.protocol = 'http:' } if (config.proxies && config.proxies.hasOwnProperty(config.urlRoot)) { - log.warn('"%s" is proxied, you should probably change urlRoot to avoid conflicts', - config.urlRoot) + log.warn(`"${config.urlRoot}" is proxied, you should probably change urlRoot to avoid conflicts`) } if (config.singleRun && config.autoWatch) { @@ -262,11 +240,11 @@ function normalizeConfig (config, configFilePath) { const definition = definitions[name] if (!helper.isObject(definition)) { - return log.warn('Can not define %s %s. Definition has to be an object.', type, name) + return log.warn(`Can not define ${type} ${name}. Definition has to be an object.`) } if (!helper.isString(definition.base)) { - return log.warn('Can not define %s %s. Missing base %s.', type, name, type) + return log.warn(`Can not define ${type} ${name}. Missing base ${type}.`) } const token = type + ':' + definition.base @@ -360,7 +338,7 @@ class Config { set (newConfig) { _.mergeWith(this, newConfig, (obj, src) => { // Overwrite arrays to keep consistent with #283 - if (_.isArray(src)) { + if (Array.isArray(src)) { return src } }) @@ -383,20 +361,17 @@ function parseConfig (configFilePath, cliOptions) { } } catch (e) { if (e.code === 'MODULE_NOT_FOUND' && e.message.includes(configFilePath)) { - log.error('File %s does not exist!', configFilePath) + log.error(`File ${configFilePath} does not exist!`) } else { log.error('Invalid config file!\n ' + e.stack) const extension = path.extname(configFilePath) if (extension === '.coffee' && !COFFEE_SCRIPT_AVAILABLE) { - log.error('You need to install CoffeeScript.\n' + - ' npm install coffee-script --save-dev') + log.error('You need to install CoffeeScript.\n npm install coffee-script --save-dev') } else if (extension === '.ls' && !LIVE_SCRIPT_AVAILABLE) { - log.error('You need to install LiveScript.\n' + - ' npm install LiveScript --save-dev') + log.error('You need to install LiveScript.\n npm install LiveScript --save-dev') } else if (extension === '.ts' && !TYPE_SCRIPT_AVAILABLE) { - log.error('You need to install TypeScript.\n' + - ' npm install typescript ts-node --save-dev') + log.error('You need to install TypeScript.\n npm install typescript ts-node --save-dev') } } return process.exit(1) @@ -406,8 +381,7 @@ function parseConfig (configFilePath, cliOptions) { return process.exit(1) } } else { - // if no config file path is passed, we define a dummy config module. - configModule = () => {} + configModule = () => {} // if no config file path is passed, we define a dummy config module. } const config = new Config() @@ -434,9 +408,8 @@ function parseConfig (configFilePath, cliOptions) { // if the user changed listenAddress, but didn't set a hostname, warn them if (config.hostname === null && config.listenAddress !== null) { - log.warn('ListenAddress was set to %s but hostname was left as the default: ' + - '%s. If your browsers fail to connect, consider changing the hostname option.', - config.listenAddress, defaultHostname) + log.warn(`ListenAddress was set to ${config.listenAddress} but hostname was left as the default: ` + + `${defaultHostname}. If your browsers fail to connect, consider changing the hostname option.`) } // restore values that weren't overwritten by the user if (config.hostname === null) { @@ -449,11 +422,7 @@ function parseConfig (configFilePath, cliOptions) { // configure the logger as soon as we can logger.setup(config.logLevel, config.colors, config.loggers) - if (configFilePath) { - log.debug('Loading config %s', configFilePath) - } else { - log.debug('No config file specified.') - } + log.debug(configFilePath ? `Loading config ${configFilePath}` : 'No config file specified.') return normalizeConfig(config, configFilePath) } diff --git a/test/unit/config.spec.js b/test/unit/config.spec.js index 54305bd52..560af8717 100644 --- a/test/unit/config.spec.js +++ b/test/unit/config.spec.js @@ -118,7 +118,7 @@ describe('config', () => { expect(logSpy).to.have.been.called const event = logSpy.lastCall.args - expect(event).to.be.deep.equal(['File %s does not exist!', '/conf/not-exist.js']) + expect(event).to.be.deep.equal(['File /conf/not-exist.js does not exist!']) expect(mocks.process.exit).to.have.been.calledWith(1) }) From 9bd7e1d506e0fa697b9ceb9df149852ddd10b947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Thu, 11 Oct 2018 17:45:56 +0200 Subject: [PATCH 054/374] refactor(server): refactoring of executor and browser_collection (#3170) --- lib/browser_collection.js | 52 +++++++++++----------------- lib/executor.js | 24 +++++-------- test/unit/browser_collection.spec.js | 12 ++++--- 3 files changed, 38 insertions(+), 50 deletions(-) diff --git a/lib/browser_collection.js b/lib/browser_collection.js index 981f75608..04354af69 100644 --- a/lib/browser_collection.js +++ b/lib/browser_collection.js @@ -4,8 +4,8 @@ const Result = require('./browser_result') const helper = require('./helper') class BrowserCollection { - constructor (emitter, browsers) { - this.browsers = browsers || [] + constructor (emitter, browsers = []) { + this.browsers = browsers this.emitter = emitter } @@ -26,16 +26,12 @@ class BrowserCollection { return this.browsers.find((browser) => browser.id === browserId) || null } - areAllReady (nonReadyList) { - nonReadyList = nonReadyList || [] - - this.browsers.forEach((browser) => { - if (!browser.isConnected()) { - nonReadyList.push(browser) - } - }) + getNonReady () { + return this.browsers.filter((browser) => !browser.isConnected()) + } - return nonReadyList.length === 0 + areAllReady () { + return this.browsers.every((browser) => browser.isConnected()) } serialize () { @@ -45,36 +41,30 @@ class BrowserCollection { calculateExitCode (results, singleRunBrowserNotCaptured, failOnEmptyTestSuite, failOnFailingTestSuite) { if (results.disconnected || singleRunBrowserNotCaptured) { return 1 - } - if (results.success + results.failed === 0 && !failOnEmptyTestSuite) { + } else if (results.success + results.failed === 0 && !failOnEmptyTestSuite) { return 0 - } - if (results.error) { + } else if (results.error) { return 1 + } else if (failOnFailingTestSuite === false) { + return 0 // Tests executed without infrastructure error, exit with 0 independent of test status. + } else { + return results.failed ? 1 : 0 } - if (failOnFailingTestSuite === false) { - // Tests executed without infrastructure error, exit with 0 independent of test status. - return 0 - } - return results.failed ? 1 : 0 } getResults (singleRunBrowserNotCaptured, failOnEmptyTestSuite, failOnFailingTestSuite) { - const results = this.browsers.reduce((previous, current) => { - previous.success += current.lastResult.success - previous.failed += current.lastResult.failed - previous.error = previous.error || current.lastResult.error - previous.disconnected = previous.disconnected || current.lastResult.disconnected - return previous - }, {success: 0, failed: 0, error: false, disconnected: false, exitCode: 0}) - - // compute exit status code - results.exitCode = this.calculateExitCode(results, singleRunBrowserNotCaptured, failOnEmptyTestSuite, failOnFailingTestSuite) + const results = { success: 0, failed: 0, error: false, disconnected: false, exitCode: 0 } + this.browsers.forEach((browser) => { + results.success += browser.lastResult.success + results.failed += browser.lastResult.failed + results.error = results.error || browser.lastResult.error + results.disconnected = results.disconnected || browser.lastResult.disconnected + }) + results.exitCode = this.calculateExitCode(results, singleRunBrowserNotCaptured, failOnEmptyTestSuite, failOnFailingTestSuite) return results } - // TODO(vojta): can we remove this? (we clear the results per browser in onBrowserStart) clearResults () { this.browsers.forEach((browser) => { browser.lastResult = new Result() diff --git a/lib/executor.js b/lib/executor.js index 189c575fc..41f6a9ebd 100644 --- a/lib/executor.js +++ b/lib/executor.js @@ -12,23 +12,17 @@ class Executor { this.pendingCount = 0 this.runningBrowsers = null - // bind all the events this.emitter.on('run_complete', () => this.onRunComplete()) this.emitter.on('browser_complete', () => this.onBrowserComplete()) } schedule () { - const nonReady = [] - - if (!this.capturedBrowsers.length) { - log.warn('No captured browser, open %s//%s:%s%s', this.config.protocol, this.config.hostname, - this.config.port, this.config.urlRoot) + if (this.capturedBrowsers.length === 0) { + log.warn(`No captured browser, open ${this.config.protocol}//${this.config.hostname}:${this.config.port}${this.config.urlRoot}`) return false - } - - if (this.capturedBrowsers.areAllReady(nonReady)) { + } else if (this.capturedBrowsers.areAllReady()) { log.debug('All browsers are ready, executing') - log.debug('Captured %s browsers', this.capturedBrowsers.length) + log.debug(`Captured ${this.capturedBrowsers.length} browsers`) this.executionScheduled = false this.capturedBrowsers.clearResults() this.pendingCount = this.capturedBrowsers.length @@ -36,11 +30,11 @@ class Executor { this.emitter.emit('run_start', this.runningBrowsers) this.socketIoSockets.emit('execute', this.config.client) return true + } else { + log.info('Delaying execution, these browsers are not ready: ' + this.capturedBrowsers.getNonReady().join(', ')) + this.executionScheduled = true + return false } - - log.info('Delaying execution, these browsers are not ready: ' + nonReady.join(', ')) - this.executionScheduled = true - return false } onRunComplete () { @@ -57,7 +51,7 @@ class Executor { // so it is never emitted before browser_complete setTimeout(() => { this.emitter.emit('run_complete', this.runningBrowsers, this.runningBrowsers.getResults()) - }, 0) + }) } } } diff --git a/test/unit/browser_collection.spec.js b/test/unit/browser_collection.spec.js index d883cb701..622d6f9aa 100644 --- a/test/unit/browser_collection.spec.js +++ b/test/unit/browser_collection.spec.js @@ -90,13 +90,17 @@ describe('BrowserCollection', () => { browsers[1].state = Browser.STATE_EXECUTING expect(collection.areAllReady()).to.equal(false) }) + }) - it('should add all non-ready browsers into given array', () => { + describe('getNonReady', () => { + it('return all non-ready browsers', () => { + const browsers = [new Browser(), new Browser(), new Browser()] browsers[0].state = Browser.STATE_EXECUTING browsers[1].state = Browser.STATE_EXECUTING_DISCONNECTED - const nonReady = [] - collection.areAllReady(nonReady) - expect(nonReady).to.deep.equal([browsers[0], browsers[1]]) + browsers[2].state = Browser.STATE_CONNECTED + browsers.forEach((browser) => collection.add(browser)) + + expect(collection.getNonReady()).to.deep.equal([browsers[0], browsers[1]]) }) }) From c9210103185b28f92352576946ba64933ca61ddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Thu, 11 Oct 2018 17:56:02 +0200 Subject: [PATCH 055/374] refactor(server): refactoring of proxy (#3172) --- lib/middleware/proxy.js | 78 +++++++++++++---------------------------- 1 file changed, 25 insertions(+), 53 deletions(-) diff --git a/lib/middleware/proxy.js b/lib/middleware/proxy.js index c3a59b783..cfb86204b 100644 --- a/lib/middleware/proxy.js +++ b/lib/middleware/proxy.js @@ -5,14 +5,7 @@ const _ = require('lodash') const log = require('../logger').create('proxy') function parseProxyConfig (proxies, config) { - function endsWithSlash (str) { - return str.substr(-1) === '/' - } - - if (!proxies) { - return [] - } - + proxies = proxies || [] return _.sortBy(_.map(proxies, function (proxyConfiguration, proxyPath) { if (typeof proxyConfiguration === 'string') { proxyConfiguration = {target: proxyConfiguration} @@ -21,20 +14,18 @@ function parseProxyConfig (proxies, config) { const proxyDetails = url.parse(proxyUrl) let pathname = proxyDetails.pathname - // normalize the proxies config - // should we move this to lib/config.js ? - if (endsWithSlash(proxyPath) && !endsWithSlash(proxyUrl)) { - log.warn('proxy "%s" normalized to "%s"', proxyUrl, proxyUrl + '/') + if (proxyPath.endsWith('/') && !proxyUrl.endsWith('/')) { + log.warn(`proxy "${proxyUrl}" normalized to "${proxyUrl}/"`) proxyUrl += '/' pathname += '/' } - if (!endsWithSlash(proxyPath) && endsWithSlash(proxyUrl)) { - log.warn('proxy "%s" normalized to "%s"', proxyPath, proxyPath + '/') + if (!proxyPath.endsWith('/') && proxyUrl.endsWith('/')) { + log.warn(`proxy "${proxyPath}" normalized to "${proxyPath}/"`) proxyPath += '/' } - if (pathname === '/' && !endsWithSlash(proxyUrl)) { + if (pathname === '/' && !proxyUrl.endsWith('/')) { pathname = '' } @@ -45,18 +36,13 @@ function parseProxyConfig (proxies, config) { if (proxyDetails.port) { port = proxyDetails.port } else if (proxyDetails.protocol) { - port = proxyDetails.protocol === 'https:' ? '443' : '80' + port = https ? '443' : '80' } else { port = config.port } - const changeOrigin = 'changeOrigin' in proxyConfiguration ? proxyConfiguration.changeOrigin : false + const changeOrigin = proxyConfiguration.changeOrigin || false const proxy = httpProxy.createProxyServer({ - target: { - host: hostname, - port: port, - https: https, - protocol: protocol - }, + target: { host: hostname, port, https, protocol }, xfwd: true, changeOrigin: changeOrigin, secure: config.proxyValidateSSL @@ -79,14 +65,7 @@ function parseProxyConfig (proxies, config) { res.destroy() }) - return { - path: proxyPath, - baseUrl: pathname, - host: hostname, - port: port, - https: https, - proxy: proxy - } + return { path: proxyPath, baseUrl: pathname, host: hostname, port, https, proxy } }), 'path').reverse() } @@ -98,42 +77,35 @@ function parseProxyConfig (proxies, config) { */ function createProxyHandler (proxies, urlRoot) { if (!proxies.length) { - const nullProxy = function (request, response, next) { - return next() - } - nullProxy.upgrade = function upgradeNullProxy () {} + const nullProxy = (request, response, next) => next() + nullProxy.upgrade = () => {} return nullProxy } function createProxy (request, response, next) { - const proxyRecord = _.find(proxies, (p) => request.url.startsWith(p.path)) - - if (!proxyRecord) { + const proxyRecord = proxies.find((p) => request.url.startsWith(p.path)) + if (proxyRecord) { + log.debug(`proxying request - ${request.url} to ${proxyRecord.host}:${proxyRecord.port}`) + request.url = request.url.replace(proxyRecord.path, proxyRecord.baseUrl) + proxyRecord.proxy.web(request, response) + } else { return next() } - - log.debug('proxying request - %s to %s:%s', request.url, proxyRecord.host, proxyRecord.port) - request.url = request.url.replace(proxyRecord.path, proxyRecord.baseUrl) - proxyRecord.proxy.web(request, response) } - createProxy.upgrade = function upgradeProxy (request, socket, head) { + createProxy.upgrade = function (request, socket, head) { // special-case karma's route to avoid upgrading it if (request.url.startsWith(urlRoot)) { - log.debug('NOT upgrading proxyWebSocketRequest %s', request.url) + log.debug(`NOT upgrading proxyWebSocketRequest ${request.url}`) return } - const proxyRecord = _.find(proxies, (p) => request.url.startsWith(p.path)) - - if (!proxyRecord) { - return + const proxyRecord = proxies.find((p) => request.url.startsWith(p.path)) + if (proxyRecord) { + log.debug(`upgrade proxyWebSocketRequest ${request.url} to ${proxyRecord.host}:${proxyRecord.port}`) + request.url = request.url.replace(proxyRecord.path, proxyRecord.baseUrl) + proxyRecord.proxy.ws(request, socket, head) } - - log.debug('upgrade proxyWebSocketRequest %s to %s:%s', - request.url, proxyRecord.host, proxyRecord.port) - request.url = request.url.replace(proxyRecord.path, proxyRecord.baseUrl) - proxyRecord.proxy.ws(request, socket, head) } return createProxy From 871a1c9c90e32459173dfd0b0ea611da623df69b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Thu, 11 Oct 2018 17:59:54 +0200 Subject: [PATCH 056/374] refactor(server): refactoring of watcher (#3173) --- lib/watcher.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/watcher.js b/lib/watcher.js index 8f4c1ea2b..622f40e73 100644 --- a/lib/watcher.js +++ b/lib/watcher.js @@ -26,7 +26,7 @@ function watchPatterns (patterns, watcher) { pathsToWatch = Array.from(pathsToWatch) // watch only common parents, no sub paths pathsToWatch.forEach((path) => { - if (!pathsToWatch.some((p) => p !== path && path.substr(0, p.length + 1) === p + DIR_SEP)) { + if (!pathsToWatch.some((p) => p !== path && path.startsWith(p + DIR_SEP))) { watcher.add(path) log.debug('Watching "%s"', path) } @@ -39,22 +39,18 @@ function checkAnyPathMatch (patterns, path) { function createIgnore (patterns, excludes) { return function (path, stat) { - if (!stat || stat.isDirectory()) { + if (stat && !stat.isDirectory()) { + return !checkAnyPathMatch(patterns, path) || checkAnyPathMatch(excludes, path) + } else { return false } - - return !checkAnyPathMatch(patterns, path) || checkAnyPathMatch(excludes, path) } } function getWatchedPatterns (patterns) { return patterns - .reduce((array, pattern) => { - if (pattern.watched) { - array.push(pattern.pattern) - } - return array - }, []) + .filter((pattern) => pattern.watched) + .map((pattern) => pattern.pattern) } exports.watch = function (patterns, excludes, fileList, usePolling, emitter) { From dab8a8218de2513aea6aefcf1f642a92e08869fd Mon Sep 17 00:00:00 2001 From: Pierre Vanduynslager Date: Tue, 18 Jul 2017 18:04:00 -0400 Subject: [PATCH 057/374] feat(server): Add public API to force a file refresh Adds a public API similar to `server.refreshFiles()` that allows to refresh a specific file. This is useful for preprocessors that process files with dependencies (sass, js modules, postcss), so they can trigger an update on a file when a change is detected on a dependency. Contrary to `server.refreshFiles()` it allows to refresh only the file that need to be processed again. --- docs/dev/04-public-api.md | 8 ++++++++ lib/file-list.js | 6 +++--- lib/server.js | 4 ++++ test/unit/file-list.spec.js | 17 +++++++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/docs/dev/04-public-api.md b/docs/dev/04-public-api.md index 21974dd40..3f810a43c 100644 --- a/docs/dev/04-public-api.md +++ b/docs/dev/04-public-api.md @@ -33,6 +33,14 @@ Trigger a file list refresh. Returns a promise. server.refreshFiles() ``` +### **server.refreshFile(path)** + +Trigger a file refresh. Returns a promise. + +```javascript +server.refreshFile('src/js/module-dep.js') +``` + ### Events The `server` object is an [`EventEmitter`](https://nodejs.org/docs/latest/api/events.html#events_class_events_eventemitter). You can simply listen to events like this: diff --git a/lib/file-list.js b/lib/file-list.js index 02d0bacdc..35f5058e2 100644 --- a/lib/file-list.js +++ b/lib/file-list.js @@ -213,7 +213,7 @@ class FileList { }) } - changeFile (path) { + changeFile (path, force) { const pattern = this._findIncluded(path) const file = this._findFile(path, pattern) @@ -226,14 +226,14 @@ class FileList { fs.statAsync(path), this._refreshing ]).spread((stat) => { - if (stat.mtime <= file.mtime) throw new Promise.CancellationError() + if (!force && stat.mtime <= file.mtime) throw new Promise.CancellationError() file.mtime = stat.mtime return this._preprocess(file) }) .then(() => { log.info('Changed file "%s".', path) - this._emitModified() + this._emitModified(force) return this.files }) .catch(Promise.CancellationError, () => this.files) diff --git a/lib/server.js b/lib/server.js index 426f49e27..dacfdc095 100644 --- a/lib/server.js +++ b/lib/server.js @@ -133,6 +133,10 @@ class Server extends KarmaEventEmitter { return this._fileList ? this._fileList.refresh() : Promise.resolve() } + refreshFile (path) { + return this._fileList ? this._fileList.changeFile(path) : Promise.resolve() + } + _start (config, launcher, preprocess, fileList, capturedBrowsers, executor, done) { if (config.detached) { this._detach(config, done) diff --git a/test/unit/file-list.spec.js b/test/unit/file-list.spec.js index f9eef1d51..3bec4bc68 100644 --- a/test/unit/file-list.spec.js +++ b/test/unit/file-list.spec.js @@ -632,6 +632,23 @@ describe('FileList', () => { }) }) + it('fire "file_list_modified" if force is true even if mtime has not changed', () => { + // MATCH: /some/a.js, /some/b.js, /a.txt + list = new List(patterns('/some/*.js', '/a.*'), [], emitter, preprocess) + + var modified = sinon.stub() + emitter.on('file_list_modified', modified) + + return list.refresh().then((files) => { + // not touching the file, stat will return still the same + modified.reset() + + return list.changeFile('/some/b.js', true).then(() => { + expect(modified).to.have.been.calledOnce + }) + }) + }) + it('does not fire "file_list_modified" if mtime has not changed', () => { // chokidar on fucking windows sometimes fires event multiple times // MATCH: /some/a.js, /some/b.js, /a.txt From 8efb28d7a42b815cf92b1029fbdb75feab343da7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Thu, 11 Oct 2018 19:25:50 +0200 Subject: [PATCH 058/374] refactor(server): refactoring of lib/browser (#3171) * refactor(config): small refactoring of lib/config * refactor(server): refactoring of lib/browser --- lib/browser.js | 219 +++++++++++++------------------ lib/browser_collection.js | 4 +- lib/browser_result.js | 5 +- lib/helper.js | 4 +- lib/middleware/common.js | 85 +++++------- test/unit/browser_result.spec.js | 4 +- 6 files changed, 133 insertions(+), 188 deletions(-) diff --git a/lib/browser.js b/lib/browser.js index 3c914613d..3bcfbe9c5 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -1,23 +1,14 @@ 'use strict' -const Result = require('./browser_result') +const BrowserResult = require('./browser_result') const helper = require('./helper') const logger = require('./logger') -// The browser is connected but not yet been commanded to execute tests. -const CONNECTED = 1 - -// The browser has been told to execute tests; it is configuring before tests execution. -const CONFIGURING = 2 - -// The browser is executing the tests. -const EXECUTING = 3 - -// The browser is executing the tests, but temporarily disconnect (waiting for reconnecting). -const EXECUTING_DISCONNECTED = 4 - -// The browser got permanently disconnected (being removed from the collection and destroyed). -const DISCONNECTED = 5 +const CONNECTED = 1 // The browser is connected but not yet been commanded to execute tests. +const CONFIGURING = 2 // The browser has been told to execute tests; it is configuring before tests execution. +const EXECUTING = 3 // The browser is executing the tests. +const EXECUTING_DISCONNECTED = 4 // The browser is executing the tests, but temporarily disconnect (waiting for reconnecting). +const DISCONNECTED = 5 // The browser got permanently disconnected (being removed from the collection and destroyed). class Browser { constructor (id, fullName, collection, emitter, socket, timer, disconnectDelay, noActivityTimeout) { @@ -25,7 +16,7 @@ class Browser { this.fullName = fullName this.name = helper.browserFullNameToShort(fullName) this.state = CONNECTED - this.lastResult = new Result() + this.lastResult = new BrowserResult() this.disconnectsCount = 0 this.activeSockets = [socket] this.noActivityTimeout = noActivityTimeout @@ -42,118 +33,77 @@ class Browser { } init () { - this.collection.add(this) + this.log.info(`Connected on socket ${this.socket.id} with id ${this.id}`) this.bindSocketEvents(this.socket) - - this.log.info('Connected on socket %s with id %s', this.socket.id, this.id) - - // TODO(vojta): move to collection - this.emitter.emit('browsers_change', this.collection) - + this.collection.add(this) + this.emitter.emit('browsers_change', this.collection) // TODO(vojta): move to collection this.emitter.emit('browser_register', this) } - isConnected () { - return this.state === CONNECTED - } - - toString () { - return this.name - } - - toJSON () { - return { - id: this.id, - fullName: this.fullName, - name: this.name, - state: this.state, - lastResult: this.lastResult, - disconnectsCount: this.disconnectsCount, - noActivityTimeout: this.noActivityTimeout, - disconnectDelay: this.disconnectDelay - } - } - onKarmaError (error) { - if (this.isConnected()) { - return + if (this.isNotConnected()) { + this.lastResult.error = true + this.emitter.emit('browser_error', this, error) + this.refreshNoActivityTimeout() } - - this.lastResult.error = true - this.emitter.emit('browser_error', this, error) - - this.refreshNoActivityTimeout() } onInfo (info) { - if (this.isConnected()) { - return - } - - // TODO(vojta): remove - if (helper.isDefined(info.dump)) { - this.emitter.emit('browser_log', this, info.dump, 'dump') - } + if (this.isNotConnected()) { + if (helper.isDefined(info.dump)) { + this.emitter.emit('browser_log', this, info.dump, 'dump') + } - if (helper.isDefined(info.log)) { - this.emitter.emit('browser_log', this, info.log, info.type) - } + if (helper.isDefined(info.log)) { + this.emitter.emit('browser_log', this, info.log, info.type) + } else if (!helper.isDefined(info.dump)) { + this.emitter.emit('browser_info', this, info) + } - if ( - !helper.isDefined(info.log) && - !helper.isDefined(info.dump) - ) { - this.emitter.emit('browser_info', this, info) + this.refreshNoActivityTimeout() } - - this.refreshNoActivityTimeout() } onStart (info) { - this.lastResult = new Result() - this.lastResult.total = info.total - - this.state = EXECUTING - if (info.total === null) { this.log.warn('Adapter did not report total number of specs.') } + this.lastResult = new BrowserResult(info.total) + this.state = EXECUTING this.emitter.emit('browser_start', this, info) this.refreshNoActivityTimeout() } onComplete (result) { - if (this.isConnected()) { - return - } - - this.state = CONNECTED - this.lastResult.totalTimeEnd() + if (this.isNotConnected()) { + this.state = CONNECTED + this.lastResult.totalTimeEnd() - if (!this.lastResult.success) { - this.lastResult.error = true - } + if (!this.lastResult.success) { + this.lastResult.error = true + } - this.emitter.emit('browsers_change', this.collection) - this.emitter.emit('browser_complete', this, result) + this.emitter.emit('browsers_change', this.collection) + this.emitter.emit('browser_complete', this, result) - this.clearNoActivityTimeout() + this.clearNoActivityTimeout() + } } onDisconnect (reason, disconnectedSocket) { helper.arrayRemove(this.activeSockets, disconnectedSocket) if (this.activeSockets.length) { - this.log.debug('Disconnected %s, still have %s', disconnectedSocket.id, this.getActiveSocketsIds()) + this.log.debug(`Disconnected ${disconnectedSocket.id}, still have ${this.getActiveSocketsIds()}`) return } - if (this.state === CONNECTED) { - this.disconnect(`client disconnected from CONNECTED state (${reason})`) - } else if (this.state === CONFIGURING || this.state === EXECUTING) { - this.log.debug('Disconnected during run, waiting %sms for reconnecting.', this.disconnectDelay) + if (this.isConnected()) { + this.disconnect(`Client disconnected from CONNECTED state (${reason})`) + } else if ([CONFIGURING, EXECUTING].includes(this.state)) { + this.log.debug(`Disconnected during run, waiting ${this.disconnectDelay}ms for reconnecting.`) this.state = EXECUTING_DISCONNECTED this.pendingDisconnect = this.timer.setTimeout(() => { @@ -169,23 +119,20 @@ class Browser { reconnect (newSocket) { if (this.state === EXECUTING_DISCONNECTED) { + this.log.debug(`Reconnected on ${newSocket.id}.`) this.state = EXECUTING - this.log.debug('Reconnected on %s.', newSocket.id) - } else if (this.state === CONNECTED || this.state === CONFIGURING || this.state === EXECUTING) { - this.log.debug('New connection %s (already have %s)', newSocket.id, this.getActiveSocketsIds()) + } else if ([CONNECTED, CONFIGURING, EXECUTING].includes(this.state)) { + this.log.debug(`New connection ${newSocket.id} (already have ${this.getActiveSocketsIds()})`) } else if (this.state === DISCONNECTED) { + this.log.info(`Connected on socket ${newSocket.id} with id ${this.id}`) this.state = CONNECTED - this.log.info('Connected on socket %s with id %s', newSocket.id, this.id) - this.collection.add(this) - - // TODO(vojta): move to collection - this.emitter.emit('browsers_change', this.collection) + this.collection.add(this) + this.emitter.emit('browsers_change', this.collection) // TODO(vojta): move to collection this.emitter.emit('browser_register', this) } - const exists = this.activeSockets.some((s) => s.id === newSocket.id) - if (!exists) { + if (!this.activeSockets.some((s) => s.id === newSocket.id)) { this.activeSockets.push(newSocket) this.bindSocketEvents(newSocket) } @@ -199,33 +146,18 @@ class Browser { onResult (result) { if (result.length) { - return result.forEach(this.onResult, this) - } - - // ignore - probably results from last run (after server disconnecting) - if (this.isConnected()) { + result.forEach(this.onResult, this) return + } else if (this.isNotConnected()) { + this.lastResult.add(result) + this.emitter.emit('spec_complete', this, result) } - - this.lastResult.add(result) - - this.emitter.emit('spec_complete', this, result) this.refreshNoActivityTimeout() } - serialize () { - return { - id: this.id, - name: this.name, - isConnected: this.state === CONNECTED - } - } - execute (config) { this.activeSockets.forEach((socket) => socket.emit('execute', config)) - this.state = CONFIGURING - this.refreshNoActivityTimeout() } @@ -234,10 +166,10 @@ class Browser { } disconnect (reason) { + this.log.warn(`Disconnected (${this.disconnectsCount} times)${reason || ''}`) this.state = DISCONNECTED this.disconnectsCount++ - this.log.warn('Disconnected (%d times)' + (reason || ''), this.disconnectsCount) - this.emitter.emit('browser_error', this, 'Disconnected' + (reason || '')) + this.emitter.emit('browser_error', this, `Disconnected${reason || ''}`) this.collection.remove(this) } @@ -248,18 +180,16 @@ class Browser { this.noActivityTimeoutId = this.timer.setTimeout(() => { this.lastResult.totalTimeEnd() this.lastResult.disconnected = true - this.disconnect(', because no message in ' + this.noActivityTimeout + ' ms.') + this.disconnect(`, because no message in ${this.noActivityTimeout} ms.`) this.emitter.emit('browser_complete', this) }, this.noActivityTimeout) } } clearNoActivityTimeout () { - if (this.noActivityTimeout) { - if (this.noActivityTimeoutId) { - this.timer.clearTimeout(this.noActivityTimeoutId) - this.noActivityTimeoutId = null - } + if (this.noActivityTimeout && this.noActivityTimeoutId) { + this.timer.clearTimeout(this.noActivityTimeoutId) + this.noActivityTimeoutId = null } } @@ -272,6 +202,39 @@ class Browser { socket.on('info', (info) => this.onInfo(info)) socket.on('result', (result) => this.onResult(result)) } + + isConnected () { + return this.state === CONNECTED + } + + isNotConnected () { + return !this.isConnected() + } + + serialize () { + return { + id: this.id, + name: this.name, + isConnected: this.state === CONNECTED + } + } + + toString () { + return this.name + } + + toJSON () { + return { + id: this.id, + fullName: this.fullName, + name: this.name, + state: this.state, + lastResult: this.lastResult, + disconnectsCount: this.disconnectsCount, + noActivityTimeout: this.noActivityTimeout, + disconnectDelay: this.disconnectDelay + } + } } Browser.factory = function ( diff --git a/lib/browser_collection.js b/lib/browser_collection.js index 04354af69..1f586ea03 100644 --- a/lib/browser_collection.js +++ b/lib/browser_collection.js @@ -1,6 +1,6 @@ 'use strict' -const Result = require('./browser_result') +const BrowserResult = require('./browser_result') const helper = require('./helper') class BrowserCollection { @@ -67,7 +67,7 @@ class BrowserCollection { clearResults () { this.browsers.forEach((browser) => { - browser.lastResult = new Result() + browser.lastResult = new BrowserResult() }) } diff --git a/lib/browser_result.js b/lib/browser_result.js index 1d6cb0758..02f4d4e3d 100644 --- a/lib/browser_result.js +++ b/lib/browser_result.js @@ -1,10 +1,11 @@ 'use strict' class BrowserResult { - constructor () { + constructor (total = 0) { this.startTime = Date.now() - this.total = this.skipped = this.failed = this.success = 0 + this.total = total + this.skipped = this.failed = this.success = 0 this.netTime = this.totalTime = 0 this.disconnected = this.error = false } diff --git a/lib/helper.js b/lib/helper.js index aaa00b6f5..b940309ca 100644 --- a/lib/helper.js +++ b/lib/helper.js @@ -9,8 +9,8 @@ const mm = require('minimatch') exports.browserFullNameToShort = (fullName) => { const agent = useragent.parse(fullName) - const isKnown = agent.family !== 'Other' && agent.os.family !== 'Other' - return isKnown ? agent.toAgent() + ' (' + agent.os + ')' : fullName + const isUnknown = agent.family === 'Other' || agent.os.family === 'Other' + return isUnknown ? fullName : `${agent.toAgent()} (${agent.os})` } exports.isDefined = (value) => { diff --git a/lib/middleware/common.js b/lib/middleware/common.js index 368abc830..a04d23d99 100644 --- a/lib/middleware/common.js +++ b/lib/middleware/common.js @@ -7,65 +7,36 @@ const mime = require('mime') const _ = require('lodash') const parseRange = require('range-parser') const Buffer = require('safe-buffer').Buffer - const log = require('../logger').create('web-server') -class PromiseContainer { - constructor () { - this.promise = null - } - - then (success, error) { - return this.promise.then(success, error) - } - - set (newPromise) { - this.promise = newPromise - } -} - -function serve404 (response, path) { - log.warn('404: ' + path) - response.writeHead(404) - return response.end('NOT FOUND') -} - function createServeFile (fs, directory, config) { const cache = Object.create(null) return function (filepath, rangeHeader, response, transform, content, doNotCache) { let responseData - const convertForRangeRequest = function () { + function convertForRangeRequest () { const range = parseRange(responseData.length, rangeHeader) if (range === -2) { - // malformed header string - return 200 + return 200 // malformed header string } else if (range === -1) { - // unsatisfiable range - responseData = Buffer.alloc(0) + responseData = Buffer.alloc(0) // unsatisfiable range return 416 } else if (range.type === 'bytes') { responseData = Buffer.from(responseData) if (range.length === 1) { - const start = range[0].start - const end = range[0].end - response.setHeader( - 'Content-Range', - 'bytes ' + start + '-' + end + '/' + responseData.length - ) + const { start, end } = range[0] + response.setHeader('Content-Range', `bytes ${start}-${end}/${responseData.length}`) response.setHeader('Accept-Ranges', 'bytes') response.setHeader('Content-Length', end - start + 1) responseData = responseData.slice(start, end + 1) return 206 } else { - // Multiple ranges are not supported. Maybe future? - responseData = Buffer.alloc(0) + responseData = Buffer.alloc(0) // Multiple ranges are not supported. Maybe future? return 416 } } - // All other states, ignore - return 200 + return 200 // All other states, ignore } if (directory) { @@ -77,25 +48,20 @@ function createServeFile (fs, directory, config) { } if (config && config.customHeaders && config.customHeaders.length > 0) { - config.customHeaders.forEach(function (header) { + config.customHeaders.forEach((header) => { const regex = new RegExp(header.match) if (regex.test(filepath)) { - log.debug('setting header: ' + header.name + ' for: ' + filepath) + log.debug(`setting header: ${header.name} for: ${filepath}`) response.setHeader(header.name, header.value) } }) } - // serve from cache if (content && !doNotCache) { + log.debug(`serving (cached): ${filepath}`) response.setHeader('Content-Type', mime.getType(filepath, 'text/plain')) - - // call custom transform fn to transform the data responseData = (transform && transform(content)) || content - response.writeHead(rangeHeader ? convertForRangeRequest() : 200) - - log.debug('serving (cached): ' + filepath) return response.end(responseData) } @@ -108,19 +74,22 @@ function createServeFile (fs, directory, config) { cache[filepath] = data.toString() } + log.debug('serving: ' + filepath) response.setHeader('Content-Type', mime.getType(filepath, 'text/plain')) - - // call custom transform fn to transform the data responseData = (transform && transform(data.toString())) || data - response.writeHead(rangeHeader ? convertForRangeRequest() : 200) - log.debug('serving: ' + filepath) return response.end(responseData) }) } } +function serve404 (response, path) { + log.warn(`404: ${path}`) + response.writeHead(404) + return response.end('NOT FOUND') +} + function setNoCacheHeaders (response) { response.setHeader('Cache-Control', 'no-cache') response.setHeader('Pragma', 'no-cache') @@ -133,14 +102,26 @@ function setHeavyCacheHeaders (response) { function initializeMimeTypes (config) { if (config && config.mime) { - _.forEach(config.mime, function (value, key) { - const map = {} - map[key] = value - mime.define(map, true) + _.forEach(config.mime, (value, key) => { + mime.define({ [key]: value }, true) }) } } +class PromiseContainer { + constructor () { + this.promise = null + } + + then (success, error) { + return this.promise.then(success, error) + } + + set (newPromise) { + this.promise = newPromise + } +} + // PUBLIC API exports.PromiseContainer = PromiseContainer exports.createServeFile = createServeFile diff --git a/test/unit/browser_result.spec.js b/test/unit/browser_result.spec.js index c85d3bdc7..5ba54df9a 100644 --- a/test/unit/browser_result.spec.js +++ b/test/unit/browser_result.spec.js @@ -1,7 +1,7 @@ 'use strict' describe('BrowserResult', () => { - const Result = require('../../lib/browser_result') + const BrowserResult = require('../../lib/browser_result') let result = null const successResultFromBrowser = { @@ -25,7 +25,7 @@ describe('BrowserResult', () => { beforeEach(() => { sinon.stub(Date, 'now') Date.now.returns(123) - result = new Result() + result = new BrowserResult() }) afterEach(() => { From 5cc408936a705e3f6dfd68faad3f7e6908c8521e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Fri, 12 Oct 2018 16:32:08 +0200 Subject: [PATCH 059/374] refactor(server): refactoring of stopper (#3174) --- lib/stopper.js | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/lib/stopper.js b/lib/stopper.js index 8b8ee0d57..5e87be595 100644 --- a/lib/stopper.js +++ b/lib/stopper.js @@ -1,5 +1,4 @@ const http = require('http') - const cfg = require('./config') const logger = require('./logger') const helper = require('./helper') @@ -7,33 +6,30 @@ const helper = require('./helper') exports.stop = function (config, done) { config = config || {} logger.setupFromConfig(config) - done = helper.isFunction(done) ? done : process.exit const log = logger.create('stopper') + done = helper.isFunction(done) ? done : process.exit config = cfg.parseConfig(config.configFile, config) - const options = { + const request = http.request({ hostname: config.hostname, path: config.urlRoot + 'stop', port: config.port, method: 'GET' - } - - const request = http.request(options) + }) request.on('response', function (response) { - if (response.statusCode !== 200) { - log.error('Server returned status code: ' + response.statusCode) + if (response.statusCode === 200) { + log.info('Server stopped.') + done(0) + } else { + log.error(`Server returned status code: ${response.statusCode}`) done(1) - return } - - log.info('Server stopped.') - done(0) }) request.on('error', function (e) { if (e.code === 'ECONNREFUSED') { - log.error('There is no server listening on port %d', options.port) + log.error(`There is no server listening on port ${config.port}`) done(1, e.code) } else { throw e From 4651524518df22842f69786f3f74fd4aeaf50c85 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Fri, 12 Oct 2018 16:09:33 -0700 Subject: [PATCH 060/374] feat(server): .dom files include HTML tags in page. (#3178) Add support for .dom extension files, insert the content of the file into the test HTML document. This allows 'component' tests where JS interacts with HTML. Provides a simpler alternative to solutions that use JS to embed HTML in JS then write it into the DOM. Limited to cases where the DOM fragments from different tests do not interfere. --- docs/config/02-files.md | 18 ++++++----- lib/middleware/karma.js | 22 ++++++++++++-- lib/server.js | 2 ++ lib/web-server.js | 23 ++++++++++++-- test/unit/middleware/karma.spec.js | 48 ++++++++++++++++++++++++++++++ test/unit/web-server.spec.js | 4 ++- 6 files changed, 105 insertions(+), 12 deletions(-) diff --git a/docs/config/02-files.md b/docs/config/02-files.md index 7cd632082..91de57174 100644 --- a/docs/config/02-files.md +++ b/docs/config/02-files.md @@ -34,6 +34,10 @@ Each pattern is either a simple string or an object with the following propertie * `js` * `dart` * `module` + * `dom` +* **Description.** The type determines the mechanism for including the file. The `css` and `html` types +create `link` elements; the `js`, `dart`, and `module` elements create `script` elements. The `dom` type +includes the file content in the page, used, for example, to test components combinging HTML and JS. ### `watched` * **Type.** Boolean @@ -46,17 +50,17 @@ Each pattern is either a simple string or an object with the following propertie * **Description.** Should the files be included in the browser using ` %SCRIPTS% - + diff --git a/static/debug.html b/static/debug.html index 7d4c45461..3fc6173f2 100644 --- a/static/debug.html +++ b/static/debug.html @@ -28,7 +28,12 @@ %SCRIPTS% - + diff --git a/test/e2e/module-types.feature b/test/e2e/module-types.feature new file mode 100644 index 000000000..0a2011b5e --- /dev/null +++ b/test/e2e/module-types.feature @@ -0,0 +1,35 @@ +Feature: ES Modules + In order to use Karma + As a person who wants to write great tests + I want to use different script types with Karma. + + Scenario: Globbing modules, with both .js and .mjs extensions + Given a configuration with: + """ + files = [ + { pattern: 'modules/**/*.js', type: 'module' }, + { pattern: 'modules/**/*.mjs', type: 'module' }, + ]; + // Chrome fails on Travis, so we must use Firefox (which means we must + // manually enable modules). + customLaunchers = { + FirefoxWithModules: { + base: 'Firefox', + prefs: { + 'dom.moduleScripts.enabled': true + } + } + }; + browsers = ['FirefoxWithModules']; + frameworks = ['mocha', 'chai']; + plugins = [ + 'karma-mocha', + 'karma-chai', + 'karma-firefox-launcher' + ]; + """ + When I start Karma + Then it passes with like: + """ + Executed 4 of 4 SUCCESS + """ diff --git a/test/e2e/support/modules/__tests__/minus.test.mjs b/test/e2e/support/modules/__tests__/minus.test.mjs new file mode 100644 index 000000000..4f1401794 --- /dev/null +++ b/test/e2e/support/modules/__tests__/minus.test.mjs @@ -0,0 +1,11 @@ +import { minus } from '../minus.mjs' + +describe('minus', function () { + it('should pass', function () { + expect(true).to.be.true + }) + + it('should work', function () { + expect(minus(3, 2)).to.equal(1) + }) +}) diff --git a/test/e2e/support/modules/__tests__/plus.test.js b/test/e2e/support/modules/__tests__/plus.test.js new file mode 100644 index 000000000..305f9589f --- /dev/null +++ b/test/e2e/support/modules/__tests__/plus.test.js @@ -0,0 +1,11 @@ +import { plus } from '../plus.js' + +describe('plus', function () { + it('should pass', function () { + expect(true).to.be.true + }) + + it('should work', function () { + expect(plus(1, 2)).to.equal(3) + }) +}) diff --git a/test/e2e/support/modules/minus.mjs b/test/e2e/support/modules/minus.mjs new file mode 100644 index 000000000..811152cc9 --- /dev/null +++ b/test/e2e/support/modules/minus.mjs @@ -0,0 +1,4 @@ +// Some code under test +export function minus (a, b) { + return a - b +} diff --git a/test/e2e/support/modules/plus.js b/test/e2e/support/modules/plus.js new file mode 100644 index 000000000..7699b6298 --- /dev/null +++ b/test/e2e/support/modules/plus.js @@ -0,0 +1,4 @@ +// Some code under test +export function plus (a, b) { + return a + b +} From 7634e7145b4220123f317d652b3dd13bd12c32ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Usarz?= Date: Tue, 16 Oct 2018 01:40:46 +0200 Subject: [PATCH 064/374] fix(browser): emit 'browsers_change' in collection (#3183) --- lib/browser.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/browser.js b/lib/browser.js index 3bcfbe9c5..1301c93a5 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -37,7 +37,6 @@ class Browser { this.bindSocketEvents(this.socket) this.collection.add(this) - this.emitter.emit('browsers_change', this.collection) // TODO(vojta): move to collection this.emitter.emit('browser_register', this) } @@ -128,7 +127,6 @@ class Browser { this.state = CONNECTED this.collection.add(this) - this.emitter.emit('browsers_change', this.collection) // TODO(vojta): move to collection this.emitter.emit('browser_register', this) } From c311ac00cef4a957f889ed613238793c0ffa95a2 Mon Sep 17 00:00:00 2001 From: lukasz Date: Fri, 12 Oct 2018 08:49:11 +0200 Subject: [PATCH 065/374] refactor(server): use ES6 string interpolation wherever possible --- lib/cli.js | 6 +++--- lib/completion.js | 6 +++--- lib/config.js | 2 +- lib/file-list.js | 24 ++++++++++++------------ lib/init.js | 31 ++++++++++++------------------- lib/launcher.js | 7 +------ lib/launchers/base.js | 2 +- lib/launchers/capture_timeout.js | 2 +- lib/launchers/process.js | 24 +++++++++++------------- lib/launchers/retry.js | 7 +++---- lib/middleware/karma.js | 8 ++++---- lib/middleware/proxy.js | 4 ++-- lib/middleware/runner.js | 2 +- lib/middleware/source_files.js | 4 ++-- lib/plugin.js | 2 +- lib/preprocessor.js | 5 ++--- lib/reporter.js | 6 +++--- lib/reporters/base.js | 7 +++---- lib/server.js | 2 +- lib/watcher.js | 2 +- lib/web-server.js | 2 +- 21 files changed, 69 insertions(+), 86 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index bdfa87a55..41fbee184 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -15,7 +15,7 @@ function processArgs (argv, options, fs, path) { } if (argv.version) { - console.log('Karma version: ' + constant.VERSION) + console.log(`Karma version: ${constant.VERSION}`) process.exit(0) } @@ -24,7 +24,7 @@ function processArgs (argv, options, fs, path) { let argumentValue = argv[name] if (name !== '_' && name !== '$0') { if (name.includes('_')) { - throw new Error('Bad argument: ' + name + ' did you mean ' + name.replace('_', '-')) + throw new Error(`Bad argument: ${name} did you mean ${name.replace('_', '-')}`) } if (Array.isArray(argumentValue)) { // If the same argument is defined multiple times, override. @@ -60,7 +60,7 @@ function processArgs (argv, options, fs, path) { // support exports.formatError and module.exports = function options.formatError = required.formatError || required if (!helper.isFunction(options.formatError)) { - console.error('Format error must be a function, got: ' + typeof options.formatError) + console.error(`Format error must be a function, got: ${typeof options.formatError}`) process.exit(1) } } diff --git a/lib/completion.js b/lib/completion.js index 32e5dc8a6..df58a79da 100644 --- a/lib/completion.js +++ b/lib/completion.js @@ -35,11 +35,11 @@ const options = { } function opositeWord (word) { - if (!word.startsWith('-')) { + if (word.startsWith('-')) { + return word.startsWith('--no-') ? `--${word.substr(5)}` : `--no-${word.substr(2)}` + } else { return null } - - return word.substr(0, 5) === '--no-' ? '--' + word.substr(5) : '--no-' + word.substr(2) } function sendCompletion (possibleWords, env) { diff --git a/lib/config.js b/lib/config.js index 919782a88..fe90c927a 100644 --- a/lib/config.js +++ b/lib/config.js @@ -234,7 +234,7 @@ function normalizeConfig (config, configFilePath) { const types = ['launcher', 'preprocessor', 'reporter'] types.forEach(function (type) { - const definitions = config['custom' + helper.ucFirst(type) + 's'] || {} + const definitions = config[`custom${helper.ucFirst(type)}s`] || {} Object.keys(definitions).forEach(function (name) { const definition = definitions[name] diff --git a/lib/file-list.js b/lib/file-list.js index 35f5058e2..a6dac0f25 100644 --- a/lib/file-list.js +++ b/lib/file-list.js @@ -80,13 +80,13 @@ class FileList { const files = mg.found if (_.isEmpty(files)) { this.buckets.set(pattern, []) - log.warn('Pattern "%s" does not match any file.', pattern) + log.warn(`Pattern "${pattern}" does not match any file.`) return } return Promise.map(files, (path) => { if (this._findExcluded(path)) { - log.debug('Excluded file "%s"', path) + log.debug(`Excluded file "${path}"`) return Promise.resolve() } @@ -98,7 +98,7 @@ class FileList { const file = new File(path, mg.statCache[path].mtime, patternObject.nocache, type) if (file.doNotCache) { - log.debug('Not preprocessing "%s" due to nocache', pattern) + log.debug(`Not preprocessing "${pattern}" due to nocache`) return Promise.resolve(file) } @@ -109,7 +109,7 @@ class FileList { this.buckets.set(pattern, files) if (_.isEmpty(files)) { - log.warn('All files matched by "%s" were excluded or matched by prior matchers.', pattern) + log.warn(`All files matched by "${pattern}" were excluded or matched by prior matchers.`) } }) }) @@ -180,18 +180,18 @@ class FileList { addFile (path) { const excluded = this._findExcluded(path) if (excluded) { - log.debug('Add file "%s" ignored. Excluded by "%s".', path, excluded) + log.debug(`Add file "${path}" ignored. Excluded by "${excluded}".`) return Promise.resolve(this.files) } const pattern = this._findIncluded(path) if (!pattern) { - log.debug('Add file "%s" ignored. Does not match any pattern.', path) + log.debug(`Add file "${path}" ignored. Does not match any pattern.`) return Promise.resolve(this.files) } if (this._exists(path)) { - log.debug('Add file "%s" ignored. Already in the list.', path) + log.debug(`Add file "${path}" ignored. Already in the list.`) return Promise.resolve(this.files) } @@ -207,7 +207,7 @@ class FileList { return this._preprocess(file) }) .then(() => { - log.info('Added file "%s".', path) + log.info(`Added file "${path}".`) this._emitModified() return this.files }) @@ -218,7 +218,7 @@ class FileList { const file = this._findFile(path, pattern) if (!file) { - log.debug('Changed file "%s" ignored. Does not match any file in the list.', path) + log.debug(`Changed file "${path}" ignored. Does not match any file in the list.`) return Promise.resolve(this.files) } @@ -232,7 +232,7 @@ class FileList { return this._preprocess(file) }) .then(() => { - log.info('Changed file "%s".', path) + log.info(`Changed file "${path}".`) this._emitModified(force) return this.files }) @@ -246,11 +246,11 @@ class FileList { if (file) { helper.arrayRemove(this._getFilesByPattern(pattern.pattern), file) - log.info('Removed file "%s".', path) + log.info(`Removed file "${path}".`) this._emitModified() } else { - log.debug('Removed file "%s" ignored. Does not match any file in the list.', path) + log.debug(`Removed file "${path}" ignored. Does not match any file in the list.`) } return this.files }) diff --git a/lib/init.js b/lib/init.js index 2257743ee..9bd050f55 100755 --- a/lib/init.js +++ b/lib/init.js @@ -36,26 +36,24 @@ function installPackage (pkgName) { return } catch (e) {} - log.debug('Missing plugin "%s". Installing...', pkgName) + log.debug(`Missing plugin "${pkgName}". Installing...`) const options = { cwd: path.resolve(NODE_MODULES_DIR, '..') } - exec('npm install ' + pkgName + ' --save-dev', options, function (err, stdout, stderr) { + exec(`npm install ${pkgName} --save-dev`, options, function (err, stdout, stderr) { // Put the logs into the queue and print them after answering current question. // Otherwise the log would clobber the interactive terminal. logQueue.push(function () { if (!err) { - log.debug('%s successfully installed.', pkgName) + log.debug(`${pkgName} successfully installed.`) } else if (/is not in the npm registry/.test(stderr)) { - log.warn('Failed to install "%s". It is not in the NPM registry!\n' + - ' Please install it manually.', pkgName) + log.warn(`Failed to install "${pkgName}". It is not in the NPM registry!\n Please install it manually.`) } else if (/Error: EACCES/.test(stderr)) { - log.warn('Failed to install "%s". No permissions to write in %s!\n' + - ' Please install it manually.', pkgName, options.cwd) + log.warn(`Failed to install "${pkgName}". No permissions to write in ${options.cwd}!\n Please install it manually.`) } else { - log.warn('Failed to install "%s"\n Please install it manually.', pkgName) + log.warn(`Failed to install "${pkgName}"\n Please install it manually.`) } }) }) @@ -91,8 +89,7 @@ var questions = [{ }, { id: 'requirejs', question: 'Do you want to use Require.js ?', - hint: 'This will add Require.js plugin.\n' + - 'Press tab to list possible options. Enter to move to the next question.', + hint: 'This will add Require.js plugin.\nPress tab to list possible options. Enter to move to the next question.', options: ['no', 'yes'], validate: validateRequireJs, boolean: true @@ -106,15 +103,13 @@ var questions = [{ }, { id: 'files', question: 'What is the location of your source and test files ?', - hint: 'You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".\n' + - 'Enter empty string to move to the next question.', + hint: 'You can use glob patterns, eg. "js/*.js" or "test/**/*Spec.js".\nEnter empty string to move to the next question.', multiple: true, validate: validatePattern }, { id: 'exclude', question: 'Should any of the files included by the previous patterns be excluded ?', - hint: 'You can use glob patterns, eg. "**/*.swp".\n' + - 'Enter empty string to move to the next question.', + hint: 'You can use glob patterns, eg. "**/*.swp".\nEnter empty string to move to the next question.', multiple: true, validate: validatePattern }, { @@ -126,7 +121,7 @@ var questions = [{ condition: (answers) => answers.requirejs }, { id: 'includedFiles', - question: 'Which files do you want to include with ` tag. + * `dart` - Include using `` tag. Note that this does not work in the modern browsers. + * `module` - Include using `` tag. + * `dom` - Inline content of the file in the page. This can be used, for example, to test components combining HTML and JS. +* **Description.** The type determines the mechanism for including the file. ### `watched` * **Type.** Boolean From fffbaeeffbe725e1a756135ca0e9f05fafd482c2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 8 Sep 2020 16:16:48 +0000 Subject: [PATCH 266/374] chore(release): 5.2.2 [skip ci] ## [5.2.2](https://github.com/karma-runner/karma/compare/v5.2.1...v5.2.2) (2020-09-08) ### Bug Fixes * revert source-map update ([#3559](https://github.com/karma-runner/karma/issues/3559)) ([d9ba284](https://github.com/karma-runner/karma/commit/d9ba2849ced403a2ff2574d8e3a14deee21f1cc4)), closes [#3557](https://github.com/karma-runner/karma/issues/3557) --- CHANGELOG.md | 7 + package-lock.json | 2 +- package.json | 348 +++++++++++++++++++++++----------------------- 3 files changed, 183 insertions(+), 174 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8cc0b860..dd316ddad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.2.2](https://github.com/karma-runner/karma/compare/v5.2.1...v5.2.2) (2020-09-08) + + +### Bug Fixes + +* revert source-map update ([#3559](https://github.com/karma-runner/karma/issues/3559)) ([d9ba284](https://github.com/karma-runner/karma/commit/d9ba2849ced403a2ff2574d8e3a14deee21f1cc4)), closes [#3557](https://github.com/karma-runner/karma/issues/3557) + ## [5.2.1](https://github.com/karma-runner/karma/compare/v5.2.0...v5.2.1) (2020-09-02) diff --git a/package-lock.json b/package-lock.json index 55f1bc086..4431cccb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "5.2.1", + "version": "5.2.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a210f1c38..719c5336e 100644 --- a/package.json +++ b/package.json @@ -26,113 +26,224 @@ "Friedel Ziegelmayer ", "dignifiedquire ", "johnjbarton ", - "greenkeeperio-bot ", "Yaroslav Admin ", + "greenkeeperio-bot ", "Karma Bot ", "Maksim Ryzhikov ", "ukasz Usarz ", "Christian Budde Christensen ", - "taichi ", "Wesley Cho ", "semantic-release-bot ", + "taichi ", "Liam Newman ", "lukasz ", "Anton ", - "Todd Wolfson ", "Michał Gołębiowski-Owczarek ", + "Todd Wolfson ", "Mark Trostler ", "Ciro Nunes ", - "Tim Cuthbertson ", - "Pawel Kozlowski ", "Christian Budde Christensen ", - "Shyam Seshadri ", + "Pawel Kozlowski ", "Robo ", - "Mourad ", + "Shyam Seshadri ", + "Tim Cuthbertson ", "Daniel Compton ", "Mark Ethan Trostler ", - "Kim Joar Bekkelund ", - "vivganes ", - "joshjb84 ", - "Georgii Dolzhykov ", - "Nick Malaguti ", + "Mourad ", "Brian Di Palma ", + "Georgii Dolzhykov ", + "Kim Joar Bekkelund ", "Matthias Oßwald <1410947+matz3@users.noreply.github.com>", - "Daniel Aleksandersen ", + "Nick Malaguti ", + "joshjb84 ", + "vivganes ", "Andrew Martin ", - "Iristyle ", - "ywong ", - "Chris Casola ", "Aymeric Beaumet ", - "Jeff Jewiss ", - "Pieter Mees ", - "Jake Champion ", - "Marcello Nuccio ", - "Jérémy Judéaux ", "Brian Ford ", + "Chris Casola ", "Chris Hunt ", - "Ilya Volodin ", + "Daniel Aleksandersen ", "David Souther ", + "Ilya Volodin ", + "Iristyle ", + "Jake Champion ", + "Jeff Jewiss ", + "Jérémy Judéaux ", + "Marcello Nuccio ", + "Pieter Mees ", "pavelgj ", "sylvain-hamel ", + "ywong ", + "Andrew Morris ", + "Aseem Bansal ", + "Bryan Smith ", + "Bulat Shakirzyanov ", + "ChangZhuo Chen (陳昌倬) ", + "Cyrus Chan ", + "DarthCharles ", + "David Herges ", + "David Pärsson ", + "Ethan J. Brown ", + "Ezra Brooks ", + "Filipe Guerra ", + "Greenkeeper ", + "Hugues Malphettes ", + "Igor Minar ", + "Igor Minar ", + "Ilya Goncharov ", + "James Ford ", + "James Talmage ", + "Jonas Pommerening ", + "Jonathan Freeman ", + "Josh ", + "KJ Tsanaktsidis ", + "Keen Yee Liau ", + "Kelly Jensen ", + "Kevin Huang ", + "Kevin WENNER ", + "Levi Thomason ", + "Luke Page ", + "Matt Lewis ", + "Nico Jansen ", + "Parashuram ", + "Pat Tullmann ", + "PatrickJS ", + "Richard Harrington ", + "Roarke Gaskill ", "Robert Stein ", - "ngiebel ", "Robin Liang ", - "rdodev ", - "Filipe Guerra ", "Ruben Bridgewater ", - "Bryan Smith ", "Réda Housni Alaoui ", - "David Pärsson ", "Sammy Jelin ", - "Jonas Pommerening ", "Sergei Startsev ", "Sergey Simonchik ", "Sergey Simonchik ", - "Jonathan Freeman ", - "Bulat Shakirzyanov ", "Shane Russell ", - "Josh ", - "Andrew Morris ", - "Greenkeeper ", "Stefan Dragnev ", "Steve Mao ", "Steve Mao ", "Steve Van Opstal ", "Sylvain Hamel ", - "KJ Tsanaktsidis ", - "Nico Jansen ", "Terry ", - "Cyrus Chan ", - "Hugues Malphettes ", "Thomas Parisot ", - "Igor Minar ", - "Keen Yee Liau ", - "Igor Minar ", "Tom Erik Støwer ", - "Kelly Jensen ", - "Ilya Goncharov ", - "Kevin Huang ", - "Kevin WENNER ", - "Parashuram ", "Vivek Ganesan ", "Vladimir Starkov ", - "Pat Tullmann ", - "ChangZhuo Chen (陳昌倬) ", - "PatrickJS ", - "Levi Thomason ", - "Aseem Bansal ", - "Luke Page ", "comdiv ", - "James Ford ", - "James Talmage ", - "DarthCharles ", - "Richard Harrington ", "karmarunnerbot ", - "Ethan J. Brown ", - "Ezra Brooks ", - "Roarke Gaskill ", - "Matt Lewis ", - "David Herges ", + "ngiebel ", + "rdodev ", + "u812 <0u812@github.com>", + "Aaron Powell ", + "Adrien Crivelli ", + "Alan Agius ", + "Alejandro Mantecon Guillen ", + "Ales Rosina ", + "Alexander Pepper ", + "Alexander Shtuchkin ", + "Alexei ", + "Ameer Jhan ", + "Anders Ekdahl ", + "Anders Janmyr ", + "Andreas Krummsdorf ", + "Andreas Pålsson ", + "Andrew Fischer ", + "Andrew Marcinkevičius ", + "Andrey Chalkin ", + "Andy Joslin ", + "Anton Usmansky ", + "Atul Bhosale ", + "AugustinLF ", + "AvnerCohen ", + "Awad Mackie ", + "Basemm ", + "Benoit Charbonnier ", + "Bhavesh Kakadiya ", + "Borewit ", + "Brady Wied ", + "Bram Borggreve ", + "Breno Calazans ", + "Brian Donovan ", + "Brian Donovan ", + "Brian M Hunt ", + "Cagdas Bayram ", + "Carl Goldberg ", + "Chad Smith ", + "Chang Wang ", + "Chelsea Urquhart ", + "Chris ", + "Chris Chua ", + "Chris Dawson ", + "Christian Weiss ", + "Christopher Hiller ", + "Chuf <42591821+GChuf@users.noreply.github.com>", + "Ciro S. Costa ", + "Daan Stolp ", + "Damien Choizit ", + "Dan Siwiec ", + "Dan Thareja ", + "Danny Croft ", + "Danny Tuppeny ", + "David Jensen ", + "David M. Karr ", + "Derek Gould ", + "Derek Schaller ", + "Dieter Oberkofler ", + "Dillon ", + "Dmitrii Abramov ", + "Dmitriy Ryajov ", + "Douglas Blumeyer ", + "Douglas Blumeyer ", + "Dunja Radulov ", + "ERt ", + "Ed Rooth ", + "Eddie Monge ", + "Eden ", + "Edward Hutchins ", + "Eldar Jafarov ", + "Eric Baer ", + "Esteban Marin ", + "Fabian Beuke ", + "Filipe Silva ", + "Franck Garcia ", + "Fred Sauer ", + "Frederic Hemberger ", + "Fredrik Bonander ", + "Gavin Aiken ", + "Geert Van Laethem ", + "Glenn Anderson ", + "Greg Thornton ", + "Gregory Cowan ", + "Hendrik Purmann ", + "Homa Wong ", + "Igor Lima ", + "Islam Sharabash ", + "Jack Tarantino ", + "Jacob Trimble ", + "Jakub Z ", + "James Shore ", + "Jan Molak ", + "Janderson Constantino ", + "Jeff Froom ", + "Jeff Lage ", + "Jeff Yates ", + "Jeremy Axelrod ", + "Jerry Reptak ", + "Jesse M. Holmes ", + "Joe Lencioni ", + "Johannes Gorset ", + "John Wehr ", + "Jon Bretman ", + "Jonathan ES Lin ", + "Jonathan Felchlin ", + "Jonathan Niles ", + "Josh Lory ", + "João Marcos Duarte ", + "Julian Connor ", + "Jurko Gospodnetić ", + "Justin Ridgewell ", + "KahWee Teng ", + "Karl Lindmark ", "Karol Fabjańczuk ", "Karolis Narkevicius ", "Keats ", @@ -140,6 +251,7 @@ "Kent C. Dodds ", "Kevin Ortman ", "Kostiantyn Kahanskyi ", + "Kris Kowal ", "Lenny Urbanowski ", "LoveIsGrief ", "Lucas Theisen ", @@ -207,6 +319,7 @@ "Piper Chester ", "Rafal Lindemann ", "Remy Sharp ", + "Ricardo Melo Joia ", "Rich Kuzsma ", "Richard Herrera ", "Roarke Gaskill ", @@ -287,118 +400,7 @@ "thorn0 ", "toran billups ", "chalkerx@gmail.com>", - "u812 <0u812@github.com>", - "weiran.zsd@outlook.com>", - "Aaron Powell ", - "Adrien Crivelli ", - "Alan Agius ", - "Alejandro Mantecon Guillen ", - "Ales Rosina ", - "Alexander Pepper ", - "Alexander Shtuchkin ", - "Alexei ", - "Ameer Jhan ", - "Anders Ekdahl ", - "Anders Janmyr ", - "Andreas Krummsdorf ", - "Andreas Pålsson ", - "Andrew Fischer ", - "Andrew Marcinkevičius ", - "Andrey Chalkin ", - "Andy Joslin ", - "Anton Usmansky ", - "Atul Bhosale ", - "AugustinLF ", - "AvnerCohen ", - "Awad Mackie ", - "Basemm ", - "Benoit Charbonnier ", - "Bhavesh Kakadiya ", - "Borewit ", - "Brady Wied ", - "Bram Borggreve ", - "Breno Calazans ", - "Brian Donovan ", - "Brian Donovan ", - "Brian M Hunt ", - "Cagdas Bayram ", - "Carl Goldberg ", - "Chad Smith ", - "Chang Wang ", - "Chelsea Urquhart ", - "Chris ", - "Chris Chua ", - "Chris Dawson ", - "Christian Weiss ", - "Christopher Hiller ", - "Chuf <42591821+GChuf@users.noreply.github.com>", - "Ciro S. Costa ", - "Daan Stolp ", - "Damien Choizit ", - "Dan Siwiec ", - "Dan Thareja ", - "Danny Croft ", - "Danny Tuppeny ", - "David Jensen ", - "David M. Karr ", - "Derek Gould ", - "Derek Schaller ", - "Dieter Oberkofler ", - "Dillon ", - "Dmitrii Abramov ", - "Dmitriy Ryajov ", - "Douglas Blumeyer ", - "Douglas Blumeyer ", - "Dunja Radulov ", - "ERt ", - "Ed Rooth ", - "Eddie Monge ", - "Eden ", - "Edward Hutchins ", - "Eldar Jafarov ", - "Eric Baer ", - "Esteban Marin ", - "Fabian Beuke ", - "Filipe Silva ", - "Franck Garcia ", - "Fred Sauer ", - "Frederic Hemberger ", - "Fredrik Bonander ", - "Gavin Aiken ", - "Geert Van Laethem ", - "Glenn Anderson ", - "Greg Thornton ", - "Gregory Cowan ", - "Hendrik Purmann ", - "Homa Wong ", - "Igor Lima ", - "Islam Sharabash ", - "Jack Tarantino ", - "Jacob Trimble ", - "Jakub Z ", - "James Shore ", - "Jan Molak ", - "Janderson Constantino ", - "Jeff Froom ", - "Jeff Lage ", - "Jeff Yates ", - "Jeremy Axelrod ", - "Jerry Reptak ", - "Jesse M. Holmes ", - "Joe Lencioni ", - "Johannes Gorset ", - "John Wehr ", - "Jon Bretman ", - "Jonathan ES Lin ", - "Jonathan Felchlin ", - "Jonathan Niles ", - "Josh Lory ", - "João Marcos Duarte ", - "Julian Connor ", - "Jurko Gospodnetić ", - "Justin Ridgewell ", - "KahWee Teng ", - "Karl Lindmark " + "weiran.zsd@outlook.com>" ], "dependencies": { "body-parser": "^1.19.0", @@ -486,7 +488,7 @@ "engines": { "node": ">= 10" }, - "version": "5.2.1", + "version": "5.2.2", "license": "MIT", "husky": { "hooks": { From 500ed25d7e523efe7e7cff2ec70830be7e6e797a Mon Sep 17 00:00:00 2001 From: Donovan Hutchinson Date: Fri, 25 Sep 2020 16:26:35 +0100 Subject: [PATCH 267/374] fix: update us-parser-js dependency (#3564) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4431cccb7..cf4492544 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15588,9 +15588,9 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.21", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz", - "integrity": "sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ==" + "version": "0.7.22", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz", + "integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==" }, "uglify-js": { "version": "3.6.0", diff --git a/package.json b/package.json index 719c5336e..2e00d75c0 100644 --- a/package.json +++ b/package.json @@ -424,7 +424,7 @@ "socket.io": "^2.3.0", "source-map": "^0.6.1", "tmp": "0.2.1", - "ua-parser-js": "0.7.21", + "ua-parser-js": "0.7.22", "yargs": "^15.3.1" }, "devDependencies": { From ead31cd99238da86ab8b2d8ff5aff465959f4106 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 25 Sep 2020 15:45:03 +0000 Subject: [PATCH 268/374] chore(release): 5.2.3 [skip ci] ## [5.2.3](https://github.com/karma-runner/karma/compare/v5.2.2...v5.2.3) (2020-09-25) ### Bug Fixes * update us-parser-js dependency ([#3564](https://github.com/karma-runner/karma/issues/3564)) ([500ed25](https://github.com/karma-runner/karma/commit/500ed25d7e523efe7e7cff2ec70830be7e6e797a)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 5 +++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd316ddad..43738ff94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [5.2.3](https://github.com/karma-runner/karma/compare/v5.2.2...v5.2.3) (2020-09-25) + + +### Bug Fixes + +* update us-parser-js dependency ([#3564](https://github.com/karma-runner/karma/issues/3564)) ([500ed25](https://github.com/karma-runner/karma/commit/500ed25d7e523efe7e7cff2ec70830be7e6e797a)) + ## [5.2.2](https://github.com/karma-runner/karma/compare/v5.2.1...v5.2.2) (2020-09-08) diff --git a/package-lock.json b/package-lock.json index cf4492544..19f4e6272 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "5.2.2", + "version": "5.2.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2e00d75c0..3d34ac795 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "Maksim Ryzhikov ", "ukasz Usarz ", "Christian Budde Christensen ", - "Wesley Cho ", "semantic-release-bot ", + "Wesley Cho ", "taichi ", "Liam Newman ", "lukasz ", @@ -192,6 +192,7 @@ "Dillon ", "Dmitrii Abramov ", "Dmitriy Ryajov ", + "Donovan Hutchinson ", "Douglas Blumeyer ", "Douglas Blumeyer ", "Dunja Radulov ", @@ -488,7 +489,7 @@ "engines": { "node": ">= 10" }, - "version": "5.2.2", + "version": "5.2.3", "license": "MIT", "husky": { "hooks": { From e5086fc1f2a8d69d30ea6313589fb32f072aae68 Mon Sep 17 00:00:00 2001 From: Jonathan Ginsburg Date: Mon, 5 Oct 2020 12:28:20 -0500 Subject: [PATCH 269/374] docs: clarify `browser_complete` vs `run_complete` --- docs/dev/04-public-api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/04-public-api.md b/docs/dev/04-public-api.md index 783f8e8f5..ff327a41a 100644 --- a/docs/dev/04-public-api.md +++ b/docs/dev/04-public-api.md @@ -113,7 +113,7 @@ A test run starts. * `browsers`: A collection of browser instances * `results`: A list of results -A test run was completed. +This event gets triggered whenever all the browsers, which belong to a test run, finish. For example, on a run that has 3 browsers, one would expect 3 `browser_complete` events before the `run_complete` one. ## karma.runner From 05dc28801627e3ce7054ae548046714dc2cf7a5e Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 6 Oct 2020 09:50:36 -0700 Subject: [PATCH 270/374] fix(context): do not error when karma is navigating (#3565) Change the flag name to karmaNavigating and set it along all paths where karma deliberately navigates. Other paths must be wrong. Fixes #3560 --- client/karma.js | 12 +++++++----- static/karma.js | 12 +++++++----- test/client/karma.spec.js | 23 +++++++++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/client/karma.js b/client/karma.js index 2bd4f2cf3..ec0db417e 100644 --- a/client/karma.js +++ b/client/karma.js @@ -4,7 +4,7 @@ var util = require('../common/util') function Karma (socket, iframe, opener, navigator, location, document) { var startEmitted = false - var reloadingContext = false + var karmaNavigating = false var self = this var queryParams = util.parseQueryParams(location.search) var browserId = queryParams.id || util.generateId('manual-') @@ -80,6 +80,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { var childWindow = null function navigateContextTo (url) { + karmaNavigating = true if (self.config.useIframe === false) { // run in new window if (self.config.runInParent === false) { @@ -89,9 +90,11 @@ function Karma (socket, iframe, opener, navigator, location, document) { childWindow.close() } childWindow = opener(url) + karmaNavigating = false // run context on parent element (client_with_context) // using window.__karma__.scriptUrls to get the html element strings and load them dynamically } else if (url !== 'about:blank') { + karmaNavigating = false var loadScript = function (idx) { if (idx < window.__karma__.scriptUrls.length) { var parser = new DOMParser() @@ -123,20 +126,19 @@ function Karma (socket, iframe, opener, navigator, location, document) { // run in iframe } else { iframe.src = policy.createURL(url) + karmaNavigating = false } } this.onbeforeunload = function () { - if (!reloadingContext) { + if (!karmaNavigating) { // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) self.error('Some of your tests did a full page reload!') } - reloadingContext = false + karmaNavigating = false } function clearContext () { - reloadingContext = true - navigateContextTo('about:blank') } diff --git a/static/karma.js b/static/karma.js index bb3630d98..bc3a2bbb6 100644 --- a/static/karma.js +++ b/static/karma.js @@ -14,7 +14,7 @@ var util = require('../common/util') function Karma (socket, iframe, opener, navigator, location, document) { var startEmitted = false - var reloadingContext = false + var karmaNavigating = false var self = this var queryParams = util.parseQueryParams(location.search) var browserId = queryParams.id || util.generateId('manual-') @@ -90,6 +90,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { var childWindow = null function navigateContextTo (url) { + karmaNavigating = true if (self.config.useIframe === false) { // run in new window if (self.config.runInParent === false) { @@ -99,9 +100,11 @@ function Karma (socket, iframe, opener, navigator, location, document) { childWindow.close() } childWindow = opener(url) + karmaNavigating = false // run context on parent element (client_with_context) // using window.__karma__.scriptUrls to get the html element strings and load them dynamically } else if (url !== 'about:blank') { + karmaNavigating = false var loadScript = function (idx) { if (idx < window.__karma__.scriptUrls.length) { var parser = new DOMParser() @@ -133,20 +136,19 @@ function Karma (socket, iframe, opener, navigator, location, document) { // run in iframe } else { iframe.src = policy.createURL(url) + karmaNavigating = false } } this.onbeforeunload = function () { - if (!reloadingContext) { + if (!karmaNavigating) { // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) self.error('Some of your tests did a full page reload!') } - reloadingContext = false + karmaNavigating = false } function clearContext () { - reloadingContext = true - navigateContextTo('about:blank') } diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index bc3ad81f2..a309b174f 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -145,6 +145,29 @@ describe('Karma', function () { }) it('should error out if a script attempted to reload the browser after setup', function (done) { + // Perform setup + var config = ck.config = { + clearContext: false + } + socket.emit('execute', config) + + setTimeout(function nextEventLoop () { + var mockWindow = {} + ck.setupContext(mockWindow) + + // Spy on our error handler + sinon.spy(k, 'error') + + // Emulate an unload event + mockWindow.onbeforeunload() + + // Assert our spy was called + assert(k.error.calledWith('Some of your tests did a full page reload!')) + done() + }) + }) + + it('should error out if a script attempted to reload the browser after setup with clearContext true', function (done) { // Perform setup var config = ck.config = { clearContext: true From f819fa843fa0633edbe2af6ac2889e25ea2cb639 Mon Sep 17 00:00:00 2001 From: SymbioticKilla <59652865+SymbioticKilla@users.noreply.github.com> Date: Mon, 14 Dec 2020 21:29:08 +0100 Subject: [PATCH 271/374] fix(cve): update ua-parser-js to 0.7.23 to fix CVE-2020-7793 (#3584) --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19f4e6272..6c681e6a7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15588,9 +15588,9 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.22", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.22.tgz", - "integrity": "sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==" + "version": "0.7.23", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.23.tgz", + "integrity": "sha512-m4hvMLxgGHXG3O3fQVAyyAQpZzDOvwnhOTjYz5Xmr7r/+LpkNy3vJXdVRWgd1TkAb7NGROZuSy96CrlNVjA7KA==" }, "uglify-js": { "version": "3.6.0", diff --git a/package.json b/package.json index 3d34ac795..b4b402cc7 100644 --- a/package.json +++ b/package.json @@ -425,7 +425,7 @@ "socket.io": "^2.3.0", "source-map": "^0.6.1", "tmp": "0.2.1", - "ua-parser-js": "0.7.22", + "ua-parser-js": "^0.7.23", "yargs": "^15.3.1" }, "devDependencies": { From 3fed0bc7dd042a09c8aec55c059654781a4584ec Mon Sep 17 00:00:00 2001 From: SymbioticKilla <59652865+SymbioticKilla@users.noreply.github.com> Date: Tue, 15 Dec 2020 00:13:51 +0100 Subject: [PATCH 272/374] fix(cve): update yargs to 16.1.1 to fix cve-2020-7774 in y18n (#3578) Fixes #3577 --- package-lock.json | 252 ++++++++++++++++++++++++++++++---------------- package.json | 2 +- 2 files changed, 166 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c681e6a7..ec82cd750 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2329,7 +2329,8 @@ "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true }, "@types/events": { "version": "3.0.0", @@ -3656,13 +3657,13 @@ } }, "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" }, "dependencies": { "ansi-regex": { @@ -4750,7 +4751,8 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true }, "decamelize-keys": { "version": "1.1.0", @@ -5268,6 +5270,11 @@ "ext": "^1.1.2" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -14018,7 +14025,8 @@ "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "requires-port": { "version": "1.0.0", @@ -14202,6 +14210,53 @@ "yargs": "^15.0.1" }, "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, "cosmiconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", @@ -14224,6 +14279,12 @@ "ms": "^2.1.1" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -14252,6 +14313,12 @@ "lru-cache": "^5.1.1" } }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -14358,11 +14425,77 @@ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } }, @@ -14404,7 +14537,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, "set-value": { "version": "2.0.1", @@ -16046,7 +16180,8 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true }, "which-pm-runs": { "version": "1.0.0", @@ -16121,9 +16256,9 @@ "dev": true }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -16136,11 +16271,10 @@ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -16233,9 +16367,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" }, "yallist": { "version": "3.0.3", @@ -16253,21 +16387,17 @@ } }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz", + "integrity": "sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, "dependencies": { "ansi-regex": { @@ -16275,64 +16405,16 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", @@ -16352,13 +16434,9 @@ } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" } } }, diff --git a/package.json b/package.json index b4b402cc7..13e36d87f 100644 --- a/package.json +++ b/package.json @@ -426,7 +426,7 @@ "source-map": "^0.6.1", "tmp": "0.2.1", "ua-parser-js": "^0.7.23", - "yargs": "^15.3.1" + "yargs": "^16.1.1" }, "devDependencies": { "@commitlint/cli": "^8.3.4", From 1b9e1de7d081e1c205debff27c6b5e1fe0585dee Mon Sep 17 00:00:00 2001 From: Marvin Heilemann Date: Tue, 15 Dec 2020 19:15:49 +0100 Subject: [PATCH 273/374] fix(deps): bump socket-io to v3 (#3586) * fix socket-io deprecated default export BREAKING CHANGE: Some projects have socket.io tests that are version sensitive. Fixes #3569 --- lib/server.js | 4 +- package-lock.json | 365 ++++++++++++---------------------------------- package.json | 2 +- 3 files changed, 95 insertions(+), 276 deletions(-) diff --git a/lib/server.js b/lib/server.js index fb07b77b9..d75c58a84 100644 --- a/lib/server.js +++ b/lib/server.js @@ -36,13 +36,13 @@ const EmitterWrapper = require('./emitter_wrapper') const processWrapper = new EmitterWrapper(process) function createSocketIoServer (webServer, executor, config) { - const server = new SocketIO(webServer, { + const server = new SocketIO.Server(webServer, { // avoid destroying http upgrades from socket.io to get proxied websockets working destroyUpgrade: false, path: config.urlRoot + 'socket.io/', transports: config.transports, forceJSONP: config.forceJSONP, - // Default is 5000 in socket.io v2.x. + // Default is 5000 in socket.io v2.x and v3.x. pingTimeout: config.pingTimeout || 5000 }) diff --git a/package-lock.json b/package-lock.json index ec82cd750..7e4e3dcda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2332,6 +2332,21 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/component-emitter": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", + "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" + }, + "@types/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==" + }, + "@types/cors": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz", + "integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg==" + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -2452,11 +2467,6 @@ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=" - }, "agent-base": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", @@ -2685,11 +2695,6 @@ "es-abstract": "^1.17.0-next.1" } }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" - }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -2795,7 +2800,8 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true }, "asynckit": { "version": "0.4.0", @@ -2852,11 +2858,6 @@ } } }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2918,9 +2919,9 @@ } }, "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=" + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" }, "base64-js": { "version": "1.3.0", @@ -2945,24 +2946,11 @@ "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==", "dev": true }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "requires": { - "callsite": "1.0.0" - } - }, "binary-extensions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, - "blob": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", - "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==" - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -3467,11 +3455,6 @@ "caller-callsite": "^2.0.0" } }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=" - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -3796,20 +3779,11 @@ "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", "dev": true }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" - }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true }, "concat-map": { "version": "0.0.1", @@ -4437,9 +4411,9 @@ } }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" }, "cookiejar": { "version": "2.1.2", @@ -4471,6 +4445,15 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", @@ -5057,15 +5040,16 @@ } }, "engine.io": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.4.1.tgz", - "integrity": "sha512-8MfIfF1/IIfxuc2gv5K+XlFZczw/BpTvqBdl0E2fBLkYQp4miv4LuDTVtYt4yMyaIFLEr4vtaSgV4mjvll8Crw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.5.tgz", + "integrity": "sha512-Ri+whTNr2PKklxQkfbGjwEo+kCBUM4Qxk4wtLqLrhH+b1up2NFL9g9pjYWiCV/oazwB0rArnvF/ZmZN2ab5Hpg==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "0.3.1", + "cookie": "~0.4.1", + "cors": "~2.8.5", "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", + "engine.io-parser": "~4.0.0", "ws": "^7.1.2" }, "dependencies": { @@ -5078,68 +5062,18 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "engine.io-client": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.4.2.tgz", - "integrity": "sha512-AWjc1Xg06a6UPFOBAzJf48W1UR/qKYmv/ubgSCumo9GXgvL/xGIvo05dXoBL+2NTLMipDI7in8xK61C17L25xg==", - "requires": { - "component-emitter": "~1.3.0", - "component-inherit": "0.0.3", - "debug": "~4.1.0", - "engine.io-parser": "~2.2.0", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~6.1.0", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "ws": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz", - "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==", - "requires": { - "async-limiter": "~1.0.0" - } + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "engine.io-parser": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.0.tgz", - "integrity": "sha512-6I3qD9iUxotsC5HEMuuGsKA0cXerGz+4uGcXQEkfBidgKf0amsjrrtwcbwK/nzpZBxclXlV7gGl9dgWvu4LF6w==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", + "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.5", - "has-binary2": "~1.0.2" + "base64-arraybuffer": "0.1.4" } }, "enquirer": { @@ -7299,26 +7233,6 @@ } } }, - "has-binary2": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", - "requires": { - "isarray": "2.0.1" - }, - "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - } - } - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=" - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7787,11 +7701,6 @@ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", "dev": true }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=" - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -13023,13 +12932,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-copy": { "version": "0.1.0", @@ -13379,22 +13282,6 @@ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", "dev": true }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "requires": { - "better-assert": "~1.0.0" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "requires": { - "better-assert": "~1.0.0" - } - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -14784,18 +14671,26 @@ } }, "socket.io": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", - "integrity": "sha512-2A892lrj0GcgR/9Qk81EaY2gYhCBxurV0PfmmESO6p27QPrUK1J3zdns+5QPqvUYK2q657nSj0guoIil9+7eFg==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.4.tgz", + "integrity": "sha512-Vj1jUoO75WGc9txWd311ZJJqS9Dr8QtNJJ7gk2r7dcM/yGe9sit7qOijQl3GAwhpBOz/W8CwkD7R6yob07nLbA==", "requires": { + "@types/cookie": "^0.4.0", + "@types/cors": "^2.8.8", + "@types/node": "^14.14.7", + "accepts": "~1.3.4", + "base64id": "~2.0.0", "debug": "~4.1.0", - "engine.io": "~3.4.0", - "has-binary2": "~1.0.2", - "socket.io-adapter": "~1.1.0", - "socket.io-client": "2.3.0", - "socket.io-parser": "~3.4.0" + "engine.io": "~4.0.0", + "socket.io-adapter": "~2.0.3", + "socket.io-parser": "~4.0.1" }, "dependencies": { + "@types/node": { + "version": "14.14.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.13.tgz", + "integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==" + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -14805,93 +14700,32 @@ } }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, "socket.io-adapter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", - "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==" - }, - "socket.io-client": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.3.0.tgz", - "integrity": "sha512-cEQQf24gET3rfhxZ2jJ5xzAOo/xhZwK+mOqtGRg5IowZsMgwvHwnf/mCRapAAkadhM26y+iydgwsXGObBB5ZdA==", - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "engine.io-client": "~3.4.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.3.0", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "socket.io-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz", - "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==", - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - } - } + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz", + "integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ==" }, "socket.io-parser": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.1.tgz", - "integrity": "sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.2.tgz", + "integrity": "sha512-Bs3IYHDivwf+bAAuW/8xwJgIiBNtlvnjYRc4PbXgniLmcP1BrakBoq/QhO24rgtgW7VZ7uAaswRGxutUnlAK7g==", "requires": { - "component-emitter": "1.2.1", - "debug": "~4.1.0", - "isarray": "2.0.1" + "@types/component-emitter": "^1.2.10", + "component-emitter": "~1.3.0", + "debug": "~4.1.0" }, "dependencies": { + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -14900,15 +14734,10 @@ "ms": "^2.1.1" } }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=" - }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, @@ -15586,11 +15415,6 @@ } } }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" - }, "to-object-path": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", @@ -15985,6 +15809,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -16336,9 +16165,9 @@ } }, "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", + "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" }, "xmlbuilder": { "version": "12.0.0", @@ -16346,11 +16175,6 @@ "integrity": "sha512-lMo8DJ8u6JRWp0/Y4XLa/atVDr75H9litKlb2E5j3V3MesoL50EBgZDWoLT3F/LztVnG67GjPXLZpqcky/UMnQ==", "dev": true }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=" - }, "xregexp": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.3.0.tgz", @@ -16466,11 +16290,6 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } } } diff --git a/package.json b/package.json index 13e36d87f..18a7663f5 100644 --- a/package.json +++ b/package.json @@ -422,7 +422,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^2.3.0", + "socket.io": "^3.0.4", "source-map": "^0.6.1", "tmp": "0.2.1", "ua-parser-js": "^0.7.23", From 7a3bd5545fa1307c754419252fa35ff0b7572ae4 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Thu, 17 Dec 2020 19:10:31 +0100 Subject: [PATCH 274/374] feat: remove support for running dart code in the browser (#3592) As Dartium browser is no more, there are no browsers left, which support running Dart applications natively and therefore we can remove such support from Karma to reduce the maintenance effort. BREAKING CHANGE: Using Karma to run Dart code in the browser is no longer supported. Use your favorite Dart-to-JS compiler instead. `dart` file type has been removed without a replacement. `customFileHandlers` DI token has been removed. Use [`middleware`](http://karma-runner.github.io/5.2/config/configuration-file.html#middleware) to achieve similar functionality. `customScriptTypes` DI token has been removed. It had no effect, so no replacement is provided. --- docs/config/02-files.md | 1 - docs/dev/05-plugins.md | 3 +-- lib/middleware/karma.js | 2 -- lib/server.js | 4 ---- lib/web-server.js | 14 -------------- test/unit/middleware/karma.spec.js | 4 ++-- test/unit/web-server.spec.js | 25 +------------------------ 7 files changed, 4 insertions(+), 49 deletions(-) diff --git a/docs/config/02-files.md b/docs/config/02-files.md index 4c7debcb0..f85c4d772 100644 --- a/docs/config/02-files.md +++ b/docs/config/02-files.md @@ -31,7 +31,6 @@ Each pattern is either a simple string or an object with the following propertie * `css` - Include using `` tag. * `html` - Include using [HTML Imports](https://developer.mozilla.org/en-US/docs/Web/Web_Components/HTML_Imports). Note that this feature is obsolete and does not work in the modern browsers. * `js` - Include using `` tag. - * `dart` - Include using `` tag. Note that this does not work in the modern browsers. * `module` - Include using `` tag. * `dom` - Inline content of the file in the page. This can be used, for example, to test components combining HTML and JS. * **Description.** The type determines the mechanism for including the file. diff --git a/docs/dev/05-plugins.md b/docs/dev/05-plugins.md index d785102fb..d9371e46a 100644 --- a/docs/dev/05-plugins.md +++ b/docs/dev/05-plugins.md @@ -34,7 +34,7 @@ A preprocessor is a function that accepts three arguments (`content`, `file`, an - user NPM keywords `karma-plugin`, `karma-preprocessor` ## Crazier stuff -Karma is assembled by Dependency Injection and a plugin is just an additional DI module (see [node-di] for more), that can be loaded by Karma. Therefore, it can ask for pretty much any Karma component and interact with it. There are a couple of plugins that do more interesting stuff like this, check out [karma-closure], [karma-intellij], [karma-dart]. +Karma is assembled by Dependency Injection and a plugin is just an additional DI module (see [node-di] for more), that can be loaded by Karma. Therefore, it can ask for pretty much any Karma component and interact with it. There are a couple of plugins that do more interesting stuff like this, check out [karma-closure], [karma-intellij]. [karma-jasmine]: https://github.com/karma-runner/karma-jasmine @@ -49,7 +49,6 @@ Karma is assembled by Dependency Injection and a plugin is just an additional DI [karma-ng-html2js-preprocessor]: https://github.com/karma-runner/karma-ng-html2js-preprocessor [karma-closure]: https://github.com/karma-runner/karma-closure [karma-intellij]: https://github.com/karma-runner/karma-intellij -[karma-dart]: https://github.com/karma-runner/karma-dart [node-di]: https://github.com/vojtajina/node-di [karma-material-reporter]: https://github.com/ameerthehacker/karma-material-reporter diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index c48332d12..4e27d4a52 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -20,14 +20,12 @@ const common = require('./common') const VERSION = require('../constants').VERSION const SCRIPT_TYPE = { js: 'text/javascript', - dart: 'application/dart', module: 'module' } const FILE_TYPES = [ 'css', 'html', 'js', - 'dart', 'module', 'dom' ] diff --git a/lib/server.js b/lib/server.js index d75c58a84..238caa09c 100644 --- a/lib/server.js +++ b/lib/server.js @@ -82,10 +82,6 @@ class Server extends KarmaEventEmitter { filesPromise: ['factory', createFilesPromise], socketServer: ['factory', createSocketIoServer], executor: ['factory', Executor.factory], - // TODO(vojta): remove - customFileHandlers: ['value', []], - // TODO(vojta): remove, once karma-dart does not rely on it - customScriptTypes: ['value', []], reporter: ['factory', reporter.createReporters], capturedBrowsers: ['factory', BrowserCollection.factory], args: ['value', {}], diff --git a/lib/web-server.js b/lib/web-server.js index a348f9421..379818435 100644 --- a/lib/web-server.js +++ b/lib/web-server.js @@ -16,17 +16,6 @@ const proxyMiddleware = require('./middleware/proxy') const log = require('./logger').create('web-server') -function createCustomHandler (customFileHandlers, config) { - return function (request, response, next) { - const handler = customFileHandlers.find((handler) => handler.urlRegex.test(request.url)) - return handler - ? handler.handler(request, response, 'fake/static', 'fake/adapter', config.basePath, 'fake/root') - : next() - } -} - -createCustomHandler.$inject = ['customFileHandlers', 'config'] - function createFilesPromise (emitter, fileList) { // Set an empty list of files to avoid race issues with // file_list_modified not having been emitted yet @@ -69,9 +58,6 @@ function createWebServer (injector, config) { handler.use(injector.invoke(sourceFilesMiddleware.create)) // TODO(vojta): extract the proxy into a plugin handler.use(proxyMiddlewareInstance) - // TODO(vojta): remove, this is only here because of karma-dart - // we need a better way of custom handlers - handler.use(injector.invoke(createCustomHandler)) if (config.middleware) { config.middleware.forEach((middleware) => handler.use(injector.get('middleware:' + middleware))) diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js index 16242d09d..8a968262c 100644 --- a/test/unit/middleware/karma.spec.js +++ b/test/unit/middleware/karma.spec.js @@ -202,12 +202,12 @@ describe('middleware.karma', () => { it('should serve context.html with replaced script tags', (done) => { includedFiles([ new MockFile('/first.js', 'sha123'), - new MockFile('/second.dart', 'sha456') + new MockFile('/second.js', 'sha456') ]) response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'CONTEXT\n\n') + expect(response).to.beServedAs(200, 'CONTEXT\n\n') done() }) diff --git a/test/unit/web-server.spec.js b/test/unit/web-server.spec.js index 5d9f4f18e..8517f172e 100644 --- a/test/unit/web-server.spec.js +++ b/test/unit/web-server.spec.js @@ -31,7 +31,7 @@ describe('web-server', () => { // NOTE(vojta): only loading once, to speed things up // this relies on the fact that none of these tests mutate fs const m = mocks.loadFile(path.join(__dirname, '/../../lib/web-server.js'), _mocks, _globals) - let customFileHandlers = server = emitter = null + server = emitter = null let beforeMiddlewareActive = false let middlewareActive = false const servedFiles = (files) => { @@ -40,7 +40,6 @@ describe('web-server', () => { describe('request', () => { beforeEach(() => { - customFileHandlers = [] emitter = new EventEmitter() const config = { basePath: '/base/path', @@ -57,7 +56,6 @@ describe('web-server', () => { const injector = new di.Injector([{ config: ['value', config], - customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], @@ -182,23 +180,6 @@ describe('web-server', () => { }) }) - it('should load custom handlers', () => { - servedFiles(new Set()) - - // TODO(vojta): change this, only keeping because karma-dart is relying on it - customFileHandlers.push({ - urlRegex: /\/some\/weird/, - handler (request, response, staticFolder, adapterFolder, baseFolder, urlRoot) { - response.writeHead(222) - response.end('CONTENT') - } - }) - - return request(server) - .get('/some/weird/url') - .expect(222, 'CONTENT') - }) - it('should serve 404 for non-existing files', () => { servedFiles(new Set()) @@ -215,7 +196,6 @@ describe('web-server', () => { cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } - customFileHandlers = [] emitter = new EventEmitter() const injector = new di.Injector([{ @@ -226,7 +206,6 @@ describe('web-server', () => { httpsServerOptions: credentials, client: { useIframe: true, useSingleWindow: false } }], - customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], @@ -265,12 +244,10 @@ describe('web-server', () => { cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } - customFileHandlers = [] emitter = new EventEmitter() const injector = new di.Injector([{ config: ['value', { basePath: '/base/path', urlRoot: '/', httpModule: http2, protocol: 'https:', httpsServerOptions: credentials }], - customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], From 603bbc0db2ef4e6b8474f97a8255587f2a5f924e Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Thu, 17 Dec 2020 19:14:11 +0100 Subject: [PATCH 275/374] feat(cli): error out on unexpected options or parameters (#3589) This should make CLI more helpful as it will error out early and users can see that they have passed a wrong option instead of guessing why it does not have any effect. Notes: - units tests use same parser configuration as production code (hence changes to tests) - logic and test case for _ typos in option names was removed as this is covered by yargs strict mode now - added documentation for couple of existing options as otherwise they are considered unknown and error out (but they do exist and were found in the unit tests) BREAKING CHANGE: Karma is more strict and will error out if unknown option or argument is passed to CLI. --- lib/cli.js | 52 ++++++++++++++++++------- test/e2e/cli.feature | 90 +++++++++++++++++++++++++++++++++++++------ test/unit/cli.spec.js | 59 +++++++++++----------------- 3 files changed, 140 insertions(+), 61 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 448f56eb6..0aac17e9a 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -1,7 +1,6 @@ 'use strict' const path = require('path') -const assert = require('assert') const yargs = require('yargs') const fs = require('graceful-fs') @@ -10,12 +9,9 @@ const helper = require('./helper') const constant = require('./constants') function processArgs (argv, options, fs, path) { - // TODO(vojta): warn/throw when unknown argument (probably mispelled) Object.getOwnPropertyNames(argv).forEach(function (name) { let argumentValue = argv[name] if (name !== '_' && name !== '$0') { - assert(!name.includes('_'), `Bad argument: ${name} did you mean ${name.replace('_', '-')}`) - if (Array.isArray(argumentValue)) { argumentValue = argumentValue.pop() // If the same argument is defined multiple times, override. } @@ -99,7 +95,7 @@ function processArgs (argv, options, fs, path) { options.refresh = options.refresh === 'true' } - let configFile = argv._.shift() + let configFile = argv.configFile if (!configFile) { // default config file (if exists) @@ -151,13 +147,13 @@ function describeRoot () { 'Run --help with particular command to see its description and available options.\n\n' + 'Usage:\n' + ' $0 ') - .command('init', 'Initialize a config file.', describeInit) - .command('start', 'Start the server / do a single run.', describeStart) - .command('run', 'Trigger a test run.', describeRun) - .command('stop', 'Stop the server.', describeStop) + .command('init [configFile]', 'Initialize a config file.', describeInit) + .command('start [configFile]', 'Start the server / do a single run.', describeStart) + .command('run [configFile]', 'Trigger a test run.', describeRun) + .command('stop [configFile]', 'Stop the server.', describeStop) .command('completion', 'Shell completion for karma.', describeCompletion) .demandCommand(1, 'Command not specified.') - .strictCommands() + .strict() .describe('help', 'Print usage and options.') .describe('version', 'Print current version.') } @@ -168,8 +164,11 @@ function describeInit (yargs) { 'INIT - Initialize a config file.\n\n' + 'Usage:\n' + ' $0 init [configFile]') - .strictCommands(false) .version(false) + .positional('configFile', { + describe: 'Name of the generated Karma configuration file', + type: 'string' + }) .describe('log-level', ' Level of logging.') .describe('colors', 'Use colors when reporting and printing logs.') .describe('no-colors', 'Do not use colors when reporting or printing logs.') @@ -183,6 +182,10 @@ function describeStart (yargs) { ' $0 start [configFile]') .strictCommands(false) .version(false) + .positional('configFile', { + describe: 'Path to the Karma configuration file', + type: 'string' + }) .describe('port', ' Port where the server is running.') .describe('auto-watch', 'Auto watch source files and run on change.') .describe('detached', 'Detach the server.') @@ -200,6 +203,10 @@ function describeStart (yargs) { .describe('no-fail-on-empty-test-suite', 'Do not fail on empty test suite.') .describe('fail-on-failing-test-suite', 'Fail on failing test suite.') .describe('no-fail-on-failing-test-suite', 'Do not fail on failing test suite.') + .option('format-error', { + describe: 'A path to a file that exports the format function.', + type: 'string' + }) } function describeRun (yargs) { @@ -208,8 +215,11 @@ function describeRun (yargs) { 'RUN - Run the tests (requires running server).\n\n' + 'Usage:\n' + ' $0 run [configFile] [-- ]') - .strictCommands(false) .version(false) + .positional('configFile', { + describe: 'Path to the Karma configuration file', + type: 'string' + }) .describe('port', ' Port where the server is listening.') .describe('no-refresh', 'Do not re-glob all the patterns.') .describe('fail-on-empty-test-suite', 'Fail on empty test suite.') @@ -217,6 +227,18 @@ function describeRun (yargs) { .describe('log-level', ' Level of logging.') .describe('colors', 'Use colors when reporting and printing logs.') .describe('no-colors', 'Do not use colors when reporting or printing logs.') + .option('removed-files', { + describe: 'Comma-separated paths to removed files. Useful when automatic file watching is disabled.', + type: 'string' + }) + .option('changed-files', { + describe: 'Comma-separated paths to changed files. Useful when automatic file watching is disabled.', + type: 'string' + }) + .option('added-files', { + describe: 'Comma-separated paths to added files. Useful when automatic file watching is disabled.', + type: 'string' + }) } function describeStop (yargs) { @@ -225,8 +247,11 @@ function describeStop (yargs) { 'STOP - Stop the server (requires running server).\n\n' + 'Usage:\n' + ' $0 stop [configFile]') - .strictCommands(false) .version(false) + .positional('configFile', { + describe: 'Path to the Karma configuration file', + type: 'string' + }) .describe('port', ' Port where the server is listening.') .describe('log-level', ' Level of logging.') } @@ -237,7 +262,6 @@ function describeCompletion (yargs) { 'COMPLETION - Bash/ZSH completion for karma.\n\n' + 'Installation:\n' + ' $0 completion >> ~/.bashrc') - .strictCommands(false) .version(false) } diff --git a/test/e2e/cli.feature b/test/e2e/cli.feature index 2913f23f2..476d29a8e 100644 --- a/test/e2e/cli.feature +++ b/test/e2e/cli.feature @@ -15,11 +15,11 @@ Feature: CLI karma Commands: - karma init Initialize a config file. - karma start Start the server / do a single run. - karma run Trigger a test run. - karma stop Stop the server. - karma completion Shell completion for karma. + karma init [configFile] Initialize a config file. + karma start [configFile] Start the server / do a single run. + karma run [configFile] Trigger a test run. + karma stop [configFile] Stop the server. + karma completion Shell completion for karma. Options: --help Print usage and options. [boolean] @@ -45,17 +45,62 @@ Feature: CLI karma Commands: - karma init Initialize a config file. - karma start Start the server / do a single run. - karma run Trigger a test run. - karma stop Stop the server. - karma completion Shell completion for karma. + karma init [configFile] Initialize a config file. + karma start [configFile] Start the server / do a single run. + karma run [configFile] Trigger a test run. + karma stop [configFile] Stop the server. + karma completion Shell completion for karma. Options: --help Print usage and options. [boolean] --version Print current version. [boolean] - Unknown command: strat + Unknown argument: strat + """ + + Scenario: Error when option is unknown + When I execute Karma with arguments: "start --invalid-option" + Then the stderr is exactly: + """ + Karma - Spectacular Test Runner for JavaScript. + + START - Start the server / do a single run. + + Usage: + karma start [configFile] + + Positionals: + configFile Path to the Karma configuration file [string] + + Options: + --help Print usage and options. [boolean] + --port Port where the server is running. + --auto-watch Auto watch source files and run on change. + --detached Detach the server. + --no-auto-watch Do not watch source files. + --log-level Level + of logging. + --colors Use colors when reporting and printing logs. + --no-colors Do not use colors when reporting or printing + logs. + --reporters List of reporters (available: dots, progress, + junit, growl, coverage). + --browsers List of browsers to start (eg. --browsers + Chrome,ChromeCanary,Firefox). + --capture-timeout Kill browser if does not capture in + given time [ms]. + --single-run Run the test when browsers captured and exit. + --no-single-run Disable single-run. + --report-slower-than Report tests that are slower than + given time [ms]. + --fail-on-empty-test-suite Fail on empty test suite. + --no-fail-on-empty-test-suite Do not fail on empty test suite. + --fail-on-failing-test-suite Fail on failing test suite. + --no-fail-on-failing-test-suite Do not fail on failing test suite. + --format-error A path to a file that exports the format + function. [string] + + Unknown arguments: invalid-option, invalidOption """ Scenario: Init command help @@ -69,6 +114,9 @@ Feature: CLI Usage: karma init [configFile] + Positionals: + configFile Name of the generated Karma configuration file [string] + Options: --help Print usage and options. [boolean] --log-level Level of logging. @@ -87,6 +135,9 @@ Feature: CLI Usage: karma start [configFile] + Positionals: + configFile Path to the Karma configuration file [string] + Options: --help Print usage and options. [boolean] --port Port where the server is running. @@ -112,6 +163,8 @@ Feature: CLI --no-fail-on-empty-test-suite Do not fail on empty test suite. --fail-on-failing-test-suite Fail on failing test suite. --no-fail-on-failing-test-suite Do not fail on failing test suite. + --format-error A path to a file that exports the format + function. [string] """ Scenario: Run command help @@ -125,6 +178,9 @@ Feature: CLI Usage: karma run [configFile] [-- ] + Positionals: + configFile Path to the Karma configuration file [string] + Options: --help Print usage and options. [boolean] --port Port where the server is listening. @@ -136,6 +192,15 @@ Feature: CLI --colors Use colors when reporting and printing logs. --no-colors Do not use colors when reporting or printing logs. + --removed-files Comma-separated paths to removed files. Useful + when automatic file watching is disabled. + [string] + --changed-files Comma-separated paths to changed files. Useful + when automatic file watching is disabled. + [string] + --added-files Comma-separated paths to added files. Useful + when automatic file watching is disabled. + [string] """ Scenario: Stop command help @@ -149,6 +214,9 @@ Feature: CLI Usage: karma stop [configFile] + Positionals: + configFile Path to the Karma configuration file [string] + Options: --help Print usage and options. [boolean] --port Port where the server is listening. diff --git a/test/unit/cli.spec.js b/test/unit/cli.spec.js index 8d9223256..222e92c04 100644 --- a/test/unit/cli.spec.js +++ b/test/unit/cli.spec.js @@ -1,6 +1,5 @@ 'use strict' -const yargs = require('yargs') const path = require('path') const mocks = require('mocks') @@ -34,7 +33,7 @@ describe('cli', () => { } const processArgs = (args, opts) => { - const argv = yargs.parse(args) + const argv = m.describeRoot().parse(args) return e.processArgs(argv, opts || {}, fsMock, pathMock) } @@ -63,14 +62,14 @@ describe('cli', () => { describe('processArgs', () => { it('should override if multiple options given', () => { // yargs parses --port 123 --port 456 as port = [123, 456] which makes no sense - const options = processArgs(['some.conf', '--port', '12', '--log-level', 'info', '--port', '34', '--log-level', 'debug']) + const options = processArgs(['start', 'some.conf', '--port', '12', '--log-level', 'info', '--port', '34', '--log-level', 'debug']) expect(options.port).to.equal(34) expect(options.logLevel).to.equal('DEBUG') }) it('should return camelCased options', () => { - const options = processArgs(['some.conf', '--port', '12', '--single-run']) + const options = processArgs(['start', 'some.conf', '--port', '12', '--single-run']) expect(options.configFile).to.exist expect(options.port).to.equal(12) @@ -79,41 +78,40 @@ describe('cli', () => { it('should parse options without configFile and set default', () => { setCWD('/cwd') - const options = processArgs(['--auto-watch', '--auto-watch-interval', '10']) + const options = processArgs(['start', '--auto-watch']) expect(path.resolve(options.configFile)).to.equal(path.resolve('/cwd/karma.conf.js')) expect(options.autoWatch).to.equal(true) - expect(options.autoWatchInterval).to.equal(10) }) it('should set default karma.conf.coffee config file if exists', () => { setCWD('/cwd2') - const options = processArgs(['--port', '10']) + const options = processArgs(['start', '--port', '10']) expect(path.resolve(options.configFile)).to.equal(path.resolve('/cwd2/karma.conf.coffee')) }) it('should set default karma.conf.ts config file if exists', () => { setCWD('/cwd3') - const options = processArgs(['--port', '10']) + const options = processArgs(['start', '--port', '10']) expect(path.resolve(options.configFile)).to.equal(path.resolve('/cwd3/karma.conf.ts')) }) it('should not set default config if neither exists', () => { setCWD('/') - const options = processArgs([]) + const options = processArgs(['start']) expect(options.configFile).to.equal(null) }) it('should parse auto-watch, colors, singleRun to boolean', () => { - let options = processArgs(['--auto-watch', 'false', '--colors', 'false', '--single-run', 'false']) + let options = processArgs(['start', '--auto-watch', 'false', '--colors', 'false', '--single-run', 'false']) expect(options.autoWatch).to.equal(false) expect(options.colors).to.equal(false) expect(options.singleRun).to.equal(false) - options = processArgs(['--auto-watch', 'true', '--colors', 'true', '--single-run', 'true']) + options = processArgs(['start', '--auto-watch', 'true', '--colors', 'true', '--single-run', 'true']) expect(options.autoWatch).to.equal(true) expect(options.colors).to.equal(true) @@ -121,63 +119,64 @@ describe('cli', () => { }) it('should replace log-level constants', () => { - let options = processArgs(['--log-level', 'debug']) + let options = processArgs(['start', '--log-level', 'debug']) expect(options.logLevel).to.equal(constant.LOG_DEBUG) - options = processArgs(['--log-level', 'error']) + options = processArgs(['start', '--log-level', 'error']) expect(options.logLevel).to.equal(constant.LOG_ERROR) - options = processArgs(['--log-level', 'warn']) + options = processArgs(['start', '--log-level', 'warn']) expect(options.logLevel).to.equal(constant.LOG_WARN) - options = processArgs(['--log-level', 'foo']) + options = processArgs(['start', '--log-level', 'foo']) expect(mockery.process.exit).to.have.been.calledWith(1) - options = processArgs(['--log-level']) + options = processArgs(['start', '--log-level']) expect(mockery.process.exit).to.have.been.calledWith(1) }) it('should parse format-error into a function', () => { // root export - let options = processArgs(['--format-error', '../../test/unit/fixtures/format-error-root']) + let options = processArgs(['start', '--format-error', '../../test/unit/fixtures/format-error-root']) const formatErrorRoot = require('../../test/unit/fixtures/format-error-root') expect(options.formatError).to.equal(formatErrorRoot) // property export - options = processArgs(['--format-error', '../../test/unit/fixtures/format-error-property']) + options = processArgs(['start', '--format-error', '../../test/unit/fixtures/format-error-property']) const formatErrorProperty = require('../../test/unit/fixtures/format-error-property').formatError expect(options.formatError).to.equal(formatErrorProperty) }) it('should parse browsers into an array', () => { - const options = processArgs(['--browsers', 'Chrome,ChromeCanary,Firefox']) + const options = processArgs(['start', '--browsers', 'Chrome,ChromeCanary,Firefox']) expect(options.browsers).to.deep.equal(['Chrome', 'ChromeCanary', 'Firefox']) }) it('should resolve configFile to absolute path', () => { setCWD('/cwd') - const options = processArgs(['some/config.js']) + const options = processArgs(['start', 'some/config.js']) expect(path.resolve(options.configFile)).to.equal(path.resolve('/cwd/some/config.js')) }) it('should parse report-slower-than to a number', () => { - let options = processArgs(['--report-slower-than', '2000']) + let options = processArgs(['start', '--report-slower-than', '2000']) expect(options.reportSlowerThan).to.equal(2000) - options = processArgs(['--no-report-slower-than']) + options = processArgs(['start', '--no-report-slower-than']) expect(options.reportSlowerThan).to.equal(0) }) it('should cast reporters to array', () => { - let options = processArgs(['--reporters', 'dots,junit']) + let options = processArgs(['start', '--reporters', 'dots,junit']) expect(options.reporters).to.deep.equal(['dots', 'junit']) - options = processArgs(['--reporters', 'dots']) + options = processArgs(['start', '--reporters', 'dots']) expect(options.reporters).to.deep.equal(['dots']) }) it('should parse removed/added/changed files to array', () => { const options = processArgs([ + 'run', '--removed-files', 'r1.js,r2.js', '--changed-files', 'ch1.js,ch2.js', '--added-files', 'a1.js,a2.js' @@ -187,18 +186,6 @@ describe('cli', () => { expect(options.addedFiles).to.deep.equal(['a1.js', 'a2.js']) expect(options.changedFiles).to.deep.equal(['ch1.js', 'ch2.js']) }) - - it('should error on args with underscores', () => { - let expectedException - try { - const options = processArgs(['--no_browsers']) - expectedException = 'Should have thrown but got ' + options - } catch (e) { - expectedException = e - } finally { - expect(expectedException + '').to.includes('Bad argument: no_browsers did you mean no-browsers') - } - }) }) describe('parseClientArgs', () => { From 4a8178f3a0504ef007b23ef0fd8f5ca128f0c5c6 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 17 Dec 2020 14:08:55 -0800 Subject: [PATCH 276/374] fix(client): do not reset karmaNavigating in unload handler (#3591) The unload handler itself does not know about navigation. May fix #3482 --- client/karma.js | 1 - static/karma.js | 1 - 2 files changed, 2 deletions(-) diff --git a/client/karma.js b/client/karma.js index ec0db417e..6790a77ac 100644 --- a/client/karma.js +++ b/client/karma.js @@ -135,7 +135,6 @@ function Karma (socket, iframe, opener, navigator, location, document) { // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) self.error('Some of your tests did a full page reload!') } - karmaNavigating = false } function clearContext () { diff --git a/static/karma.js b/static/karma.js index bc3a2bbb6..0c289e0ca 100644 --- a/static/karma.js +++ b/static/karma.js @@ -145,7 +145,6 @@ function Karma (socket, iframe, opener, navigator, location, document) { // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) self.error('Some of your tests did a full page reload!') } - karmaNavigating = false } function clearContext () { From 35a584234b00297dc511300bb6e42eeaceac8345 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Thu, 17 Dec 2020 16:32:02 -0800 Subject: [PATCH 277/374] feat(server): print stack of unhandledrejections (#3593) * feat(server): print stack of unhandledrejections The v8 engine includes the error with the stack and most of the time we need the stack also. Co-authored-by: Jonathan Ginsburg --- lib/server.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/server.js b/lib/server.js index 238caa09c..7c1d9224e 100644 --- a/lib/server.js +++ b/lib/server.js @@ -417,12 +417,12 @@ class Server extends KarmaEventEmitter { } processWrapper.on('unhandledRejection', (error) => { - this.log.error(`UnhandledRejection: ${error.message || String(error)}`) + this.log.error(`UnhandledRejection: ${error.stack || error.message || String(error)}`) reportError(error) }) processWrapper.on('uncaughtException', (error) => { - this.log.error(`UncaughtException:: ${error.message || String(error)}`) + this.log.error(`UncaughtException: ${error.stack || error.message || String(error)}`) reportError(error) }) } From fb76ed669b3bccadc2a67fecfcf48c3f00771dec Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Mon, 21 Dec 2020 18:47:45 +0200 Subject: [PATCH 278/374] chore(test): remove usage of deprecated buffer API (#3596) --- test/unit/preprocessor.spec.js | 2 +- test/unit/runner.spec.js | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/test/unit/preprocessor.spec.js b/test/unit/preprocessor.spec.js index 1f59eb87f..2b5fefbc2 100644 --- a/test/unit/preprocessor.spec.js +++ b/test/unit/preprocessor.spec.js @@ -11,7 +11,7 @@ describe('preprocessor', () => { let mockFs let emitterSetting // mimic first few bytes of a pdf file - const binarydata = new Buffer([0x25, 0x50, 0x44, 0x66, 0x46, 0x00]) // eslint-disable-line node/no-deprecated-api + const binarydata = Buffer.from([0x25, 0x50, 0x44, 0x66, 0x46, 0x00]) beforeEach(() => { mockFs = mocks.fs.create({ diff --git a/test/unit/runner.spec.js b/test/unit/runner.spec.js index 97cefc49a..82f0eb15b 100644 --- a/test/unit/runner.spec.js +++ b/test/unit/runner.spec.js @@ -14,12 +14,12 @@ describe('runner', () => { const EXIT = constant.EXIT_CODE it('should return 0 exit code if present in the buffer', () => { - const result = m.parseExitCode(new Buffer(`something\nfake${EXIT}10`)) // eslint-disable-line node/no-deprecated-api + const result = m.parseExitCode(Buffer.from(`something\nfake${EXIT}10`)) expect(result.exitCode).to.equal(0) }) it('should remove the exit code part of the returned buffer', () => { - const buffer = new Buffer(`some${EXIT}01`) // eslint-disable-line node/no-deprecated-api + const buffer = Buffer.from(`some${EXIT}01`) const result = m.parseExitCode(buffer) expect(buffer.toString()).to.equal(`some${EXIT}01`) @@ -28,7 +28,7 @@ describe('runner', () => { it('should not touch buffer without exit code and return default', () => { const msg = 'some nice \n messgae {}' - const buffer = new Buffer(msg) // eslint-disable-line node/no-deprecated-api + const buffer = Buffer.from(msg) const result = m.parseExitCode(buffer, 10) expect(result.buffer.toString()).to.equal(msg) @@ -53,21 +53,21 @@ describe('runner', () => { }) it('should parse any single digit exit code', () => { - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}01`)).exitCode).to.equal(1) // eslint-disable-line node/no-deprecated-api - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}17`)).exitCode).to.equal(7) // eslint-disable-line node/no-deprecated-api + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}01`)).exitCode).to.equal(1) + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}17`)).exitCode).to.equal(7) }) it('should return exit code 0 if failOnEmptyTestSuite is false and and non-empty int is 0', () => { - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}01`), undefined, false).exitCode).to.equal(0) // eslint-disable-line node/no-deprecated-api + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}01`), undefined, false).exitCode).to.equal(0) }) it('should return exit code if failOnEmptyTestSuite is true', () => { - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}00`), undefined, true).exitCode).to.equal(0) // eslint-disable-line node/no-deprecated-api - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}01`), undefined, true).exitCode).to.equal(1) // eslint-disable-line node/no-deprecated-api - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}07`), undefined, true).exitCode).to.equal(7) // eslint-disable-line node/no-deprecated-api - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}10`), undefined, true).exitCode).to.equal(0) // eslint-disable-line node/no-deprecated-api - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}11`), undefined, true).exitCode).to.equal(1) // eslint-disable-line node/no-deprecated-api - expect(m.parseExitCode(new Buffer(`something\nfake${EXIT}17`), undefined, true).exitCode).to.equal(7) // eslint-disable-line node/no-deprecated-api + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}00`), undefined, true).exitCode).to.equal(0) + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}01`), undefined, true).exitCode).to.equal(1) + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}07`), undefined, true).exitCode).to.equal(7) + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}10`), undefined, true).exitCode).to.equal(0) + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}11`), undefined, true).exitCode).to.equal(1) + expect(m.parseExitCode(Buffer.from(`something\nfake${EXIT}17`), undefined, true).exitCode).to.equal(7) }) }) }) From 1a65bf1181bc9eb5c28ba0130ab7d90e89b21918 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Mon, 21 Dec 2020 18:49:04 +0200 Subject: [PATCH 279/374] feat(server): remove deprecated static methods (#3595) BREAKING CHANGE: Deprecated `require('karma').server.start()` and `require('karma').Server.start()` variants were removed from the public API. Instead use canonical form: ``` const { Server } = require('karma'); const server = new Server(); server.start(); ``` --- lib/index.js | 15 +-------------- lib/server.js | 5 ----- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/lib/index.js b/lib/index.js index 4d906a437..d07e96ef6 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,18 +7,6 @@ const stopper = require('./stopper') const launcher = require('./launcher') const cfg = require('./config') -// TODO: remove in 1.0 -const oldServer = { - start: function (cliOptions, done) { - console.error('WARN `start` method is deprecated since 0.13. It will be removed in 0.14. Please use \n' + - ' server = new Server(config, [done])\n' + - ' server.start()\n' + - 'instead.') - const server = new Server(cliOptions, done) - server.start() - } -} - module.exports = { constants: constants, VERSION: constants.VERSION, @@ -26,6 +14,5 @@ module.exports = { runner: runner, stopper: stopper, launcher: launcher, - config: { parseConfig: cfg.parseConfig }, // lets start with only opening up the `parseConfig` api - server: oldServer + config: { parseConfig: cfg.parseConfig } // lets start with only opening up the `parseConfig` api } diff --git a/lib/server.js b/lib/server.js index 7c1d9224e..4a3eecfca 100644 --- a/lib/server.js +++ b/lib/server.js @@ -450,11 +450,6 @@ class Server extends KarmaEventEmitter { stop () { return this.emitAsync('stop') } - - static start (cliOptions, done) { - console.warn('Deprecated static method to be removed in v3.0') - return new Server(cliOptions, done).start() - } } Server.prototype._start.$inject = ['config', 'launcher', 'preprocess', 'fileList', 'capturedBrowsers', 'executor', 'done'] From fe0e24a8275c6e5a86b6a91d449ed43a86cc8ac7 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 23 Dec 2020 18:45:16 +0200 Subject: [PATCH 280/374] chore(build): unify client bundling scripts (#3600) Remove bundling logic from Grunt and introduce watch mode into the scripts/client.js. New script (`npm run build:watch`) allows to watch for the changes in client sources and bundle them automatically. This also fixes a bug where `npm run build` could swallow errors and silently do nothing. Fixes #3599 --- docs/dev/02-making-changes.md | 2 + gruntfile.js | 19 +- package-lock.json | 418 +++------------------------------- package.json | 3 +- scripts/client.js | 32 ++- 5 files changed, 65 insertions(+), 409 deletions(-) diff --git a/docs/dev/02-making-changes.md b/docs/dev/02-making-changes.md index 489e978e2..02fa76c06 100644 --- a/docs/dev/02-making-changes.md +++ b/docs/dev/02-making-changes.md @@ -49,6 +49,8 @@ Here are some tips on how to set up a Karma workspace and how to send a good pul - Build the client code via: ```bash $ npm run build + # or use the watch mode + $ npm run build:watch ``` ## Changing the Code diff --git a/gruntfile.js b/gruntfile.js index 7cf595762..7a3b95a12 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -9,24 +9,10 @@ module.exports = function (grunt) { context: ['context/**/*.js'], grunt: ['grunt.js', 'tasks/*.js'] }, - browserify: { - client: { - files: { - 'static/karma.js': ['client/main.js'], - 'static/context.js': ['context/main.js'] - } - } - }, test: { unit: 'mochaTest:unit', client: 'test/client/karma.conf.js' }, - watch: { - client: { - files: '<%= files.client %>', - tasks: 'browserify:client' - } - }, mochaTest: { options: { reporter: 'dot', @@ -43,7 +29,6 @@ module.exports = function (grunt) { }, 'npm-publish': { options: { - requires: ['build'], abortIfDirty: true, tag: 'latest' } @@ -93,8 +78,7 @@ module.exports = function (grunt) { grunt.loadTasks('tasks') require('load-grunt-tasks')(grunt) - grunt.registerTask('build', ['browserify:client']) - grunt.registerTask('default', ['build', 'test']) + grunt.registerTask('default', ['test']) grunt.registerTask('test-appveyor', ['test:unit', 'test:client']) grunt.registerTask('release', 'Build, bump and publish to NPM.', function (type) { @@ -102,7 +86,6 @@ module.exports = function (grunt) { 'check_clean', 'npm-contributors', 'bump:' + (type || 'patch') + ':bump-only', - 'build', 'conventionalChangelog', 'bump-commit', 'conventionalGithubReleaser', diff --git a/package-lock.json b/package-lock.json index 7e4e3dcda..c8da5ef94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2566,24 +2566,6 @@ } } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -2951,6 +2933,16 @@ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -3201,25 +3193,6 @@ "safe-buffer": "^5.0.1" } }, - "browserify-cache-api": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/browserify-cache-api/-/browserify-cache-api-3.0.1.tgz", - "integrity": "sha1-liR+hT8Gj9bg1FzHPwuyzZd47wI=", - "dev": true, - "requires": { - "async": "^1.5.2", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } - } - }, "browserify-cipher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", @@ -3243,36 +3216,6 @@ "safe-buffer": "^5.1.2" } }, - "browserify-incremental": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/browserify-incremental/-/browserify-incremental-3.1.1.tgz", - "integrity": "sha1-BxPLdYckemMqnwjPG9FpuHi2Koo=", - "dev": true, - "requires": { - "JSONStream": "^0.10.0", - "browserify-cache-api": "^3.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "dependencies": { - "JSONStream": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.10.0.tgz", - "integrity": "sha1-dDSdDYlSK3HzDwoD/5vSDKbxKsA=", - "dev": true, - "requires": { - "jsonparse": "0.0.5", - "through": ">=2.2.7 <3" - } - }, - "jsonparse": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz", - "integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ=", - "dev": true - } - } - }, "browserify-rsa": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", @@ -3559,13 +3502,6 @@ } } }, - "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", - "dev": true, - "optional": true - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -3684,13 +3620,6 @@ } } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true, - "optional": true - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -3822,13 +3751,6 @@ "date-now": "^0.1.4" } }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true, - "optional": true - }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -4836,13 +4758,6 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true, - "optional": true - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -4882,13 +4797,6 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, "detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", @@ -6029,6 +5937,13 @@ "flat-cache": "^2.0.1" } }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "fill-keys": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", @@ -6257,16 +6172,6 @@ "universalify": "^0.1.0" } }, - "fs-minipass": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", - "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -6290,64 +6195,6 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, "gaze": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", @@ -6924,21 +6771,6 @@ "integrity": "sha1-ShvjJUsQoXs0HkAvUbhRkehs9NE=", "dev": true }, - "grunt-browserify": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/grunt-browserify/-/grunt-browserify-5.3.0.tgz", - "integrity": "sha1-R/2M+LrFj+LeaDr9xX9/OoDKeS0=", - "dev": true, - "requires": { - "async": "^2.5.0", - "browserify": "^16.0.0", - "browserify-incremental": "^3.1.1", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "resolve": "^1.1.6", - "watchify": "^3.6.1" - } - }, "grunt-bump": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/grunt-bump/-/grunt-bump-0.8.0.tgz", @@ -7245,13 +7077,6 @@ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true, - "optional": true - }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -7652,16 +7477,6 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, "import-fresh": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", @@ -8959,27 +8774,6 @@ "is-plain-obj": "^1.1.0" } }, - "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -9148,9 +8942,9 @@ } }, "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", "dev": true, "optional": true }, @@ -9179,37 +8973,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "needle": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "optional": true - } - } - }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -9276,48 +9039,6 @@ "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", "dev": true }, - "node-pre-gyp": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - }, - "dependencies": { - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -12869,24 +12590,6 @@ } } }, - "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz", - "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -12904,19 +12607,6 @@ } } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "null-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", @@ -14050,13 +13740,6 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true, - "optional": true - }, "seed-random": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/seed-random/-/seed-random-2.2.0.tgz", @@ -15218,35 +14901,6 @@ } } }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, "temp-dir": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", @@ -15686,9 +15340,9 @@ } }, "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", "dev": true }, "upper-case": { @@ -15876,9 +15530,9 @@ } }, "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, "requires": { "anymatch": "^2.0.0", @@ -15917,14 +15571,14 @@ } }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", "dev": true, "optional": true, "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "bindings": "^1.5.0", + "nan": "^2.12.1" } }, "glob-parent": { @@ -16018,16 +15672,6 @@ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", "dev": true }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, "windows-release": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz", diff --git a/package.json b/package.json index 18a7663f5..10abb4d7b 100644 --- a/package.json +++ b/package.json @@ -447,7 +447,6 @@ "eslint-plugin-standard": "^4.0.1", "grunt": "^1.2.1", "grunt-auto-release": "^0.0.7", - "grunt-browserify": "^5.0.0", "grunt-bump": "^0.8.0", "grunt-check-clean": "^0.1.2", "grunt-cli": "^1.1.0", @@ -480,6 +479,7 @@ "sinon-chai": "^3.5.0", "supertest": "^4.0.2", "timer-shim": "^0.3.0", + "watchify": "^3.11.1", "which": "^1.3.1" }, "main": "./lib/index", @@ -506,6 +506,7 @@ "test": "npm run test:unit && npm run test:e2e && npm run test:client", "build": "node scripts/client.js build", "build:check": "node scripts/client.js check", + "build:watch": "node scripts/client.js watch", "test:appveyor": "grunt test-appveyor", "test:integration": "./scripts/integration-tests.sh", "link": "node --eval \"path=require('path'); require('fs').symlinkSync(path.resolve(__dirname), path.resolve(__dirname, 'node_modules', 'karma'), 'junction')\"", diff --git a/scripts/client.js b/scripts/client.js index 29dfabc72..be4400f13 100644 --- a/scripts/client.js +++ b/scripts/client.js @@ -1,13 +1,14 @@ const browserify = require('browserify') -const fs = require('fs') +const watchify = require('watchify') +const { createWriteStream } = require('fs') const { readFile } = require('fs').promises const bundleResourceToFile = (inPath, outPath) => { return new Promise((resolve, reject) => { browserify(inPath).bundle() - .pipe(fs.createWriteStream(outPath)) - .once('finish', () => resolve()) .once('error', (e) => reject(e)) + .pipe(createWriteStream(outPath)) + .once('finish', () => resolve()) }) } @@ -24,6 +25,28 @@ const bundleResource = (inPath) => { }) } +const watchResourceToFile = (inPath, outPath) => { + const b = browserify({ + entries: [inPath], + cache: {}, + packageCache: {}, + plugin: [watchify] + }) + + const bundle = () => { + b.bundle() + .once('error', (e) => { + console.error(`Failed to bundle ${inPath} into ${outPath}.`) + console.error(e) + }) + .pipe(createWriteStream(outPath)) + .once('finish', () => console.log(`Bundled ${inPath} into ${outPath}.`)) + } + + b.on('update', bundle) + bundle() +} + const main = async () => { if (process.argv[2] === 'build') { await bundleResourceToFile('client/main.js', 'static/karma.js') @@ -39,6 +62,9 @@ const main = async () => { // eslint-disable-next-line no-throw-literal throw 'Bundled client assets are outdated. Forgot to run "npm run build"?' } + } else if (process.argv[2] === 'watch') { + watchResourceToFile('client/main.js', 'static/karma.js') + watchResourceToFile('context/main.js', 'static/context.js') } else { // eslint-disable-next-line no-throw-literal throw `Unknown command: ${process.argv[2]}` From 8997b7465de3c5f7e436078b57acae98de1ce39a Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 23 Dec 2020 08:46:44 -0800 Subject: [PATCH 281/374] fix(test): clear up clearContext (#3597) emit the 'complete' event after the navigation event, if any. The 'complete' event on the client triggers the server to begin shutdown. The shutdown can race with the navigate context. Simplify return_url implementation, assuming that we don't need any additional execution in the client after we send 'complete'. --- client/karma.js | 53 +++++++++++++++++---------------------- lib/server.js | 2 -- static/karma.js | 53 +++++++++++++++++---------------------- test/client/karma.spec.js | 12 +++------ 4 files changed, 50 insertions(+), 70 deletions(-) diff --git a/client/karma.js b/client/karma.js index 6790a77ac..4442589cd 100644 --- a/client/karma.js +++ b/client/karma.js @@ -137,10 +137,6 @@ function Karma (socket, iframe, opener, navigator, location, document) { } } - function clearContext () { - navigateContextTo('about:blank') - } - this.log = function (type, args) { var values = [] @@ -234,15 +230,15 @@ function Karma (socket, iframe, opener, navigator, location, document) { socket.emit('result', resultsBuffer) resultsBuffer = [] } + // A test could have incorrectly issued a navigate. Wait one turn + // to ensure the error from an incorrect navigate is processed. + setTimeout(() => { + if (this.config.clearContext) { + navigateContextTo('about:blank') + } - if (self.config.clearContext) { - // A test could have incorrectly issued a navigate. To clear the context - // we will navigate the iframe. Delay ours to ensure the error from an - // incorrect navigate is processed. - setTimeout(clearContext) - } + socket.emit('complete', result || {}) - socket.emit('complete', result || {}, function () { if (returnUrl) { location.href = returnUrl } @@ -260,26 +256,23 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.on('execute', function (cfg) { - // Delay our navigation to the next event in case the clearContext has not completed. - setTimeout(function allowClearContextToComplete () { - // reset startEmitted and reload the iframe - startEmitted = false - self.config = cfg - - navigateContextTo(constant.CONTEXT_URL) - - if (self.config.clientDisplayNone) { - [].forEach.call(document.querySelectorAll('#banner, #browsers'), function (el) { - el.style.display = 'none' - }) - } + // reset startEmitted and reload the iframe + startEmitted = false + self.config = cfg - // clear the console before run - // works only on FF (Safari, Chrome do not allow to clear console from js source) - if (window.console && window.console.clear) { - window.console.clear() - } - }) + navigateContextTo(constant.CONTEXT_URL) + + if (self.config.clientDisplayNone) { + [].forEach.call(document.querySelectorAll('#banner, #browsers'), function (el) { + el.style.display = 'none' + }) + } + + // clear the console before run + // works only on FF (Safari, Chrome do not allow to clear console from js source) + if (window.console && window.console.clear) { + window.console.clear() + } }) socket.on('stop', function () { this.complete() diff --git a/lib/server.js b/lib/server.js index 4a3eecfca..229c21b19 100644 --- a/lib/server.js +++ b/lib/server.js @@ -256,8 +256,6 @@ class Server extends KarmaEventEmitter { const replySocketEvents = events.bufferEvents(socket, ['start', 'info', 'karma_error', 'result', 'complete']) - socket.on('complete', (data, ack) => ack()) - socket.on('error', (err) => { this.log.debug('karma server socket error: ' + err) }) diff --git a/static/karma.js b/static/karma.js index 0c289e0ca..4b791bc85 100644 --- a/static/karma.js +++ b/static/karma.js @@ -147,10 +147,6 @@ function Karma (socket, iframe, opener, navigator, location, document) { } } - function clearContext () { - navigateContextTo('about:blank') - } - this.log = function (type, args) { var values = [] @@ -244,15 +240,15 @@ function Karma (socket, iframe, opener, navigator, location, document) { socket.emit('result', resultsBuffer) resultsBuffer = [] } + // A test could have incorrectly issued a navigate. Wait one turn + // to ensure the error from an incorrect navigate is processed. + setTimeout(() => { + if (this.config.clearContext) { + navigateContextTo('about:blank') + } - if (self.config.clearContext) { - // A test could have incorrectly issued a navigate. To clear the context - // we will navigate the iframe. Delay ours to ensure the error from an - // incorrect navigate is processed. - setTimeout(clearContext) - } + socket.emit('complete', result || {}) - socket.emit('complete', result || {}, function () { if (returnUrl) { location.href = returnUrl } @@ -270,26 +266,23 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.on('execute', function (cfg) { - // Delay our navigation to the next event in case the clearContext has not completed. - setTimeout(function allowClearContextToComplete () { - // reset startEmitted and reload the iframe - startEmitted = false - self.config = cfg - - navigateContextTo(constant.CONTEXT_URL) - - if (self.config.clientDisplayNone) { - [].forEach.call(document.querySelectorAll('#banner, #browsers'), function (el) { - el.style.display = 'none' - }) - } + // reset startEmitted and reload the iframe + startEmitted = false + self.config = cfg - // clear the console before run - // works only on FF (Safari, Chrome do not allow to clear console from js source) - if (window.console && window.console.clear) { - window.console.clear() - } - }) + navigateContextTo(constant.CONTEXT_URL) + + if (self.config.clientDisplayNone) { + [].forEach.call(document.querySelectorAll('#banner, #browsers'), function (el) { + el.style.display = 'none' + }) + } + + // clear the console before run + // works only on FF (Safari, Chrome do not allow to clear console from js source) + if (window.console && window.console.clear) { + window.console.clear() + } }) socket.on('stop', function () { this.complete() diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index a309b174f..567339f48 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -437,24 +437,20 @@ describe('Karma', function () { it('should navigate the client to return_url if specified', function (done) { windowLocation.search = '?id=567&return_url=http://return.com' socket = new MockSocket() - k = new ClientKarma(socket, {}, windowStub, windowNavigator, windowLocation) + k = new ClientKarma(socket, iframe, windowStub, windowNavigator, windowLocation) clientWindow = { karma: k } ck = new ContextKarma(ContextKarma.getDirectCallParentKarmaMethod(clientWindow)) ck.config = {} sinon.spy(socket, 'disconnect') - - socket.on('complete', function (data, ack) { - ack() - }) + clock.tick(500) ck.complete() - - clock.tick(500) - setTimeout(function () { + setTimeout(() => { assert(windowLocation.href === 'http://return.com') done() }, 5) + clock.tick(10) }) From 3c649fa1e4a7f846d548e46c55addfa013889f31 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 23 Dec 2020 22:04:27 +0200 Subject: [PATCH 282/374] chore(build): remove obsolete Grunt tasks (#3602) These tasks are now handled by the semantic-release or other scripts and therefore we can clean them up. --- gruntfile.js | 58 - package-lock.json | 2874 +++++++++++---------------------------------- package.json | 7 - 3 files changed, 716 insertions(+), 2223 deletions(-) diff --git a/gruntfile.js b/gruntfile.js index 7a3b95a12..377867d44 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -26,70 +26,12 @@ module.exports = function (grunt) { 'test/unit/**/*.spec.js' ] } - }, - 'npm-publish': { - options: { - abortIfDirty: true, - tag: 'latest' - } - }, - 'npm-contributors': { - options: { - commitMessage: 'chore: update contributors' - } - }, - conventionalChangelog: { - release: { - options: { - changelogOpts: { - preset: 'angular' - } - }, - src: 'CHANGELOG.md' - } - }, - conventionalGithubReleaser: { - release: { - options: { - auth: { - type: 'oauth', - token: process.env.GH_TOKEN - }, - changelogOpts: { - preset: 'angular' - } - } - } - }, - bump: { - options: { - updateConfigs: ['pkg'], - commitFiles: [ - 'package.json', - 'CHANGELOG.md' - ], - commitMessage: 'chore: release v%VERSION%', - prereleaseName: 'rc' - } } }) - grunt.loadNpmTasks('grunt-check-clean') grunt.loadTasks('tasks') require('load-grunt-tasks')(grunt) grunt.registerTask('default', ['test']) grunt.registerTask('test-appveyor', ['test:unit', 'test:client']) - - grunt.registerTask('release', 'Build, bump and publish to NPM.', function (type) { - grunt.task.run([ - 'check_clean', - 'npm-contributors', - 'bump:' + (type || 'patch') + ':bump-only', - 'conventionalChangelog', - 'bump-commit', - 'conventionalGithubReleaser', - 'npm-publish' - ]) - }) } diff --git a/package-lock.json b/package-lock.json index c8da5ef94..c74d5612a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2764,15 +2764,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -2955,42 +2946,6 @@ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", "dev": true }, - "body": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz", - "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", - "dev": true, - "requires": { - "continuable-cache": "^0.3.1", - "error": "^7.0.0", - "raw-body": "~1.1.0", - "safe-json-parse": "~1.0.1" - }, - "dependencies": { - "bytes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz", - "integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=", - "dev": true - }, - "raw-body": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz", - "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", - "dev": true, - "requires": { - "bytes": "1", - "string_decoder": "0.10" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -3404,22 +3359,6 @@ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" - } - }, "cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", @@ -3768,31 +3707,6 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, - "continuable-cache": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz", - "integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=", - "dev": true - }, - "conventional-changelog": { - "version": "1.1.24", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-1.1.24.tgz", - "integrity": "sha512-2WcSUst4Y3Z4hHvoMTWXMJr/DmgVdLiMOVY1Kak2LfFz+GIz2KDp5naqbFesYbfXPmaZ5p491dO0FWZIJoJw1Q==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^1.6.6", - "conventional-changelog-atom": "^0.2.8", - "conventional-changelog-codemirror": "^0.3.8", - "conventional-changelog-core": "^2.0.11", - "conventional-changelog-ember": "^0.3.12", - "conventional-changelog-eslint": "^1.0.9", - "conventional-changelog-express": "^0.3.6", - "conventional-changelog-jquery": "^0.1.0", - "conventional-changelog-jscs": "^0.1.0", - "conventional-changelog-jshint": "^0.3.8", - "conventional-changelog-preset-loader": "^1.1.8" - } - }, "conventional-changelog-angular": { "version": "1.6.6", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", @@ -3803,24 +3717,6 @@ "q": "^1.5.1" } }, - "conventional-changelog-atom": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-0.2.8.tgz", - "integrity": "sha512-8pPZqhMbrnltNBizjoDCb/Sz85KyUXNDQxuAEYAU5V/eHn0okMBVjqc8aHWYpHrytyZWvMGbayOlDv7i8kEf6g==", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-codemirror": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-0.3.8.tgz", - "integrity": "sha512-3HFZKtBXTaUCHvz7ai6nk2+psRIkldDoNzCsom0egDtVmPsvvHZkzjynhdQyULfacRSsBTaiQ0ol6nBOL4dDiQ==", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, "conventional-changelog-conventionalcommits": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.2.1.tgz", @@ -3832,1233 +3728,722 @@ "q": "^1.5.1" } }, - "conventional-changelog-core": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-2.0.11.tgz", - "integrity": "sha512-HvTE6RlqeEZ/NFPtQeFLsIDOLrGP3bXYr7lFLMhCVsbduF1MXIe8OODkwMFyo1i9ku9NWBwVnVn0jDmIFXjDRg==", + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { - "conventional-changelog-writer": "^3.0.9", - "conventional-commits-parser": "^2.1.7", - "dateformat": "^3.0.0", - "get-pkg-repo": "^1.0.0", - "git-raw-commits": "^1.3.6", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^1.3.6", - "lodash": "^4.2.1", - "normalize-package-data": "^2.3.5", - "q": "^1.5.1", - "read-pkg": "^1.1.0", - "read-pkg-up": "^1.0.1", - "through2": "^2.0.0" + "safe-buffer": "~5.1.1" }, "dependencies": { - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + } + } + }, + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "core-js-pure": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", + "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "dependencies": { + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" } }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true } } }, - "conventional-changelog-ember": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-0.3.12.tgz", - "integrity": "sha512-mmJzA7uzbrOqeF89dMMi6z17O07ORTXlTMArnLG9ZTX4oLaKNolUlxFUFlFm9JUoVWajVpaHQWjxH1EOQ+ARoQ==", - "dev": true, - "requires": { - "q": "^1.5.1" - } - }, - "conventional-changelog-eslint": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-1.0.9.tgz", - "integrity": "sha512-h87nfVh2fdk9fJIvz26wCBsbDC/KxqCc5wSlNMZbXcARtbgNbNDIF7Y7ctokFdnxkzVdaHsbINkh548T9eBA7Q==", + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { - "q": "^1.5.1" + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" } }, - "conventional-changelog-express": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-0.3.6.tgz", - "integrity": "sha512-3iWVtBJZ9RnRnZveNDzOD8QRn6g6vUif0qVTWWyi5nUIAbuN1FfPVyKdAlJJfp5Im+dE8Kiy/d2SpaX/0X678Q==", + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { - "q": "^1.5.1" + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, - "conventional-changelog-jquery": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-0.1.0.tgz", - "integrity": "sha1-Agg5cWLjhGmG5xJztsecW1+A9RA=", + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "q": "^1.4.1" + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "conventional-changelog-jscs": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jscs/-/conventional-changelog-jscs-0.1.0.tgz", - "integrity": "sha1-BHnrRDzH1yxYvwvPDvHURKkvDlw=", + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { - "q": "^1.4.1" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" } }, - "conventional-changelog-jshint": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-0.3.8.tgz", - "integrity": "sha512-hn9QU4ZI/5V50wKPJNPGT4gEWgiBFpV6adieILW4MaUFynuDYOvQ71EMSj3EznJyKi/KzuXpc9dGmX8njZMjig==", + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "compare-func": "^1.3.1", - "q": "^1.5.1" + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" } }, - "conventional-changelog-preset-loader": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-1.1.8.tgz", - "integrity": "sha512-MkksM4G4YdrMlT2MbTsV2F6LXu/hZR0Tc/yenRrDIKRwBl/SP7ER4ZDlglqJsCzLJi4UonBc52Bkm5hzrOVCcw==", + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", "dev": true }, - "conventional-changelog-writer": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-3.0.9.tgz", - "integrity": "sha512-n9KbsxlJxRQsUnK6wIBRnARacvNnN4C/nxnxCkH+B/R1JS2Fa+DiP1dU4I59mEDEjgnFaN2+9wr1P1s7GYB5/Q==", + "cucumber": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cucumber/-/cucumber-6.0.5.tgz", + "integrity": "sha512-x+W9Fwk6TvcapQsYMxwFU5AsQJDOIJVGrPKmH15OC7jzb9/Dk7Hb0ZAyw4WcpaDcUDRc8bi2k2yJejDp5eTRlg==", "dev": true, "requires": { - "compare-func": "^1.3.1", - "conventional-commits-filter": "^1.1.6", - "dateformat": "^3.0.0", - "handlebars": "^4.0.2", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.2.1", - "meow": "^4.0.0", - "semver": "^5.5.0", - "split": "^1.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } - }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "assertion-error-formatter": "^3.0.0", + "bluebird": "^3.4.1", + "cli-table3": "^0.5.1", + "colors": "^1.1.2", + "commander": "^3.0.1", + "cucumber-expressions": "^8.1.0", + "cucumber-tag-expressions": "^2.0.2", + "duration": "^0.2.1", + "escape-string-regexp": "^2.0.0", + "figures": "^3.0.0", + "gherkin": "5.0.0", + "glob": "^7.1.3", + "indent-string": "^4.0.0", + "is-generator": "^1.0.2", + "is-stream": "^2.0.0", + "knuth-shuffle-seeded": "^1.0.6", + "lodash": "^4.17.14", + "mz": "^2.4.0", + "progress": "^2.0.0", + "resolve": "^1.3.3", + "serialize-error": "^4.1.0", + "stack-chain": "^2.0.0", + "stacktrace-js": "^2.0.0", + "string-argv": "^0.3.0", + "title-case": "^2.1.1", + "util-arity": "^1.0.2", + "verror": "^1.9.0" + }, + "dependencies": { + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", "dev": true }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "map-obj": { + "escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "meow": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" + "escape-string-regexp": "^1.0.5" }, "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true } } }, - "parse-json": { + "indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, - "trim-newlines": { + "is-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true } } }, - "conventional-commits-filter": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-1.1.6.tgz", - "integrity": "sha512-KcDgtCRKJCQhyk6VLT7zR+ZOyCnerfemE/CsR3iQpzRRFbLEs0Y6rwk3mpDvtOh04X223z+1xyJ582Stfct/0Q==", + "cucumber-expressions": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/cucumber-expressions/-/cucumber-expressions-8.3.0.tgz", + "integrity": "sha512-cP2ya0EiorwXBC7Ll7Cj7NELYbasNv9Ty42L4u7sso9KruWemWG1ZiTq4PMqir3SNDSrbykoqI5wZgMbLEDjLQ==", "dev": true, "requires": { - "is-subset": "^0.1.1", - "modify-values": "^1.0.0" + "becke-ch--regex--s0-0-v1--base--pl--lib": "^1.4.0", + "xregexp": "^4.2.4" } }, - "conventional-commits-parser": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-2.1.7.tgz", - "integrity": "sha512-BoMaddIEJ6B4QVMSDu9IkVImlGOSGA1I2BQyOZHeLQ6qVOJLcLKn97+fL6dGbzWEiqDzfH4OkcveULmeq2MHFQ==", + "cucumber-tag-expressions": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cucumber-tag-expressions/-/cucumber-tag-expressions-2.0.3.tgz", + "integrity": "sha512-+x5j1IfZrBtbvYHuoUX0rl4nUGxaey6Do9sM0CABmZfDCcWXuuRm1fQeCaklIYQgOFHQ6xOHvDSdkMHHpni6tQ==", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.0", - "lodash": "^4.2.1", - "meow": "^4.0.0", - "split2": "^2.0.0", - "through2": "^2.0.0", - "trim-off-newlines": "^1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, - "meow": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true - } + "array-find-index": "^1.0.1" } }, - "conventional-github-releaser": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/conventional-github-releaser/-/conventional-github-releaser-1.1.13.tgz", - "integrity": "sha1-C+ezp8eGfoiL5SZHWlkP9ZMDUXw=", - "dev": true, - "requires": { - "conventional-changelog": "^1.1.0", - "dateformat": "^1.0.11", - "git-semver-tags": "^1.0.0", - "github": "^0.2.4", - "lodash.merge": "^4.0.2", - "meow": "^3.3.0", - "object-assign": "^4.0.1", - "q": "^1.4.1", - "semver": "^5.0.1", - "semver-regex": "^1.0.0", - "through2": "^2.0.0" - } + "custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=" }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "dev": true, "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } + "es5-ext": "^0.10.50", + "type": "^1.0.1" } }, - "cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + "dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", + "dev": true }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "date-format": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", + "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==" + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, - "core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, "requires": { - "object-assign": "^4", - "vary": "^1" + "object-keys": "^1.0.12" } }, - "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" }, "dependencies": { - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "kind-of": "^6.0.0" } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "kind-of": "^6.0.0" } }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } } } }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "deprecation": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", + "dev": true + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "dev": true, "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" } }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, "requires": { - "cipher-base": "^1.0.1", "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "minimalistic-assert": "^1.0.0" } }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" } }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=" + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" } }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "cucumber": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cucumber/-/cucumber-6.0.5.tgz", - "integrity": "sha512-x+W9Fwk6TvcapQsYMxwFU5AsQJDOIJVGrPKmH15OC7jzb9/Dk7Hb0ZAyw4WcpaDcUDRc8bi2k2yJejDp5eTRlg==", + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { - "assertion-error-formatter": "^3.0.0", - "bluebird": "^3.4.1", - "cli-table3": "^0.5.1", - "colors": "^1.1.2", - "commander": "^3.0.1", - "cucumber-expressions": "^8.1.0", - "cucumber-tag-expressions": "^2.0.2", - "duration": "^0.2.1", - "escape-string-regexp": "^2.0.0", - "figures": "^3.0.0", - "gherkin": "5.0.0", - "glob": "^7.1.3", - "indent-string": "^4.0.0", - "is-generator": "^1.0.2", - "is-stream": "^2.0.0", - "knuth-shuffle-seeded": "^1.0.6", - "lodash": "^4.17.14", - "mz": "^2.4.0", - "progress": "^2.0.0", - "resolve": "^1.3.3", - "serialize-error": "^4.1.0", - "stack-chain": "^2.0.0", - "stacktrace-js": "^2.0.0", - "string-argv": "^0.3.0", - "title-case": "^2.1.1", - "util-arity": "^1.0.2", - "verror": "^1.9.0" + "path-type": "^4.0.0" }, "dependencies": { - "commander": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", - "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - } - } - }, - "indent-string": { + "path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true } } }, - "cucumber-expressions": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/cucumber-expressions/-/cucumber-expressions-8.3.0.tgz", - "integrity": "sha512-cP2ya0EiorwXBC7Ll7Cj7NELYbasNv9Ty42L4u7sso9KruWemWG1ZiTq4PMqir3SNDSrbykoqI5wZgMbLEDjLQ==", + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { - "becke-ch--regex--s0-0-v1--base--pl--lib": "^1.4.0", - "xregexp": "^4.2.4" + "esutils": "^2.0.2" } }, - "cucumber-tag-expressions": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/cucumber-tag-expressions/-/cucumber-tag-expressions-2.0.3.tgz", - "integrity": "sha512-+x5j1IfZrBtbvYHuoUX0rl4nUGxaey6Do9sM0CABmZfDCcWXuuRm1fQeCaklIYQgOFHQ6xOHvDSdkMHHpni6tQ==", + "dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "requires": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", "dev": true, "requires": { - "array-find-index": "^1.0.1" + "is-obj": "^1.0.0" } }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=" + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true }, - "d": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", - "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "es5-ext": "^0.10.50", - "type": "^1.0.1" + "readable-stream": "^2.0.2" } }, - "dargs": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", - "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", + "duration": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", + "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "d": "1", + "es5-ext": "~0.10.46" } }, - "dash-ast": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", - "dev": true - }, - "date-format": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-3.0.0.tgz", - "integrity": "sha512-eyTcpKOcamdhWJXj56DpQMo1ylSQpcGtGKXcU0Tb97+K56/CF5amAqqqNj0+KvA0iw2ynxtHWFsPDSClCxe48w==" - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, - "dateformat": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", - "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", + "elliptic": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", + "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", - "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - } - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-eql": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", - "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, - "requires": { - "type-detect": "^4.0.0" - } - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "once": "^1.4.0" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, + "engine.io": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.5.tgz", + "integrity": "sha512-Ri+whTNr2PKklxQkfbGjwEo+kCBUM4Qxk4wtLqLrhH+b1up2NFL9g9pjYWiCV/oazwB0rArnvF/ZmZN2ab5Hpg==", "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "cors": "~2.8.5", + "debug": "~4.1.0", + "engine.io-parser": "~4.0.0", + "ws": "^7.1.2" }, "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "requires": { - "kind-of": "^6.0.0" + "ms": "^2.1.1" } }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" } } }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true - }, - "deps-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", - "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", - "dev": true, + "engine.io-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", + "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", "requires": { - "JSONStream": "^1.0.3", - "shasum": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" + "base64-arraybuffer": "0.1.4" } }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "ansi-colors": "^4.1.1" } }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true + "ent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", + "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" }, - "detective": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", - "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "env-ci": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-4.5.2.tgz", + "integrity": "sha512-lS+edpNp2+QXEPkx6raEMIjKxKKWnJ4+VWzovYJ2NLYiJAYenSAXotFfVdgaFxdbVnvAbUI8epQDa1u12ERxfQ==", "dev": true, "requires": { - "acorn-node": "^1.6.1", - "defined": "^1.0.0", - "minimist": "^1.1.1" + "execa": "^3.2.0", + "java-properties": "^1.0.0" } }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=" - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "is-arrayish": "^0.2.1" } }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", "dev": true, "requires": { - "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } + "stackframe": "^1.1.1" } }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", "dev": true, "requires": { - "esutils": "^2.0.2" + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" } }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", - "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "dot-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", - "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", - "dev": true, - "requires": { - "is-obj": "^1.0.0" - } - }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", - "dev": true - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - } - }, - "duration": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/duration/-/duration-0.2.2.tgz", - "integrity": "sha512-06kgtea+bGreF5eKYgI/36A6pLXggY7oR4p1pq4SmdFBn1ReOL5D8RhG64VrqfTTKNucqqtBAwEj8aB88mcqrg==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.46" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "engine.io": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.5.tgz", - "integrity": "sha512-Ri+whTNr2PKklxQkfbGjwEo+kCBUM4Qxk4wtLqLrhH+b1up2NFL9g9pjYWiCV/oazwB0rArnvF/ZmZN2ab5Hpg==", - "requires": { - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.1.0", - "engine.io-parser": "~4.0.0", - "ws": "^7.1.2" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", - "requires": { - "base64-arraybuffer": "0.1.4" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" - }, - "env-ci": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-4.5.2.tgz", - "integrity": "sha512-lS+edpNp2+QXEPkx6raEMIjKxKKWnJ4+VWzovYJ2NLYiJAYenSAXotFfVdgaFxdbVnvAbUI8epQDa1u12ERxfQ==", - "dev": true, - "requires": { - "execa": "^3.2.0", - "java-properties": "^1.0.0" - } - }, - "error": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/error/-/error-7.2.1.tgz", - "integrity": "sha512-fo9HBvWnx3NGUKMvMwB/CBCMMrfEJgbDTVDEkPygA3Bdd3lM1OyCd+rbQ8BwnpF6GdVeOLDNmyL4N5Bg80ZvdA==", - "dev": true, - "requires": { - "string-template": "~0.2.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "error-stack-parser": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", - "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", - "dev": true, - "requires": { - "stackframe": "^1.1.1" - } - }, - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", @@ -5901,15 +5286,6 @@ "reusify": "^1.0.4" } }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -6086,512 +5462,181 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "form-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.0.tgz", - "integrity": "sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "formidable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", - "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", - "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-access": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", - "dev": true, - "requires": { - "null-check": "^1.0.0" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gaze": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", - "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", - "dev": true, - "requires": { - "globule": "^1.0.0" - } - }, - "get-assigned-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-func-name": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true - }, - "get-pkg-repo": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", - "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "meow": "^3.3.0", - "normalize-package-data": "^2.3.0", - "parse-github-repo-url": "^1.3.0", - "through2": "^2.0.0" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", - "dev": true - }, - "gherkin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/gherkin/-/gherkin-5.0.0.tgz", - "integrity": "sha1-lt70EZjsOQgli1Ea909lWidk0qE=", - "dev": true - }, - "git-log-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", - "integrity": "sha1-LmpMGxP8AAKCB7p5WnrDFme5/Uo=", - "dev": true, - "requires": { - "argv-formatter": "~1.0.0", - "spawn-error-forwarder": "~1.0.0", - "split2": "~1.0.0", - "stream-combiner2": "~1.1.1", - "through2": "~2.0.0", - "traverse": "~0.6.6" - }, - "dependencies": { - "split2": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", - "integrity": "sha1-UuLiIdiMdfmnP5BVbiY/+WdysxQ=", - "dev": true, - "requires": { - "through2": "~2.0.0" - } - } - } - }, - "git-raw-commits": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.6.tgz", - "integrity": "sha512-svsK26tQ8vEKnMshTDatSIQSMDdz8CxIIqKsvPqbtV23Etmw6VNaFAitu8zwZ0VrOne7FztwPyRLxK7/DIUTQg==", - "dev": true, - "requires": { - "dargs": "^4.0.1", - "lodash.template": "^4.0.2", - "meow": "^4.0.0", - "split2": "^2.0.0", - "through2": "^2.0.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, - "meow": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true - } - } - }, - "git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", - "dev": true, - "requires": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - } - }, - "git-semver-tags": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-1.3.6.tgz", - "integrity": "sha512-2jHlJnln4D/ECk9FxGEBh3k44wgYdWjWDtMmJPaecjoRmxKo3Y1Lh8GMYuOPu04CHw86NTAODchYjC5pnpMQig==", - "dev": true, - "requires": { - "meow": "^4.0.0", - "semver": "^5.5.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", - "dev": true - }, - "meow": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", - "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist": "^1.1.3", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true + "ms": "^2.1.1" + } }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, - "gitconfiglocal": { + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "form-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.0.tgz", + "integrity": "sha512-WXieX3G/8side6VIqx44ablyULoGruSde5PNTxoUyo5CeyAMX6nVWUd0rgist/EuX655cjhUhTo1Fo3tRYqbcA==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "formidable": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", + "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-access": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", + "dev": true, + "requires": { + "null-check": "^1.0.0" + } + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", "dev": true, "requires": { - "ini": "^1.3.2" + "pump": "^3.0.0" } }, - "github": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/github/-/github-0.2.4.tgz", - "integrity": "sha1-JPp/DhP6EblGr5ETTFGYKpHOU4s=", + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getobject": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", + "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", + "dev": true + }, + "gherkin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gherkin/-/gherkin-5.0.0.tgz", + "integrity": "sha1-lt70EZjsOQgli1Ea909lWidk0qE=", + "dev": true + }, + "git-log-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz", + "integrity": "sha1-LmpMGxP8AAKCB7p5WnrDFme5/Uo=", "dev": true, "requires": { - "mime": "^1.2.11" + "argv-formatter": "~1.0.0", + "spawn-error-forwarder": "~1.0.0", + "split2": "~1.0.0", + "stream-combiner2": "~1.1.1", + "through2": "~2.0.0", + "traverse": "~0.6.6" }, "dependencies": { - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true + "split2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz", + "integrity": "sha1-UuLiIdiMdfmnP5BVbiY/+WdysxQ=", + "dev": true, + "requires": { + "through2": "~2.0.0" + } } } }, @@ -6696,17 +5741,6 @@ } } }, - "globule": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", - "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", - "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - } - }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -6738,196 +5772,55 @@ "minimatch": "~3.0.4", "mkdirp": "~1.0.4", "nopt": "~3.0.6", - "rimraf": "~3.0.2" - }, - "dependencies": { - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "grunt-auto-release": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/grunt-auto-release/-/grunt-auto-release-0.0.7.tgz", - "integrity": "sha1-ShvjJUsQoXs0HkAvUbhRkehs9NE=", - "dev": true - }, - "grunt-bump": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/grunt-bump/-/grunt-bump-0.8.0.tgz", - "integrity": "sha1-0//gzzzws44JYHt4U49CpTHq/lU=", - "dev": true, - "requires": { - "semver": "^5.1.0" - } - }, - "grunt-check-clean": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/grunt-check-clean/-/grunt-check-clean-0.1.2.tgz", - "integrity": "sha1-ArsQ9+nyh4eCEg3hlm02ZJ8stBQ=", - "dev": true - }, - "grunt-cli": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", - "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", - "dev": true, - "requires": { - "grunt-known-options": "~1.1.0", - "interpret": "~1.1.0", - "liftoff": "~2.5.0", - "nopt": "~4.0.1", - "v8flags": "~3.1.1" - }, - "dependencies": { - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, - "grunt-contrib-watch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-watch/-/grunt-contrib-watch-1.1.0.tgz", - "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", - "dev": true, - "requires": { - "async": "^2.6.0", - "gaze": "^1.1.0", - "lodash": "^4.17.10", - "tiny-lr": "^1.1.1" - } - }, - "grunt-conventional-changelog": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/grunt-conventional-changelog/-/grunt-conventional-changelog-6.1.0.tgz", - "integrity": "sha1-mL1b37Kw3mMWwFx8b6ykziTdFDU=", - "dev": true, - "requires": { - "chalk": "^1.1.0", - "concat-stream": "^1.5.0", - "conventional-changelog": "^1.1.0", - "plur": "^2.0.0", - "q": "^1.4.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "rimraf": "~3.0.2" + }, + "dependencies": { + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true } } }, - "grunt-conventional-github-releaser": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-conventional-github-releaser/-/grunt-conventional-github-releaser-1.0.0.tgz", - "integrity": "sha1-7Tbg9V1orq6FrxSEBsPXAYJnuHU=", + "grunt-cli": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", + "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", "dev": true, "requires": { - "chalk": "^1.1.0", - "conventional-github-releaser": "^1.1.0", - "plur": "^2.0.0" + "grunt-known-options": "~1.1.0", + "interpret": "~1.1.0", + "liftoff": "~2.5.0", + "nopt": "~4.0.1", + "v8flags": "~3.1.1" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "abbrev": "1", + "osenv": "^0.1.4" } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true } } }, @@ -7000,39 +5893,6 @@ "mkdirp": "^0.5.0" } }, - "grunt-npm": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/grunt-npm/-/grunt-npm-0.0.2.tgz", - "integrity": "sha1-s8s0ub3y6tafFQFtkkEqeqkxzhQ=", - "dev": true - }, - "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -7048,23 +5908,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7204,12 +6047,6 @@ } } }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=", - "dev": true - }, "http-proxy": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", @@ -7587,12 +6424,6 @@ "p-is-promise": "^3.0.0" } }, - "irregular-plurals": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", - "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=", - "dev": true - }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", @@ -7717,15 +6548,6 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", @@ -7829,12 +6651,6 @@ "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", "dev": true }, - "is-subset": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", - "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", - "dev": true - }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -7862,12 +6678,6 @@ "unc-path-regex": "^0.1.2" } }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -8210,12 +7020,6 @@ "integrity": "sha1-e3QYm/rW52Nn+1oQ88NpExKLeCs=", "dev": true }, - "livereload-js": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz", - "integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==", - "dev": true - }, "load-grunt-tasks": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-4.0.0.tgz", @@ -8303,12 +7107,6 @@ "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", "dev": true }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, "lodash.set": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", @@ -8502,99 +7300,6 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "^2.0.0" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "^0.2.0" - } - } - } - }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -12613,12 +11318,6 @@ "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", "dev": true }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -12951,12 +11650,6 @@ "path-root": "^0.1.1" } }, - "parse-github-repo-url": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", - "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", - "dev": true - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -13110,21 +11803,6 @@ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "^2.0.0" - } - }, "pkg-conf": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", @@ -13192,15 +11870,6 @@ "semver-compare": "^1.0.0" } }, - "plur": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", - "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true, - "requires": { - "irregular-plurals": "^1.0.0" - } - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -13506,27 +12175,6 @@ "resolve": "^1.1.6" } }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" - }, - "dependencies": { - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - } - } - }, "redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", @@ -13585,15 +12233,6 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -13720,12 +12359,6 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, - "safe-json-parse": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz", - "integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=", - "dev": true - }, "safe-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", @@ -14081,12 +12714,6 @@ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, - "semver-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-1.0.0.tgz", - "integrity": "sha1-kqSWkGX5xwxpR1PVUkj8aPj2Usk=", - "dev": true - }, "serialize-error": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-4.1.0.tgz", @@ -14670,12 +13297,6 @@ "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", "dev": true }, - "string-template": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz", - "integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=", - "dev": true - }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -14750,15 +13371,6 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "^4.0.1" - } - }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -15010,37 +13622,6 @@ "process": "~0.11.0" } }, - "tiny-lr": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz", - "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", - "dev": true, - "requires": { - "body": "^5.1.0", - "debug": "^3.1.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.3.0", - "object-assign": "^4.1.0", - "qs": "^6.4.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, "title-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", @@ -15127,12 +13708,6 @@ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", "dev": true }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, "trim-off-newlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", @@ -15634,23 +14209,6 @@ } } }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true - }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index 10abb4d7b..e350c7927 100644 --- a/package.json +++ b/package.json @@ -446,15 +446,8 @@ "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", "grunt": "^1.2.1", - "grunt-auto-release": "^0.0.7", - "grunt-bump": "^0.8.0", - "grunt-check-clean": "^0.1.2", "grunt-cli": "^1.1.0", - "grunt-contrib-watch": "^1.1.0", - "grunt-conventional-changelog": "^6.0.1", - "grunt-conventional-github-releaser": "^1.0.0", "grunt-mocha-test": "^0.13.2", - "grunt-npm": "0.0.2", "http2": "^3.3.6", "husky": "^4.2.5", "jasmine-core": "^3.6.0", From e6b045f7944aa54a18be7d99fdd490a8e521d931 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 23 Dec 2020 13:47:20 -0800 Subject: [PATCH 283/374] chore(deps): npm audit fix the package-lock.json (#3603) --- package-lock.json | 120 +++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 55 deletions(-) diff --git a/package-lock.json b/package-lock.json index c74d5612a..7febbf37a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6368,9 +6368,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "inline-source-map": { @@ -7739,9 +7739,9 @@ } }, "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, "nopt": { @@ -7777,9 +7777,9 @@ "dev": true }, "npm": { - "version": "6.14.7", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.7.tgz", - "integrity": "sha512-swhsdpNpyXg4GbM6LpOQ6qaloQuIKizZ+Zh6JPXJQc59ka49100Js0WvZx594iaKSoFgkFq2s8uXFHS3/Xy2WQ==", + "version": "6.14.10", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.10.tgz", + "integrity": "sha512-FT23Qy/JMA+qxEYReMOr1MY7642fKn8Onn+72LASPi872Owvmw0svm+/DXTHOC3yO9CheEO+EslyXEpdBdRtIA==", "dev": true, "requires": { "JSONStream": "^1.3.5", @@ -7846,7 +7846,7 @@ "lodash.uniq": "~4.5.0", "lodash.without": "~4.4.0", "lru-cache": "^5.1.1", - "meant": "~1.0.1", + "meant": "^1.0.2", "mississippi": "^3.0.0", "mkdirp": "^0.5.5", "move-concurrently": "^1.0.1", @@ -7861,11 +7861,11 @@ "npm-packlist": "^1.4.8", "npm-pick-manifest": "^3.0.2", "npm-profile": "^4.0.4", - "npm-registry-fetch": "^4.0.5", - "npm-user-validate": "~1.0.0", + "npm-registry-fetch": "^4.0.7", + "npm-user-validate": "^1.0.1", "npmlog": "~4.1.2", "once": "~1.4.0", - "opener": "^1.5.1", + "opener": "^1.5.2", "osenv": "^0.1.5", "pacote": "^9.5.12", "path-is-inside": "~1.0.2", @@ -7937,17 +7937,6 @@ "humanize-ms": "^1.2.1" } }, - "ajv": { - "version": "5.5.2", - "bundled": true, - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, "ansi-align": { "version": "2.0.0", "bundled": true, @@ -8278,11 +8267,6 @@ "mkdirp": "~0.5.0" } }, - "co": { - "version": "4.6.0", - "bundled": true, - "dev": true - }, "code-point-at": { "version": "1.1.0", "bundled": true, @@ -8374,11 +8358,11 @@ } }, "configstore": { - "version": "3.1.2", + "version": "3.1.5", "bundled": true, "dev": true, "requires": { - "dot-prop": "^4.1.0", + "dot-prop": "^4.2.1", "graceful-fs": "^4.1.2", "make-dir": "^1.0.0", "unique-string": "^1.0.0", @@ -8554,7 +8538,7 @@ } }, "dot-prop": { - "version": "4.2.0", + "version": "4.2.1", "bundled": true, "dev": true, "requires": { @@ -8731,11 +8715,6 @@ "bundled": true, "dev": true }, - "fast-deep-equal": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, "fast-json-stable-stringify": { "version": "2.0.0", "bundled": true, @@ -9056,12 +9035,35 @@ "dev": true }, "har-validator": { - "version": "5.1.0", + "version": "5.1.5", "bundled": true, "dev": true, "requires": { - "ajv": "^5.3.0", + "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "bundled": true, + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "bundled": true, + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "bundled": true, + "dev": true + } } }, "has": { @@ -9348,11 +9350,6 @@ "bundled": true, "dev": true }, - "json-schema-traverse": { - "version": "0.3.1", - "bundled": true, - "dev": true - }, "json-stringify-safe": { "version": "5.0.1", "bundled": true, @@ -9700,7 +9697,7 @@ } }, "meant": { - "version": "1.0.1", + "version": "1.0.2", "bundled": true, "dev": true }, @@ -9725,6 +9722,11 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true + }, "minizlib": { "version": "1.3.3", "bundled": true, @@ -9961,7 +9963,7 @@ } }, "npm-registry-fetch": { - "version": "4.0.5", + "version": "4.0.7", "bundled": true, "dev": true, "requires": { @@ -9990,7 +9992,7 @@ } }, "npm-user-validate": { - "version": "1.0.0", + "version": "1.0.1", "bundled": true, "dev": true }, @@ -10043,7 +10045,7 @@ } }, "opener": { - "version": "1.5.1", + "version": "1.5.2", "bundled": true, "dev": true }, @@ -10335,13 +10337,6 @@ "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true - } } }, "read": { @@ -11001,6 +10996,21 @@ "xdg-basedir": "^3.0.0" } }, + "uri-js": { + "version": "4.4.0", + "bundled": true, + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "bundled": true, + "dev": true + } + } + }, "url-parse-lax": { "version": "1.0.0", "bundled": true, From 87f7e5eb02e91effc5689edf18c1011fe53cc526 Mon Sep 17 00:00:00 2001 From: Athur Ming Date: Thu, 24 Dec 2020 05:49:55 +0800 Subject: [PATCH 284/374] chore(license): Update copyright notice to 2020 [ci skip] (#3568) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index d344a801f..2217a0478 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License -Copyright (C) 2011-2019 Google, Inc. +Copyright (C) 2011-2020 Google, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in From 1c9c2de54fa1abcb2c0edceebb159440b77e4863 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 23 Dec 2020 14:06:36 -0800 Subject: [PATCH 285/374] fix(test): mark all second connections reconnects (#3598) The reconnecting test is flakey, sometimes running the tests twice. This is exactly the behavior we are trying to prevent. Hard to reproduce. Refactoring: * rename newBrowser to knownBrowser as appropriate. * move browser STATE constant set/check into browser module. Browser should be the only place the state is set. * pass singleRun and clientConfig into Browser * pass isSocketReconnect into browser.reconnect() * rename browser.onDisconnect to browser.onSocketDisconnect to distinguish the socket from the reload cases. --- client/karma.js | 11 +++-- lib/browser.js | 59 ++++++++++++++++----------- lib/server.js | 28 +++---------- static/karma.js | 11 +++-- test/client/karma.spec.js | 6 ++- test/e2e/reconnecting.feature | 1 + test/e2e/support/reconnecting/test.js | 15 ++++--- test/unit/browser.spec.js | 42 +++++++++++-------- test/unit/server.spec.js | 9 ++-- 9 files changed, 92 insertions(+), 90 deletions(-) diff --git a/client/karma.js b/client/karma.js index 4442589cd..0f1e05ede 100644 --- a/client/karma.js +++ b/client/karma.js @@ -41,9 +41,11 @@ function Karma (socket, iframe, opener, navigator, location, document) { } } - // This variable will be set to "true" whenever the socket lost connection and was able to - // reconnect to the Karma server. This will be passed to the Karma server then, so that - // Karma can differentiate between a socket client reconnect and a full browser reconnect. + // To start we will signal the server that we are not reconnecting. If the socket loses + // connection and was able to reconnect to the Karma server we will get a + // second 'connect' event. There we will pass 'true' and that will be passed to the + // Karma server then, so that Karma can differentiate between a socket client + // econnect and a full browser reconnect. var socketReconnect = false this.VERSION = constant.VERSION @@ -299,9 +301,6 @@ function Karma (socket, iframe, opener, navigator, location, document) { info.displayName = displayName } socket.emit('register', info) - }) - - socket.on('reconnect', function () { socketReconnect = true }) } diff --git a/lib/browser.js b/lib/browser.js index c3ab8cc21..aa8795792 100644 --- a/lib/browser.js +++ b/lib/browser.js @@ -11,7 +11,8 @@ const EXECUTING_DISCONNECTED = 'EXECUTING_DISCONNECTED' // The browser is execut const DISCONNECTED = 'DISCONNECTED' // The browser got completely disconnected (e.g. browser crash) and can be only restored with a restart of execution. class Browser { - constructor (id, fullName, collection, emitter, socket, timer, disconnectDelay, noActivityTimeout) { + constructor (id, fullName, collection, emitter, socket, timer, disconnectDelay, + noActivityTimeout, singleRun, clientConfig) { this.id = id this.fullName = fullName this.name = helper.browserFullNameToShort(fullName) @@ -19,6 +20,8 @@ class Browser { this.disconnectsCount = 0 this.activeSockets = [socket] this.noActivityTimeout = noActivityTimeout + this.singleRun = singleRun + this.clientConfig = clientConfig this.collection = collection this.emitter = emitter this.socket = socket @@ -94,9 +97,8 @@ class Browser { } } - onDisconnect (reason, disconnectedSocket) { + onSocketDisconnect (reason, disconnectedSocket) { helper.arrayRemove(this.activeSockets, disconnectedSocket) - if (this.activeSockets.length) { this.log.debug(`Disconnected ${disconnectedSocket.id}, still have ${this.getActiveSocketsIds()}`) return @@ -119,24 +121,27 @@ class Browser { } } - reconnect (newSocket) { - if (this.state === EXECUTING_DISCONNECTED) { + reconnect (newSocket, clientSaysReconnect) { + if (!clientSaysReconnect || this.state === DISCONNECTED) { + this.log.info(`Disconnected browser returned on socket ${newSocket.id} with id ${this.id}.`) + this.setState(CONNECTED) + + // The disconnected browser is already part of the collection. + // Update the collection view in the UI (header on client.html) + this.emitter.emit('browsers_change', this.collection) + // Notify the launcher + this.emitter.emit('browser_register', this) + // Execute tests if configured to do so. + if (this.singleRun) { + this.execute() + } + } else if (this.state === EXECUTING_DISCONNECTED) { this.log.debug('Lost socket connection, but browser continued to execute. Reconnected ' + `on socket ${newSocket.id}.`) this.setState(EXECUTING) } else if ([CONNECTED, CONFIGURING, EXECUTING].includes(this.state)) { this.log.debug(`Rebinding to new socket ${newSocket.id} (already have ` + `${this.getActiveSocketsIds()})`) - } else if (this.state === DISCONNECTED) { - this.log.info(`Disconnected browser returned on socket ${newSocket.id} with id ${this.id}.`) - this.setState(CONNECTED) - - // Since the disconnected browser is already part of the collection and we want to - // make sure that the server can properly handle the browser like it's the first time - // connecting this browser (as we want a complete new execution), we need to emit the - // following events: - this.emitter.emit('browsers_change', this.collection) - this.emitter.emit('browser_register', this) } if (!this.activeSockets.some((s) => s.id === newSocket.id)) { @@ -161,8 +166,8 @@ class Browser { this.refreshNoActivityTimeout() } - execute (config) { - this.activeSockets.forEach((socket) => socket.emit('execute', config)) + execute () { + this.activeSockets.forEach((socket) => socket.emit('execute', this.clientConfig)) this.setState(CONFIGURING) this.refreshNoActivityTimeout() } @@ -172,10 +177,14 @@ class Browser { } disconnect (reason) { - this.log.warn(`Disconnected (${this.disconnectsCount} times)${reason || ''}`) - this.setState(DISCONNECTED) + this.log.warn(`Disconnected (${this.disconnectsCount} times) ${reason || ''}`) this.disconnectsCount++ - this.emitter.emit('browser_error', this, `Disconnected${reason || ''}`) + this.emitter.emit('browser_error', this, `Disconnected ${reason || ''}`) + this.remove() + } + + remove () { + this.setState(DISCONNECTED) this.collection.remove(this) } @@ -201,7 +210,7 @@ class Browser { bindSocketEvents (socket) { // TODO: check which of these events are actually emitted by socket - socket.on('disconnect', (reason) => this.onDisconnect(reason, socket)) + socket.on('disconnect', (reason) => this.onSocketDisconnect(reason, socket)) socket.on('start', (info) => this.onStart(info)) socket.on('karma_error', (error) => this.onKarmaError(error)) socket.on('complete', (result) => this.onComplete(result)) @@ -246,9 +255,11 @@ class Browser { Browser.factory = function ( id, fullName, /* capturedBrowsers */ collection, emitter, socket, timer, /* config.browserDisconnectTimeout */ disconnectDelay, - /* config.browserNoActivityTimeout */ noActivityTimeout -) { - return new Browser(id, fullName, collection, emitter, socket, timer, disconnectDelay, noActivityTimeout) + /* config.browserNoActivityTimeout */ noActivityTimeout, + /* config.singleRun */ singleRun, + /* config.client */ clientConfig) { + return new Browser(id, fullName, collection, emitter, socket, timer, + disconnectDelay, noActivityTimeout, singleRun, clientConfig) } Browser.STATE_CONNECTED = CONNECTED diff --git a/lib/server.js b/lib/server.js index 229c21b19..804745088 100644 --- a/lib/server.js +++ b/lib/server.js @@ -261,27 +261,12 @@ class Server extends KarmaEventEmitter { }) socket.on('register', (info) => { - let newBrowser = info.id ? (capturedBrowsers.getById(info.id) || singleRunBrowsers.getById(info.id)) : null - - if (newBrowser) { - // By default if a browser disconnects while still executing, we assume that the test - // execution still continues because just the socket connection has been terminated. Now - // since we know whether this is just a socket reconnect or full client reconnect, we - // need to update the browser state accordingly. This is necessary because in case a - // browser crashed and has been restarted, we need to start with a fresh execution. - if (!info.isSocketReconnect) { - newBrowser.setState(Browser.STATE_DISCONNECTED) - } - - newBrowser.reconnect(socket) + const knownBrowser = info.id ? (capturedBrowsers.getById(info.id) || singleRunBrowsers.getById(info.id)) : null - // Since not every reconnected browser is able to continue with its previous execution, - // we need to start a new execution in case a browser has restarted and is now idling. - if (newBrowser.state === Browser.STATE_CONNECTED && config.singleRun) { - newBrowser.execute(config.client) - } + if (knownBrowser) { + knownBrowser.reconnect(socket, info.isSocketReconnect) } else { - newBrowser = this._injector.createChild([{ + const newBrowser = this._injector.createChild([{ id: ['value', info.id || null], fullName: ['value', (helper.isDefined(info.displayName) ? info.displayName : info.name)], socket: ['value', socket] @@ -290,7 +275,7 @@ class Server extends KarmaEventEmitter { newBrowser.init() if (config.singleRun) { - newBrowser.execute(config.client) + newBrowser.execute() singleRunBrowsers.add(newBrowser) } } @@ -334,8 +319,7 @@ class Server extends KarmaEventEmitter { singleRunDoneBrowsers[completedBrowser.id] = true if (launcher.kill(completedBrowser.id)) { - // workaround to supress "disconnect" warning - completedBrowser.state = Browser.STATE_DISCONNECTED + completedBrowser.remove() } emitRunCompleteIfAllBrowsersDone() diff --git a/static/karma.js b/static/karma.js index 4b791bc85..9a66d9f0d 100644 --- a/static/karma.js +++ b/static/karma.js @@ -51,9 +51,11 @@ function Karma (socket, iframe, opener, navigator, location, document) { } } - // This variable will be set to "true" whenever the socket lost connection and was able to - // reconnect to the Karma server. This will be passed to the Karma server then, so that - // Karma can differentiate between a socket client reconnect and a full browser reconnect. + // To start we will signal the server that we are not reconnecting. If the socket loses + // connection and was able to reconnect to the Karma server we will get a + // second 'connect' event. There we will pass 'true' and that will be passed to the + // Karma server then, so that Karma can differentiate between a socket client + // econnect and a full browser reconnect. var socketReconnect = false this.VERSION = constant.VERSION @@ -309,9 +311,6 @@ function Karma (socket, iframe, opener, navigator, location, document) { info.displayName = displayName } socket.emit('register', info) - }) - - socket.on('reconnect', function () { socketReconnect = true }) } diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index 567339f48..21966464f 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -204,11 +204,13 @@ describe('Karma', function () { }) it('should mark "register" event for reconnected socket', function () { + // First connect. + socket.emit('connect') + socket.on('register', sinon.spy(function (info) { assert(info.isSocketReconnect === true) })) - - socket.emit('reconnect') + // Reconnect socket.emit('connect') }) diff --git a/test/e2e/reconnecting.feature b/test/e2e/reconnecting.feature index 829cbaec7..246d4e0da 100644 --- a/test/e2e/reconnecting.feature +++ b/test/e2e/reconnecting.feature @@ -21,6 +21,7 @@ Feature: Passing Options When I start Karma Then it passes with: """ + LOG: '============== START TEST ==============' ..... Chrome Headless """ diff --git a/test/e2e/support/reconnecting/test.js b/test/e2e/support/reconnecting/test.js index a3b682e1b..74216c7fe 100644 --- a/test/e2e/support/reconnecting/test.js +++ b/test/e2e/support/reconnecting/test.js @@ -6,27 +6,26 @@ describe('plus', function () { } it('should pass', function () { + // In flaky fails we probably get two starts. + console.log('============== START TEST ==============') expect(1).toBe(1) }) it('should disconnect', function (done) { expect(2).toBe(2) - socket().disconnect() - - done() + setTimeout(() => { + socket().disconnect() + done() + }, 500) }) it('should work', function () { expect(plus(1, 2)).toBe(3) }) - it('should re-connect', function (done) { + it('should re-connect', function () { expect(4).toBe(4) - // Emit reconnect, so Karma will not start new test run after reconnecting. - socket().emit('reconnect') socket().connect() - - done() }) it('should work', function () { diff --git a/test/unit/browser.spec.js b/test/unit/browser.spec.js index ec889b083..15b150a59 100644 --- a/test/unit/browser.spec.js +++ b/test/unit/browser.spec.js @@ -215,7 +215,7 @@ describe('Browser', () => { }) }) - describe('onDisconnect', () => { + describe('onSocketDisconnect', () => { let timer = null beforeEach(() => { @@ -227,7 +227,7 @@ describe('Browser', () => { it('should remove from parent collection', () => { expect(collection.length).to.equal(1) - browser.onDisconnect('socket.io-reason', socket) + browser.onSocketDisconnect('socket.io-reason', socket) expect(collection.length).to.equal(0) }) @@ -236,7 +236,7 @@ describe('Browser', () => { emitter.on('browser_complete', spy) browser.state = Browser.STATE_EXECUTING - browser.onDisconnect('socket.io-reason', socket) + browser.onSocketDisconnect('socket.io-reason', socket) timer.wind(20) expect(browser.lastResult.disconnected).to.equal(true) @@ -248,7 +248,7 @@ describe('Browser', () => { emitter.on('browser_complete', spy) browser.state = Browser.STATE_CONNECTED - browser.onDisconnect('socket.io-reason', socket) + browser.onSocketDisconnect('socket.io-reason', socket) expect(spy).not.to.have.been.called }) }) @@ -261,8 +261,8 @@ describe('Browser', () => { browser.init() browser.state = Browser.STATE_EXECUTING - browser.onDisconnect('socket.io-reason', socket) - browser.reconnect(mkSocket()) + browser.onSocketDisconnect('socket.io-reason', socket) + browser.reconnect(mkSocket(), true) timer.wind(10) expect(browser.state).to.equal(Browser.STATE_EXECUTING) @@ -275,7 +275,7 @@ describe('Browser', () => { browser.init() browser.state = Browser.STATE_EXECUTING - browser.reconnect(mkSocket()) + browser.reconnect(mkSocket(), true) // still accept results on the old socket socket.emit('result', { success: true }) @@ -293,7 +293,7 @@ describe('Browser', () => { browser = new Browser('id', 'Chrome 25.0', collection, emitter, socket, null, 10) browser.state = Browser.STATE_DISCONNECTED - browser.reconnect(mkSocket()) + browser.reconnect(mkSocket(), true) expect(browser.isConnected()).to.equal(true) }) @@ -306,7 +306,7 @@ describe('Browser', () => { browser.state = Browser.STATE_DISCONNECTED - browser.reconnect(mkSocket()) + browser.reconnect(mkSocket(), false) expect(collection.length).to.equal(1) }) @@ -387,13 +387,18 @@ describe('Browser', () => { describe('execute and start', () => { it('should emit execute and change state to CONFIGURING', () => { const spyExecute = sinon.spy() - const config = {} - browser = new Browser('fake-id', 'full name', collection, emitter, socket) + const timer = undefined + const disconnectDelay = 0 + const noActivityTimeout = 0 + const singleRun = false + const clientConfig = {} + browser = new Browser('fake-id', 'full name', collection, emitter, socket, + timer, disconnectDelay, noActivityTimeout, singleRun, clientConfig) socket.on('execute', spyExecute) - browser.execute(config) + browser.execute() expect(browser.state).to.equal(Browser.STATE_CONFIGURING) - expect(spyExecute).to.have.been.calledWith(config) + expect(spyExecute).to.have.been.calledWith(clientConfig) }) it('should emit start and change state to EXECUTING', () => { @@ -417,7 +422,7 @@ describe('Browser', () => { expect(browser.isConnected()).to.equal(false) const newSocket = mkSocket() - browser.reconnect(newSocket) + browser.reconnect(newSocket, true) expect(browser.isConnected()).to.equal(false) newSocket.emit('result', { success: false, suite: [], log: [] }) @@ -466,7 +471,7 @@ describe('Browser', () => { emitter.on('browser_register', () => browser.execute()) // reconnect on a new socket (which triggers re-execution) - browser.reconnect(newSocket) + browser.reconnect(newSocket, false) expect(browser.state).to.equal(Browser.STATE_CONFIGURING) newSocket.emit('start', { total: 11 }) expect(browser.state).to.equal(Browser.STATE_EXECUTING) @@ -487,13 +492,14 @@ describe('Browser', () => { expect(browser.state).to.equal(Browser.STATE_CONNECTED) browser.execute() + expect(browser.state).to.equal(Browser.STATE_CONFIGURING) // A second connection... const newSocket = mkSocket() - browser.reconnect(newSocket) + browser.reconnect(newSocket, true) // Disconnect the second connection... - browser.onDisconnect('socket.io-reason', newSocket) + browser.onSocketDisconnect('socket.io-reason', newSocket) expect(browser.state).to.equal(Browser.STATE_CONFIGURING) socket.emit('start', { total: 1 }) expect(browser.state).to.equal(Browser.STATE_EXECUTING) @@ -512,7 +518,7 @@ describe('Browser', () => { browser.execute() // A second connection... - browser.reconnect(socket) + browser.reconnect(socket, true) socket.emit('result', { success: true, suite: [], log: [] }) socket.emit('complete') diff --git a/test/unit/server.spec.js b/test/unit/server.spec.js index 8bfd39200..01121213e 100644 --- a/test/unit/server.spec.js +++ b/test/unit/server.spec.js @@ -45,7 +45,8 @@ describe('server', () => { singleRun: true, logLevel: 'OFF', plugins: [], - browserDisconnectTolerance: 0 + browserDisconnectTolerance: 0, + browserNoActivityTimeout: 0 } server = new Server(mockConfig, doneSpy) @@ -432,7 +433,7 @@ describe('server', () => { resolveExitCode(exitCode) }) - server.emit('browser_complete_with_no_more_retries', { id: 'fake' }) + server.emit('browser_complete_with_no_more_retries', { id: 'fake', remove: () => {} }) function mockProcess (process) { sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) @@ -449,7 +450,7 @@ describe('server', () => { resolveExitCode(exitCode) }) - server.emit('browser_complete_with_no_more_retries', { id: 'fake' }) + server.emit('browser_complete_with_no_more_retries', { id: 'fake', remove: () => {} }) function mockProcess (process) { sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) @@ -476,7 +477,7 @@ describe('server', () => { it('should re-configure disconnected browser which has been restarted', () => { const testBrowserId = 'my-id' const browser = new Browser(testBrowserId, 'Chrome 19.0', browserCollection, server, - mockBrowserSocket, null, 0) + mockBrowserSocket, undefined, 0, 0, true, {}) const registerFn = mockSocketEventListeners.get('register') browser.init() From 3fca456a02a65304d6423d6311fb55f83e73d85e Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 6 Jan 2021 22:00:33 +0200 Subject: [PATCH 286/374] fix(server): clean up close-server logic (#3607) The main change in behavior is the removal of `dieOnError` method. Previously Karma would send SIGINT to its own process and then trigger clean up logic upon receiving this signal. It is a pretty convoluted way to trigger shutdown. This commit extracts clean up logic into the `_close()` method and calls this method directly everywhere. This change solves two issues: - Makes life easier for other tools (like Angular CLI), which use Karma programmatically from another process and killing whole process on Karma error may not be the most convenient behavior. Instead Karma will clean up all its resources and notify caller using the `done` callback. - Allows to remove last Grunt bits in the future PR. When running unit tests without Grunt wrapper the SIGINT is received by the Mocha process, which stops tests execution midway. --- lib/server.js | 120 +++++++++++++++++++----------------- test/unit/server.spec.js | 127 +++++++++------------------------------ 2 files changed, 93 insertions(+), 154 deletions(-) diff --git a/lib/server.js b/lib/server.js index 804745088..ff03553eb 100644 --- a/lib/server.js +++ b/lib/server.js @@ -102,12 +102,6 @@ class Server extends KarmaEventEmitter { this._injector = new di.Injector(modules) } - dieOnError (error) { - this.log.error(error) - process.exitCode = 1 - process.kill(process.pid, 'SIGINT') - } - async start () { const config = this.get('config') try { @@ -122,7 +116,8 @@ class Server extends KarmaEventEmitter { config.port = this._boundServer.address().port await this._injector.invoke(this._start, this) } catch (err) { - this.dieOnError(`Server start failed on port ${config.port}: ${err}`) + this.log.error(`Server start failed on port ${config.port}: ${err}`) + this._close(1) } } @@ -187,7 +182,8 @@ class Server extends KarmaEventEmitter { let singleRunBrowserNotCaptured = false webServer.on('error', (err) => { - this.dieOnError(`Webserver fail ${err}`) + this.log.error(`Webserver fail ${err}`) + this._close(1) }) const afterPreprocess = () => { @@ -206,7 +202,8 @@ class Server extends KarmaEventEmitter { }) } if (this.loadErrors.length > 0) { - this.dieOnError(new Error(`Found ${this.loadErrors.length} load error${this.loadErrors.length === 1 ? '' : 's'}`)) + this.log.error(new Error(`Found ${this.loadErrors.length} load error${this.loadErrors.length === 1 ? '' : 's'}`)) + this._close(1) } }) } @@ -302,9 +299,9 @@ class Server extends KarmaEventEmitter { } }) - this.on('stop', function (done) { + this.on('stop', (done) => { this.log.debug('Received stop event, exiting.') - disconnectBrowsers() + this._close() done() }) @@ -332,9 +329,9 @@ class Server extends KarmaEventEmitter { emitRunCompleteIfAllBrowsersDone() }) - this.on('run_complete', function (browsers, results) { + this.on('run_complete', (browsers, results) => { this.log.debug('Run complete, exiting.') - disconnectBrowsers(results.exitCode) + this._close(results.exitCode) }) this.emit('run_start', singleRunBrowsers) @@ -350,52 +347,13 @@ class Server extends KarmaEventEmitter { }) } - const webServerCloseTimeout = 3000 - const disconnectBrowsers = (code) => { - const sockets = socketServer.sockets.sockets - - Object.keys(sockets).forEach((id) => { - const socket = sockets[id] - socket.removeAllListeners('disconnect') - if (!socket.disconnected) { - process.nextTick(socket.disconnect.bind(socket)) - } - }) - - this.emitExitAsync(code).catch((err) => { - this.log.error('Error while calling exit event listeners\n' + err.stack || err) - return 1 - }).then((code) => { - socketServer.sockets.removeAllListeners() - socketServer.close() - - let removeAllListenersDone = false - const removeAllListeners = () => { - if (removeAllListenersDone) { - return - } - removeAllListenersDone = true - webServer.removeAllListeners() - processWrapper.removeAllListeners() - done(code || 0) - } - - const closeTimeout = setTimeout(removeAllListeners, webServerCloseTimeout) - - webServer.close(() => { - clearTimeout(closeTimeout) - removeAllListeners() - }) - }) - } - - processWrapper.on('SIGINT', () => disconnectBrowsers(process.exitCode)) - processWrapper.on('SIGTERM', disconnectBrowsers) + processWrapper.on('SIGINT', () => this._close()) + processWrapper.on('SIGTERM', () => this._close()) const reportError = (error) => { - process.emit('infrastructure_error', error) - disconnectBrowsers(1) this.log.error(error) + process.emit('infrastructure_error', error) + this._close(1) } processWrapper.on('unhandledRejection', (error) => { @@ -429,6 +387,56 @@ class Server extends KarmaEventEmitter { child.unref() } + /** + * Cleanup all resources allocated by Karma and call the `done` callback + * with the result of the tests execution. + * + * @param [exitCode] - Optional exit code. If omitted will be computed by + * 'exit' event listeners. + */ + _close (exitCode) { + const webServer = this._injector.get('webServer') + const socketServer = this._injector.get('socketServer') + const done = this._injector.get('done') + + const webServerCloseTimeout = 3000 + const sockets = socketServer.sockets.sockets + + Object.keys(sockets).forEach((id) => { + const socket = sockets[id] + socket.removeAllListeners('disconnect') + if (!socket.disconnected) { + process.nextTick(socket.disconnect.bind(socket)) + } + }) + + this.emitExitAsync(exitCode).catch((err) => { + this.log.error('Error while calling exit event listeners\n' + err.stack || err) + return 1 + }).then((code) => { + socketServer.sockets.removeAllListeners() + socketServer.close() + + let removeAllListenersDone = false + const removeAllListeners = () => { + if (removeAllListenersDone) { + return + } + removeAllListenersDone = true + webServer.removeAllListeners() + processWrapper.removeAllListeners() + done(code || 0) + } + + const closeTimeout = setTimeout(removeAllListeners, webServerCloseTimeout) + + webServer.close(() => { + clearTimeout(closeTimeout) + removeAllListeners() + }) + }) + } + stop () { return this.emitAsync('stop') } diff --git a/test/unit/server.spec.js b/test/unit/server.spec.js index 01121213e..6523a709d 100644 --- a/test/unit/server.spec.js +++ b/test/unit/server.spec.js @@ -15,11 +15,11 @@ describe('server', () => { let mockSocketServer let mockBoundServer let mockExecutor - let doneSpy + let doneStub let logErrorSpy let server = mockConfig = browserCollection = webServerOnError = null let fileListOnResolve = fileListOnReject = mockLauncher = null - let mockFileList = mockWebServer = mockSocketServer = mockExecutor = doneSpy = null + let mockFileList = mockWebServer = mockSocketServer = mockExecutor = doneStub = null const mockSocketEventListeners = new Map() // Use regular function not arrow so 'this' is mocha 'this'. @@ -27,13 +27,11 @@ describe('server', () => { // The first call to new Server() loads plugins and it can take >2000ms. this.timeout(4000) browserCollection = new BrowserCollection() - doneSpy = sinon.spy() + doneStub = sinon.stub() logErrorSpy = sinon.spy(logger.create('karma-server'), 'error') fileListOnResolve = fileListOnReject = null - doneSpy = sinon.spy() - mockConfig = { frameworks: [], port: 9876, @@ -49,7 +47,7 @@ describe('server', () => { browserNoActivityTimeout: 0 } - server = new Server(mockConfig, doneSpy) + server = new Server(mockConfig, doneStub) sinon.stub(server._injector, 'invoke').returns([]) @@ -120,10 +118,10 @@ describe('server', () => { close: sinon.spy((callback) => callback && callback()) } - sinon - .stub(server._injector, 'get') - .withArgs('webServer').returns(mockWebServer) - .withArgs('socketServer').returns(mockSocketServer) + const injectorStub = sinon.stub(server._injector, 'get') + injectorStub.withArgs('socketServer').returns(mockSocketServer) + injectorStub.withArgs('webServer').returns(mockWebServer) + injectorStub.callThrough() webServerOnError = null }) @@ -185,7 +183,7 @@ describe('server', () => { }) it('should start the web server after all files have been preprocessed successfully', async () => { - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) expect(mockFileList.refresh).to.have.been.called expect(fileListOnResolve).not.to.be.null @@ -199,7 +197,7 @@ describe('server', () => { }) it('should start the web server after all files have been preprocessed with an error', async () => { - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) expect(mockFileList.refresh).to.have.been.called expect(fileListOnReject).not.to.be.null @@ -215,7 +213,7 @@ describe('server', () => { }) it('should launch browsers after the web server has started', async () => { - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) expect(mockWebServer.listen).not.to.have.been.called expect(webServerOnError).not.to.be.null @@ -227,7 +225,7 @@ describe('server', () => { }) it('should emit a listening event once server begin accepting connections', async () => { - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) const listening = sinon.spy() server.on('listening', listening) @@ -239,7 +237,7 @@ describe('server', () => { }) it('should emit a browsers_ready event once all the browsers are captured', async () => { - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) const browsersReady = sinon.spy() server.on('browsers_ready', browsersReady) @@ -254,7 +252,7 @@ describe('server', () => { }) it('should emit a browser_register event for each browser added', async () => { - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) const browsersReady = sinon.spy() server.on('browsers_ready', browsersReady) @@ -276,43 +274,28 @@ describe('server', () => { }) } - it('1 on load errors', async () => { - mockProcess(process) + beforeEach(() => { + doneStub.callsFake((exitCode) => resolveExitCode(exitCode)) + }) - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + it('1 on load errors', async () => { + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) server.loadErrors.push(['TestError', 'Test']) fileListOnResolve() - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } - expect(await exitCode()).to.have.equal(1) }) it('given on run_complete', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) server.emit('run_complete', browserCollection, { exitCode: 15 }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(15) }) it('given on run_complete with exit event listener (15)', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) // last non-zero exit code will be taken server.on('exit', (done) => { @@ -328,18 +311,11 @@ describe('server', () => { // Provided run_complete exitCode will be overridden by exit listeners server.emit('run_complete', browserCollection, { exitCode: 5 }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(15) }) it('given on run_complete with exit event listener (0)', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) // exit listeners can't set exit code back to 0 server.on('exit', (done) => { @@ -348,18 +324,11 @@ describe('server', () => { server.emit('run_complete', browserCollection, { exitCode: 15 }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(15) }) it('1 on run_complete with exit event listener throws', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) server.on('exit', (done) => { throw new Error('async error from exit event listener') @@ -367,18 +336,11 @@ describe('server', () => { server.emit('run_complete', browserCollection, { exitCode: 0 }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(1) }) it('1 on run_complete with exit event listener rejects', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) function onExit (done) { // Need to remove listener to prevent endless loop via unhandledRejection handler @@ -390,71 +352,40 @@ describe('server', () => { server.emit('run_complete', browserCollection, { exitCode: 0 }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(1) }) it('0 on server stop', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) server.stop() - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(0) }) it('1 on browser_process_failure (singleRunBrowserNotCaptured)', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) server.emit('browser_process_failure', { id: 'fake' }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(1) }) it('0 on browser_complete_with_no_more_retries', async () => { - mockProcess(process) - - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) server.emit('browser_complete_with_no_more_retries', { id: 'fake', remove: () => {} }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(0) }) it('1 on browser_complete_with_no_more_retries with config.failOnEmptyTestSuite', async () => { - mockProcess(process) - mockConfig.failOnEmptyTestSuite = true - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, (exitCode) => { - resolveExitCode(exitCode) - }) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) server.emit('browser_complete_with_no_more_retries', { id: 'fake', remove: () => {} }) - function mockProcess (process) { - sinon.stub(process, 'kill').callsFake((pid, ev) => process.emit(ev)) - } expect(await exitCode()).to.have.equal(1) }) }) @@ -465,7 +396,7 @@ describe('server', () => { beforeEach(async () => { browserCollection = new BrowserCollection(server) - await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneSpy) + await server._start(mockConfig, mockLauncher, null, mockFileList, browserCollection, mockExecutor, doneStub) mockBrowserSocket = { id: 'browser-socket-id', From fec972ff63760f9606a4cef7673a68c55c880722 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Tue, 12 Jan 2021 10:56:04 -0800 Subject: [PATCH 287/374] fix(middleware): catch errors when loading a module (#3605) Fix #3572 Co-authored-by: https://github.com/jehon --- lib/middleware/karma.js | 6 +++++- test/e2e/error.feature | 16 ++++++++++++++++ .../error/import-something-from-somewhere.js | 2 ++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/e2e/support/error/import-something-from-somewhere.js diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 4e27d4a52..3a34b4e58 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -191,7 +191,11 @@ function createKarmaMiddleware ( } else { const scriptType = (SCRIPT_TYPE[fileType] || 'text/javascript') const crossOriginAttribute = includeCrossOriginAttribute ? 'crossorigin="anonymous"' : '' - scriptTags.push(``) + if (fileType === 'module') { + scriptTags.push(``) + } else { + scriptTags.push(``) + } } } diff --git a/test/e2e/error.feature b/test/e2e/error.feature index 0b327110e..09236959a 100644 --- a/test/e2e/error.feature +++ b/test/e2e/error.feature @@ -40,3 +40,19 @@ Feature: Error Display """ SyntaxError: Unexpected token '}' """ + +Scenario: Missing module Error in a test file + Given a configuration with: + """ + files = [{pattern: 'error/import-something-from-somewhere.js', type: 'module'}]; + browsers = ['ChromeHeadlessNoSandbox']; + plugins = [ + 'karma-jasmine', + 'karma-chrome-launcher' + ]; + """ + When I start Karma + Then it fails with: + """ + Uncaught Error loading error/import-something-from-somewhere.js + """ diff --git a/test/e2e/support/error/import-something-from-somewhere.js b/test/e2e/support/error/import-something-from-somewhere.js new file mode 100644 index 000000000..1a56d4654 --- /dev/null +++ b/test/e2e/support/error/import-something-from-somewhere.js @@ -0,0 +1,2 @@ +import { something } from './somewhere.js' +console.log(something) From 68c4a3adf56ba826d93435f3090eba8aa12f9973 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Tue, 12 Jan 2021 22:58:55 +0400 Subject: [PATCH 288/374] chore(test): run client tests without grunt wrapper (#3604) --- appveyor.yml | 3 +- gruntfile.js | 19 ++--------- package-lock.json | 71 --------------------------------------- package.json | 6 ++-- tasks/test.js | 48 -------------------------- test/client/karma.conf.js | 6 ++-- 6 files changed, 9 insertions(+), 144 deletions(-) delete mode 100644 tasks/test.js diff --git a/appveyor.yml b/appveyor.yml index 7c696c011..c80d3b651 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -24,7 +24,8 @@ install: - npm run init:windows test_script: - - npm run test:appveyor + - npm run test:unit + - npm run test:client build: off diff --git a/gruntfile.js b/gruntfile.js index 377867d44..40da12beb 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -1,18 +1,5 @@ module.exports = function (grunt) { grunt.initConfig({ - pkg: grunt.file.readJSON('package.json'), - pkgFile: 'package.json', - files: { - server: ['lib/**/*.js'], - client: ['client/**/*.js'], - common: ['common/**/*.js'], - context: ['context/**/*.js'], - grunt: ['grunt.js', 'tasks/*.js'] - }, - test: { - unit: 'mochaTest:unit', - client: 'test/client/karma.conf.js' - }, mochaTest: { options: { reporter: 'dot', @@ -29,9 +16,7 @@ module.exports = function (grunt) { } }) - grunt.loadTasks('tasks') - require('load-grunt-tasks')(grunt) + grunt.loadNpmTasks('grunt-mocha-test') - grunt.registerTask('default', ['test']) - grunt.registerTask('test-appveyor', ['test:unit', 'test:client']) + grunt.registerTask('default', ['mochaTest:unit']) } diff --git a/package-lock.json b/package-lock.json index 7febbf37a..2f6a61d84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2599,12 +2599,6 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, "array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", @@ -2646,21 +2640,6 @@ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", "dev": true }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -7020,18 +6999,6 @@ "integrity": "sha1-e3QYm/rW52Nn+1oQ88NpExKLeCs=", "dev": true }, - "load-grunt-tasks": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-4.0.0.tgz", - "integrity": "sha512-w5JYPHpZgMxu9XFR9N9MEzyX8E0mLhQkwQ1qVP4mb3gmuomw8Ww8J49NHMbXqyQliq2LUCqdU7/wW96IVuPCKw==", - "dev": true, - "requires": { - "arrify": "^1.0.0", - "multimatch": "^2.0.0", - "pkg-up": "^2.0.0", - "resolve-pkg": "^1.0.0" - } - }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -7623,18 +7590,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, - "requires": { - "array-differ": "^1.0.0", - "array-union": "^1.0.1", - "arrify": "^1.0.0", - "minimatch": "^3.0.0" - } - }, "mz": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", @@ -11862,15 +11817,6 @@ "find-up": "^2.1.0" } }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, "please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -12293,23 +12239,6 @@ "global-dirs": "^0.1.1" } }, - "resolve-pkg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-1.0.0.tgz", - "integrity": "sha1-4ZoV54rKLhJEYdySsuOUPvk0lNk=", - "dev": true, - "requires": { - "resolve-from": "^2.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", - "dev": true - } - } - }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", diff --git a/package.json b/package.json index e350c7927..5a935dc42 100644 --- a/package.json +++ b/package.json @@ -461,7 +461,6 @@ "karma-mocha": "^1.0.1", "karma-mocha-reporter": "^2.0.0", "karma-script-launcher": "^1.0.0", - "load-grunt-tasks": "^4.0.0", "mkdirp": "^0.5.0", "mocha": "^4.1.0", "mocks": "^0.0.15", @@ -493,14 +492,13 @@ "scripts": { "lint": "eslint . --ext js --ignore-pattern *.tpl.js", "lint:fix": "eslint . --ext js --ignore-pattern *.tpl.js --fix", - "test:unit": "grunt test:unit", + "test:unit": "grunt", "test:e2e": "cucumber-js test/e2e/*.feature", - "test:client": "grunt test:client", + "test:client": "node bin/karma start test/client/karma.conf.js", "test": "npm run test:unit && npm run test:e2e && npm run test:client", "build": "node scripts/client.js build", "build:check": "node scripts/client.js check", "build:watch": "node scripts/client.js watch", - "test:appveyor": "grunt test-appveyor", "test:integration": "./scripts/integration-tests.sh", "link": "node --eval \"path=require('path'); require('fs').symlinkSync(path.resolve(__dirname), path.resolve(__dirname, 'node_modules', 'karma'), 'junction')\"", "unlink": "node --eval \"require('fs').unlinkSync(require('path').resolve(__dirname, 'node_modules', 'karma'))\"", diff --git a/tasks/test.js b/tasks/test.js deleted file mode 100644 index efbed1c15..000000000 --- a/tasks/test.js +++ /dev/null @@ -1,48 +0,0 @@ -module.exports = function (grunt) { - /** - * Run tests - * - * grunt test - * grunt test:unit - * grunt test:client - */ - grunt.registerMultiTask('test', 'Run tests.', function () { - const specDone = this.async() - const node = require('which').sync('node') - const path = require('path') - const cmd = path.join(__dirname, '..', 'bin', 'karma') - - function spawnKarma (args, callback) { - grunt.log.writeln(['Running', cmd].concat(args).join(' ')) - var child - if (process.platform === 'win32') { - child = grunt.util.spawn({ cmd: node, args: [cmd].concat(args) }, callback) - } else { - child = grunt.util.spawn({ cmd: cmd, args: args }, callback) - } - child.stdout.pipe(process.stdout) - child.stderr.pipe(process.stderr) - } - - function exec (args, failMsg) { - spawnKarma(args, function (err, result, code) { - if (code || err) { - console.error(err) - grunt.fail.fatal(failMsg, code) - } else { - specDone() - } - }) - } - - // CLIENT unit tests - if (this.target === 'client') { - return exec(['start', this.data, '--single-run', '--no-auto-watch', '--reporters=dots'], - 'Client unit tests failed.') - } - - // UNIT tests or TASK tests - grunt.task.run([this.data]) - specDone() - }) -} diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index eb16e4e0c..0700aad3d 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -102,7 +102,7 @@ module.exports = function (config) { // use dots reporter, as travis terminal does not support escaping sequences // possible values: 'dots', 'progress' // CLI --reporters progress - reporters: ['progress', 'junit'], + reporters: ['dots'], junitReporter: { // will be resolved to basePath (in the same way as files/exclude patterns) @@ -124,7 +124,7 @@ module.exports = function (config) { // enable / disable watching file and executing tests whenever any file changes // CLI --auto-watch --no-auto-watch - autoWatch: true, + autoWatch: false, // Start these browsers, currently available: // - Chrome @@ -149,7 +149,7 @@ module.exports = function (config) { // Auto run tests on start (when browsers are captured) and exit // CLI --single-run --no-single-run - singleRun: false, + singleRun: true, // report which specs are slower than 500ms // CLI --report-slower-than 500 From 4bf90f70f46cddf52a55d8f2b9ce0ccd2d4a4d3b Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 13 Jan 2021 08:48:03 -0800 Subject: [PATCH 289/374] feat(client): update banner with connection, test status, ping times (#3611) The banner is visible in videos so we can have some client side info on the state if it breaks. --- client/karma.js | 10 +++++- client/main.js | 4 +-- client/updater.js | 62 ++++++++++++++++++++++++-------- static/karma.js | 76 ++++++++++++++++++++++++++++++--------- test/client/karma.spec.js | 19 +++++++--- 5 files changed, 132 insertions(+), 39 deletions(-) diff --git a/client/karma.js b/client/karma.js index 0f1e05ede..0734822ff 100644 --- a/client/karma.js +++ b/client/karma.js @@ -2,7 +2,8 @@ var stringify = require('../common/stringify') var constant = require('./constants') var util = require('../common/util') -function Karma (socket, iframe, opener, navigator, location, document) { +function Karma (updater, socket, iframe, opener, navigator, location, document) { + this.updater = updater var startEmitted = false var karmaNavigating = false var self = this @@ -190,6 +191,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.emit('karma_error', message) + self.updater.updateTestStatus(`karma_error ${message}`) this.complete() return false } @@ -212,10 +214,12 @@ function Karma (socket, iframe, opener, navigator, location, document) { if (!startEmitted) { socket.emit('start', { total: null }) + self.updater.updateTestStatus('start') startEmitted = true } if (resultsBufferLimit === 1) { + self.updater.updateTestStatus('result') return socket.emit('result', convertedResult) } @@ -223,6 +227,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { if (resultsBuffer.length === resultsBufferLimit) { socket.emit('result', resultsBuffer) + self.updater.updateTestStatus('result') resultsBuffer = [] } } @@ -232,6 +237,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { socket.emit('result', resultsBuffer) resultsBuffer = [] } + // A test could have incorrectly issued a navigate. Wait one turn // to ensure the error from an incorrect navigate is processed. setTimeout(() => { @@ -240,6 +246,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.emit('complete', result || {}) + self.updater.updateTestStatus('complete') if (returnUrl) { location.href = returnUrl @@ -258,6 +265,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.on('execute', function (cfg) { + self.updater.updateTestStatus('execute') // reset startEmitted and reload the iframe startEmitted = false self.config = cfg diff --git a/client/main.js b/client/main.js index d07aa71af..8780d8768 100644 --- a/client/main.js +++ b/client/main.js @@ -20,6 +20,6 @@ var socket = io(location.host, { }) // instantiate the updater of the view -new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers')) -window.karma = new Karma(socket, util.elm('context'), window.open, +var updater = new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers')) +window.karma = new Karma(updater, socket, util.elm('context'), window.open, window.navigator, window.location, window.document) diff --git a/client/updater.js b/client/updater.js index d8a5cbff0..3365b5253 100644 --- a/client/updater.js +++ b/client/updater.js @@ -21,26 +21,60 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { } } - function updateBanner (status) { - return function (param) { - if (!titleElement || !bannerElement) { - return - } - var paramStatus = param ? status.replace('$', param) : status - titleElement.textContent = 'Karma v' + VERSION + ' - ' + paramStatus - bannerElement.className = status === 'connected' ? 'online' : 'offline' + var connectionText = 'never-connected' + var testText = 'loading' + var pingText = '' + + function updateBanner () { + if (!titleElement || !bannerElement) { + return } + titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}` + bannerElement.className = connectionText === 'connected' ? 'online' : 'offline' + } + + function updateConnectionStatus (connectionStatus) { + connectionText = connectionStatus || connectionText + updateBanner() } + function updateTestStatus (testStatus) { + testText = testStatus || testText + updateBanner() + } + function updatePingStatus (pingStatus) { + pingText = pingStatus || pingText + updateBanner() + } + + socket.on('connect', () => { + updateConnectionStatus('connected') + }) + socket.on('disconnect', () => { + updateConnectionStatus('disconnected') + }) + socket.on('reconnecting', (sec) => { + updateConnectionStatus(`reconnecting in ${sec} seconds`) + }) + socket.on('reconnect', () => { + updateConnectionStatus('reconnected') + }) + socket.on('reconnect_failed', () => { + updateConnectionStatus('reconnect_failed') + }) - socket.on('connect', updateBanner('connected')) - socket.on('disconnect', updateBanner('disconnected')) - socket.on('reconnecting', updateBanner('reconnecting in $ seconds...')) - socket.on('reconnect', updateBanner('connected')) - socket.on('reconnect_failed', updateBanner('failed to reconnect')) socket.on('info', updateBrowsersInfo) - socket.on('disconnect', function () { + socket.on('disconnect', () => { updateBrowsersInfo([]) }) + + socket.on('ping', () => { + updatePingStatus('ping...') + }) + socket.on('pong', (latency) => { + updatePingStatus(`ping ${latency}ms`) + }) + + return { updateTestStatus: updateTestStatus } } module.exports = StatusUpdater diff --git a/static/karma.js b/static/karma.js index 9a66d9f0d..8c08d3fca 100644 --- a/static/karma.js +++ b/static/karma.js @@ -12,7 +12,8 @@ var stringify = require('../common/stringify') var constant = require('./constants') var util = require('../common/util') -function Karma (socket, iframe, opener, navigator, location, document) { +function Karma (updater, socket, iframe, opener, navigator, location, document) { + this.updater = updater var startEmitted = false var karmaNavigating = false var self = this @@ -200,6 +201,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.emit('karma_error', message) + self.updater.updateTestStatus(`karma_error ${message}`) this.complete() return false } @@ -222,10 +224,12 @@ function Karma (socket, iframe, opener, navigator, location, document) { if (!startEmitted) { socket.emit('start', { total: null }) + self.updater.updateTestStatus('start') startEmitted = true } if (resultsBufferLimit === 1) { + self.updater.updateTestStatus('result') return socket.emit('result', convertedResult) } @@ -233,6 +237,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { if (resultsBuffer.length === resultsBufferLimit) { socket.emit('result', resultsBuffer) + self.updater.updateTestStatus('result') resultsBuffer = [] } } @@ -242,6 +247,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { socket.emit('result', resultsBuffer) resultsBuffer = [] } + // A test could have incorrectly issued a navigate. Wait one turn // to ensure the error from an incorrect navigate is processed. setTimeout(() => { @@ -250,6 +256,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.emit('complete', result || {}) + self.updater.updateTestStatus('complete') if (returnUrl) { location.href = returnUrl @@ -268,6 +275,7 @@ function Karma (socket, iframe, opener, navigator, location, document) { } socket.on('execute', function (cfg) { + self.updater.updateTestStatus('execute') // reset startEmitted and reload the iframe startEmitted = false self.config = cfg @@ -340,8 +348,8 @@ var socket = io(location.host, { }) // instantiate the updater of the view -new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers')) -window.karma = new Karma(socket, util.elm('context'), window.open, +var updater = new StatusUpdater(socket, util.elm('title'), util.elm('banner'), util.elm('browsers')) +window.karma = new Karma(updater, socket, util.elm('context'), window.open, window.navigator, window.location, window.document) },{"../common/util":6,"./constants":1,"./karma":2,"./updater":4}],4:[function(require,module,exports){ @@ -368,26 +376,60 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { } } - function updateBanner (status) { - return function (param) { - if (!titleElement || !bannerElement) { - return - } - var paramStatus = param ? status.replace('$', param) : status - titleElement.textContent = 'Karma v' + VERSION + ' - ' + paramStatus - bannerElement.className = status === 'connected' ? 'online' : 'offline' + var connectionText = 'never-connected' + var testText = 'loading' + var pingText = '' + + function updateBanner () { + if (!titleElement || !bannerElement) { + return } + titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}` + bannerElement.className = connectionText === 'connected' ? 'online' : 'offline' } - socket.on('connect', updateBanner('connected')) - socket.on('disconnect', updateBanner('disconnected')) - socket.on('reconnecting', updateBanner('reconnecting in $ seconds...')) - socket.on('reconnect', updateBanner('connected')) - socket.on('reconnect_failed', updateBanner('failed to reconnect')) + function updateConnectionStatus (connectionStatus) { + connectionText = connectionStatus || connectionText + updateBanner() + } + function updateTestStatus (testStatus) { + testText = testStatus || testText + updateBanner() + } + function updatePingStatus (pingStatus) { + pingText = pingStatus || pingText + updateBanner() + } + + socket.on('connect', () => { + updateConnectionStatus('connected') + }) + socket.on('disconnect', () => { + updateConnectionStatus('disconnected') + }) + socket.on('reconnecting', (sec) => { + updateConnectionStatus(`reconnecting in ${sec} seconds`) + }) + socket.on('reconnect', () => { + updateConnectionStatus('reconnected') + }) + socket.on('reconnect_failed', () => { + updateConnectionStatus('reconnect_failed') + }) + socket.on('info', updateBrowsersInfo) - socket.on('disconnect', function () { + socket.on('disconnect', () => { updateBrowsersInfo([]) }) + + socket.on('ping', () => { + updatePingStatus('ping...') + }) + socket.on('pong', (latency) => { + updatePingStatus(`ping ${latency}ms`) + }) + + return { updateTestStatus: updateTestStatus } } module.exports = StatusUpdater diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index 21966464f..b1c50a00a 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -6,8 +6,8 @@ var ContextKarma = require('../../context/karma') var MockSocket = require('./mocks').Socket describe('Karma', function () { - var socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow - var windowDocument, elements + var updater, socket, k, ck, windowNavigator, windowLocation, windowStub, startSpy, iframe, clientWindow + var windowDocument, elements, mockTestStatus function setTransportTo (transportName) { socket._setTransportNameTo(transportName) @@ -15,6 +15,12 @@ describe('Karma', function () { } beforeEach(function () { + mockTestStatus = '' + updater = { + updateTestStatus: (s) => { + mockTestStatus = s + } + } socket = new MockSocket() iframe = {} windowNavigator = {} @@ -23,7 +29,7 @@ describe('Karma', function () { elements = [{ style: {} }, { style: {} }] windowDocument = { querySelectorAll: sinon.stub().returns(elements) } - k = new ClientKarma(socket, iframe, windowStub, windowNavigator, windowLocation, windowDocument) + k = new ClientKarma(updater, socket, iframe, windowStub, windowNavigator, windowLocation, windowDocument) clientWindow = { karma: k } @@ -217,7 +223,7 @@ describe('Karma', function () { it('should report browser id', function () { windowLocation.search = '?id=567' socket = new MockSocket() - k = new ClientKarma(socket, {}, windowStub, windowNavigator, windowLocation) + k = new ClientKarma(updater, socket, {}, windowStub, windowNavigator, windowLocation) var spyInfo = sinon.spy(function (info) { assert(info.id === '567') @@ -439,7 +445,7 @@ describe('Karma', function () { it('should navigate the client to return_url if specified', function (done) { windowLocation.search = '?id=567&return_url=http://return.com' socket = new MockSocket() - k = new ClientKarma(socket, iframe, windowStub, windowNavigator, windowLocation) + k = new ClientKarma(updater, socket, iframe, windowStub, windowNavigator, windowLocation) clientWindow = { karma: k } ck = new ContextKarma(ContextKarma.getDirectCallParentKarmaMethod(clientWindow)) ck.config = {} @@ -479,11 +485,14 @@ describe('Karma', function () { } socket.emit('execute', config) + assert(mockTestStatus === 'execute') + clock.tick(1) var CURRENT_URL = iframe.src ck.complete() clock.tick(1) assert.strictEqual(iframe.src, CURRENT_URL) + assert(mockTestStatus === 'complete') }) it('should accept multiple calls to loaded', function () { From 04a811dc7a4b37aa56c0405880f03cb2493bf820 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 13 Jan 2021 08:52:10 -0800 Subject: [PATCH 290/374] fix(ci): abandon browserstack tests for Safari and IE (#3615) Run test:client on Chrome for both travis and not travis. --- test/client/karma.conf.js | 66 ++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 35 deletions(-) diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index 0700aad3d..0b1281d78 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -14,35 +14,35 @@ const launchers = { browser: 'firefox', os: 'Windows', os_version: '10' - }, - bs_safari: { - base: 'BrowserStack', - browser: 'safari', - browser_version: '9.0', - os_version: 'El Capitan', - os: 'OS X' - }, - bs_ie_11: { - base: 'BrowserStack', - browser: 'ie', - browser_version: '11.0', - os: 'Windows', - os_version: '10' - }, - bs_ie_10: { - base: 'BrowserStack', - browser: 'ie', - browser_version: '10.0', - os: 'Windows', - os_version: '8' - }, - bs_ie_9: { - base: 'BrowserStack', - browser: 'ie', - browser_version: '9.0', - os: 'Windows', - os_version: '7' } + // bs_safari: { + // base: 'BrowserStack', + // browser: 'safari', + // browser_version: '9.0', + // os_version: 'El Capitan', + // os: 'OS X' + // }, + // bs_ie_11: { + // base: 'BrowserStack', + // browser: 'ie', + // browser_version: '11.0', + // os: 'Windows', + // os_version: '10' + // }, + // bs_ie_10: { + // base: 'BrowserStack', + // browser: 'ie', + // browser_version: '10.0', + // os: 'Windows', + // os_version: '8' + // }, + // bs_ie_9: { + // base: 'BrowserStack', + // browser: 'ie', + // browser_version: '9.0', + // os: 'Windows', + // os_version: '7' + // } } // Verify the install. This will run async but that's ok we'll see the log. @@ -57,26 +57,22 @@ fs.lstat('node_modules/karma', (err, stats) => { console.log('**** Incorrect directory layout for karma self-tests ****') console.log(` $ npm install - + $ npm run init # or if you're on Windows $ npm run init:windows - + $ npm run build `) process.exit(1) }) -let browsers = [] +let browsers = ['Chrome'] if (process.env.TRAVIS) { if (TRAVIS_WITH_BS) { browsers = Object.keys(launchers) - } else { - browsers.push('Firefox') } -} else { - browsers.push('Chrome') } module.exports = function (config) { From 3653caf54502a524350359f193cef74eb21a6a85 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 13 Jan 2021 17:46:00 +0000 Subject: [PATCH 291/374] chore(release): 6.0.0 [skip ci] # [6.0.0](https://github.com/karma-runner/karma/compare/v5.2.3...v6.0.0) (2021-01-13) ### Bug Fixes * **ci:** abandon browserstack tests for Safari and IE ([#3615](https://github.com/karma-runner/karma/issues/3615)) ([04a811d](https://github.com/karma-runner/karma/commit/04a811dc7a4b37aa56c0405880f03cb2493bf820)) * **client:** do not reset karmaNavigating in unload handler ([#3591](https://github.com/karma-runner/karma/issues/3591)) ([4a8178f](https://github.com/karma-runner/karma/commit/4a8178f3a0504ef007b23ef0fd8f5ca128f0c5c6)), closes [#3482](https://github.com/karma-runner/karma/issues/3482) * **context:** do not error when karma is navigating ([#3565](https://github.com/karma-runner/karma/issues/3565)) ([05dc288](https://github.com/karma-runner/karma/commit/05dc28801627e3ce7054ae548046714dc2cf7a5e)), closes [#3560](https://github.com/karma-runner/karma/issues/3560) * **cve:** update ua-parser-js to 0.7.23 to fix CVE-2020-7793 ([#3584](https://github.com/karma-runner/karma/issues/3584)) ([f819fa8](https://github.com/karma-runner/karma/commit/f819fa843fa0633edbe2af6ac2889e25ea2cb639)) * **cve:** update yargs to 16.1.1 to fix cve-2020-7774 in y18n ([#3578](https://github.com/karma-runner/karma/issues/3578)) ([3fed0bc](https://github.com/karma-runner/karma/commit/3fed0bc7dd042a09c8aec55c059654781a4584ec)), closes [#3577](https://github.com/karma-runner/karma/issues/3577) * **deps:** bump socket-io to v3 ([#3586](https://github.com/karma-runner/karma/issues/3586)) ([1b9e1de](https://github.com/karma-runner/karma/commit/1b9e1de7d081e1c205debff27c6b5e1fe0585dee)), closes [#3569](https://github.com/karma-runner/karma/issues/3569) * **middleware:** catch errors when loading a module ([#3605](https://github.com/karma-runner/karma/issues/3605)) ([fec972f](https://github.com/karma-runner/karma/commit/fec972ff63760f9606a4cef7673a68c55c880722)), closes [#3572](https://github.com/karma-runner/karma/issues/3572) * **server:** clean up close-server logic ([#3607](https://github.com/karma-runner/karma/issues/3607)) ([3fca456](https://github.com/karma-runner/karma/commit/3fca456a02a65304d6423d6311fb55f83e73d85e)) * **test:** clear up clearContext ([#3597](https://github.com/karma-runner/karma/issues/3597)) ([8997b74](https://github.com/karma-runner/karma/commit/8997b7465de3c5f7e436078b57acae98de1ce39a)) * **test:** mark all second connections reconnects ([#3598](https://github.com/karma-runner/karma/issues/3598)) ([1c9c2de](https://github.com/karma-runner/karma/commit/1c9c2de54fa1abcb2c0edceebb159440b77e4863)) ### Features * **cli:** error out on unexpected options or parameters ([#3589](https://github.com/karma-runner/karma/issues/3589)) ([603bbc0](https://github.com/karma-runner/karma/commit/603bbc0db2ef4e6b8474f97a8255587f2a5f924e)) * **client:** update banner with connection, test status, ping times ([#3611](https://github.com/karma-runner/karma/issues/3611)) ([4bf90f7](https://github.com/karma-runner/karma/commit/4bf90f70f46cddf52a55d8f2b9ce0ccd2d4a4d3b)) * **server:** print stack of unhandledrejections ([#3593](https://github.com/karma-runner/karma/issues/3593)) ([35a5842](https://github.com/karma-runner/karma/commit/35a584234b00297dc511300bb6e42eeaceac8345)) * **server:** remove deprecated static methods ([#3595](https://github.com/karma-runner/karma/issues/3595)) ([1a65bf1](https://github.com/karma-runner/karma/commit/1a65bf1181bc9eb5c28ba0130ab7d90e89b21918)) * remove support for running dart code in the browser ([#3592](https://github.com/karma-runner/karma/issues/3592)) ([7a3bd55](https://github.com/karma-runner/karma/commit/7a3bd5545fa1307c754419252fa35ff0b7572ae4)) ### BREAKING CHANGES * **server:** Deprecated `require('karma').server.start()` and `require('karma').Server.start()` variants were removed from the public API. Instead use canonical form: ``` const { Server } = require('karma'); const server = new Server(); server.start(); ``` * **cli:** Karma is more strict and will error out if unknown option or argument is passed to CLI. * Using Karma to run Dart code in the browser is no longer supported. Use your favorite Dart-to-JS compiler instead. `dart` file type has been removed without a replacement. `customFileHandlers` DI token has been removed. Use [`middleware`](http://karma-runner.github.io/5.2/config/configuration-file.html#middleware) to achieve similar functionality. `customScriptTypes` DI token has been removed. It had no effect, so no replacement is provided. * **deps:** Some projects have socket.io tests that are version sensitive. --- CHANGELOG.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 2 +- package.json | 6 +++++- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43738ff94..1556bc8d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,48 @@ +# [6.0.0](https://github.com/karma-runner/karma/compare/v5.2.3...v6.0.0) (2021-01-13) + + +### Bug Fixes + +* **ci:** abandon browserstack tests for Safari and IE ([#3615](https://github.com/karma-runner/karma/issues/3615)) ([04a811d](https://github.com/karma-runner/karma/commit/04a811dc7a4b37aa56c0405880f03cb2493bf820)) +* **client:** do not reset karmaNavigating in unload handler ([#3591](https://github.com/karma-runner/karma/issues/3591)) ([4a8178f](https://github.com/karma-runner/karma/commit/4a8178f3a0504ef007b23ef0fd8f5ca128f0c5c6)), closes [#3482](https://github.com/karma-runner/karma/issues/3482) +* **context:** do not error when karma is navigating ([#3565](https://github.com/karma-runner/karma/issues/3565)) ([05dc288](https://github.com/karma-runner/karma/commit/05dc28801627e3ce7054ae548046714dc2cf7a5e)), closes [#3560](https://github.com/karma-runner/karma/issues/3560) +* **cve:** update ua-parser-js to 0.7.23 to fix CVE-2020-7793 ([#3584](https://github.com/karma-runner/karma/issues/3584)) ([f819fa8](https://github.com/karma-runner/karma/commit/f819fa843fa0633edbe2af6ac2889e25ea2cb639)) +* **cve:** update yargs to 16.1.1 to fix cve-2020-7774 in y18n ([#3578](https://github.com/karma-runner/karma/issues/3578)) ([3fed0bc](https://github.com/karma-runner/karma/commit/3fed0bc7dd042a09c8aec55c059654781a4584ec)), closes [#3577](https://github.com/karma-runner/karma/issues/3577) +* **deps:** bump socket-io to v3 ([#3586](https://github.com/karma-runner/karma/issues/3586)) ([1b9e1de](https://github.com/karma-runner/karma/commit/1b9e1de7d081e1c205debff27c6b5e1fe0585dee)), closes [#3569](https://github.com/karma-runner/karma/issues/3569) +* **middleware:** catch errors when loading a module ([#3605](https://github.com/karma-runner/karma/issues/3605)) ([fec972f](https://github.com/karma-runner/karma/commit/fec972ff63760f9606a4cef7673a68c55c880722)), closes [#3572](https://github.com/karma-runner/karma/issues/3572) +* **server:** clean up close-server logic ([#3607](https://github.com/karma-runner/karma/issues/3607)) ([3fca456](https://github.com/karma-runner/karma/commit/3fca456a02a65304d6423d6311fb55f83e73d85e)) +* **test:** clear up clearContext ([#3597](https://github.com/karma-runner/karma/issues/3597)) ([8997b74](https://github.com/karma-runner/karma/commit/8997b7465de3c5f7e436078b57acae98de1ce39a)) +* **test:** mark all second connections reconnects ([#3598](https://github.com/karma-runner/karma/issues/3598)) ([1c9c2de](https://github.com/karma-runner/karma/commit/1c9c2de54fa1abcb2c0edceebb159440b77e4863)) + + +### Features + +* **cli:** error out on unexpected options or parameters ([#3589](https://github.com/karma-runner/karma/issues/3589)) ([603bbc0](https://github.com/karma-runner/karma/commit/603bbc0db2ef4e6b8474f97a8255587f2a5f924e)) +* **client:** update banner with connection, test status, ping times ([#3611](https://github.com/karma-runner/karma/issues/3611)) ([4bf90f7](https://github.com/karma-runner/karma/commit/4bf90f70f46cddf52a55d8f2b9ce0ccd2d4a4d3b)) +* **server:** print stack of unhandledrejections ([#3593](https://github.com/karma-runner/karma/issues/3593)) ([35a5842](https://github.com/karma-runner/karma/commit/35a584234b00297dc511300bb6e42eeaceac8345)) +* **server:** remove deprecated static methods ([#3595](https://github.com/karma-runner/karma/issues/3595)) ([1a65bf1](https://github.com/karma-runner/karma/commit/1a65bf1181bc9eb5c28ba0130ab7d90e89b21918)) +* remove support for running dart code in the browser ([#3592](https://github.com/karma-runner/karma/issues/3592)) ([7a3bd55](https://github.com/karma-runner/karma/commit/7a3bd5545fa1307c754419252fa35ff0b7572ae4)) + + +### BREAKING CHANGES + +* **server:** Deprecated `require('karma').server.start()` and `require('karma').Server.start()` variants were removed from the public API. Instead use canonical form: + +``` +const { Server } = require('karma'); +const server = new Server(); +server.start(); +``` +* **cli:** Karma is more strict and will error out if unknown option or argument is passed to CLI. +* Using Karma to run Dart code in the browser is no longer supported. Use your favorite Dart-to-JS compiler instead. + +`dart` file type has been removed without a replacement. + +`customFileHandlers` DI token has been removed. Use [`middleware`](http://karma-runner.github.io/5.2/config/configuration-file.html#middleware) to achieve similar functionality. + +`customScriptTypes` DI token has been removed. It had no effect, so no replacement is provided. +* **deps:** Some projects have socket.io tests that are version sensitive. + ## [5.2.3](https://github.com/karma-runner/karma/compare/v5.2.2...v5.2.3) (2020-09-25) diff --git a/package-lock.json b/package-lock.json index 2f6a61d84..b92a4b0a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "5.2.3", + "version": "6.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5a935dc42..9fdce2cad 100644 --- a/package.json +++ b/package.json @@ -124,6 +124,7 @@ "Steve Mao ", "Steve Van Opstal ", "Sylvain Hamel ", + "SymbioticKilla <59652865+SymbioticKilla@users.noreply.github.com>", "Terry ", "Thomas Parisot ", "Tom Erik Støwer ", @@ -152,6 +153,7 @@ "Andrey Chalkin ", "Andy Joslin ", "Anton Usmansky ", + "Athur Ming ", "Atul Bhosale ", "AugustinLF ", "AvnerCohen ", @@ -237,6 +239,7 @@ "Jon Bretman ", "Jonathan ES Lin ", "Jonathan Felchlin ", + "Jonathan Ginsburg ", "Jonathan Niles ", "Josh Lory ", "João Marcos Duarte ", @@ -266,6 +269,7 @@ "Martin Jul ", "Martin Lemanski ", "Martin Probst ", + "Marvin Heilemann ", "Matias Niemelä ", "Matthew Amato ", "Matthew Cale ", @@ -481,7 +485,7 @@ "engines": { "node": ">= 10" }, - "version": "5.2.3", + "version": "6.0.0", "license": "MIT", "husky": { "hooks": { From 07edde41ec3d129818ab6a6f80e80a4d6b9dddfe Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 20 Jan 2021 01:57:13 +0100 Subject: [PATCH 292/374] docs: document how to load files from another server (#3622) Fixes #1486 --- docs/config/02-files.md | 62 ++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/docs/config/02-files.md b/docs/config/02-files.md index f85c4d772..aac9304e0 100644 --- a/docs/config/02-files.md +++ b/docs/config/02-files.md @@ -1,28 +1,14 @@ -**The `files` array determines which files are included in the browser and which files are watched and served by Karma.** +The `files` array determines which files are included in the browser, watched, and served by Karma. - -## Pattern matching and `basePath` -- All of the relative patterns will get resolved using the `basePath` first. -- If the `basePath` is a relative path, it gets resolved to the - directory where the configuration file is located. -- Eventually, all the patterns will get resolved into files using - [glob], so you can use [minimatch] expressions like `test/unit/**/*.spec.js`. - - -## Ordering -- The order of patterns determines the order in which files are included in the browser. -- Multiple files matching a single pattern are sorted alphabetically. -- Each file is included exactly once. If multiple patterns match the - same file, it's included as if it only matched the first pattern. - - -## Included, served, watched -Each pattern is either a simple string or an object with the following properties: +## `files` +**Type.** Array +**No Default.** This property is mandatory. +**Description.** Each item is either a string (equivalent to `{ pattern: "" }`) or an object with the following properties: ### `pattern` * **Type.** String * **No Default.** This property is mandatory. -* **Description.** The pattern to use for matching. +* **Description.** The pattern to use for matching. See below for details on how patterns are resolved. ### `type` * **Type.** String @@ -68,6 +54,18 @@ Each pattern is either a simple string or an object with the following propertie * **Default.** `false` * **Description.** Should the files be served from disk on each request by Karma's webserver? +## Pattern matching and `basePath` +- All of the relative patterns will get resolved using the `basePath` first. +- If the `basePath` is a relative path, it gets resolved to the + directory where the configuration file is located. +- Eventually, all the patterns will get resolved into files using + [glob], so you can use [minimatch] expressions like `test/unit/**/*.spec.js`. + +## Ordering +- The order of patterns determines the order in which files are included in the browser. +- Multiple files matching a single pattern are sorted alphabetically. +- Each file is included exactly once. If multiple patterns match the + same file, it's included as if it only matched the first pattern. ## Preprocessor transformations Depending on preprocessor configuration, be aware that files loaded may be transformed and no longer available in @@ -100,6 +98,30 @@ files: [ ], ``` +## Loading files from another server + +Pattern can also be an absolute URL. This allows including files which are not served by Karma. + +Example: + +```javascript +config.set({ + files: [ + 'https://example.com/my-lib.js', + { pattern: 'https://example.com/my-lib', type: 'js' } + ] +}) +``` + +Absolute URLs have some special rules comparing to the regular file paths: + +- Globing is not support, so each URL must be specified as a separate pattern. +- Most of the regular options are not supported: + - `watched` is always `false` + - `included` is always `true` + - `served` is always `false` + - `nocache` is always `false` + ## Loading Assets By default all assets are served at `http://localhost:[PORT]/base/` From 25d9abb76929b6ea8abe1cf040ba6db2f269d50e Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 20 Jan 2021 18:45:25 +0100 Subject: [PATCH 293/374] fix: restore `customFileHandlers` provider (#3624) The removal of `customFileHandlers` turned out to be more disruptive change than anticipated as this provider is still used by several popular plugins: https://github.com/karma-runner/karma/issues/3619, https://github.com/ryanclark/karma-webpack/issues/462, https://github.com/angular/angular-cli/issues/19815. Hence we restore the provider and print a deprecation warning to make upgrading easier. This should give more time for the plugin authors to release new versions and users to adopt these versions. --- lib/server.js | 2 ++ lib/web-server.js | 21 +++++++++++++++++++++ test/unit/web-server.spec.js | 24 +++++++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index ff03553eb..8b7823e43 100644 --- a/lib/server.js +++ b/lib/server.js @@ -82,6 +82,8 @@ class Server extends KarmaEventEmitter { filesPromise: ['factory', createFilesPromise], socketServer: ['factory', createSocketIoServer], executor: ['factory', Executor.factory], + // TODO: Deprecated. Remove in the next major + customFileHandlers: ['value', []], reporter: ['factory', reporter.createReporters], capturedBrowsers: ['factory', BrowserCollection.factory], args: ['value', {}], diff --git a/lib/web-server.js b/lib/web-server.js index 379818435..394066b7b 100644 --- a/lib/web-server.js +++ b/lib/web-server.js @@ -16,6 +16,25 @@ const proxyMiddleware = require('./middleware/proxy') const log = require('./logger').create('web-server') +function createCustomHandler (customFileHandlers, config) { + let warningDone = false + + return function (request, response, next) { + const handler = customFileHandlers.find((handler) => handler.urlRegex.test(request.url)) + + if (customFileHandlers.length > 0 && !warningDone) { + warningDone = true + log.warn('The `customFileHandlers` is deprecated and will be removed in Karma 7. Please upgrade plugins relying on this provider.') + } + + return handler + ? handler.handler(request, response, 'fake/static', 'fake/adapter', config.basePath, 'fake/root') + : next() + } +} + +createCustomHandler.$inject = ['customFileHandlers', 'config'] + function createFilesPromise (emitter, fileList) { // Set an empty list of files to avoid race issues with // file_list_modified not having been emitted yet @@ -58,6 +77,8 @@ function createWebServer (injector, config) { handler.use(injector.invoke(sourceFilesMiddleware.create)) // TODO(vojta): extract the proxy into a plugin handler.use(proxyMiddlewareInstance) + // TODO: Deprecated. Remove in the next major + handler.use(injector.invoke(createCustomHandler)) if (config.middleware) { config.middleware.forEach((middleware) => handler.use(injector.get('middleware:' + middleware))) diff --git a/test/unit/web-server.spec.js b/test/unit/web-server.spec.js index 8517f172e..fccf57b65 100644 --- a/test/unit/web-server.spec.js +++ b/test/unit/web-server.spec.js @@ -31,7 +31,7 @@ describe('web-server', () => { // NOTE(vojta): only loading once, to speed things up // this relies on the fact that none of these tests mutate fs const m = mocks.loadFile(path.join(__dirname, '/../../lib/web-server.js'), _mocks, _globals) - server = emitter = null + let customFileHandlers = server = emitter = null let beforeMiddlewareActive = false let middlewareActive = false const servedFiles = (files) => { @@ -40,6 +40,7 @@ describe('web-server', () => { describe('request', () => { beforeEach(() => { + customFileHandlers = [] emitter = new EventEmitter() const config = { basePath: '/base/path', @@ -56,6 +57,7 @@ describe('web-server', () => { const injector = new di.Injector([{ config: ['value', config], + customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], @@ -180,6 +182,22 @@ describe('web-server', () => { }) }) + it('should load custom handlers', () => { + servedFiles(new Set()) + + customFileHandlers.push({ + urlRegex: /\/some\/weird/, + handler (request, response, staticFolder, adapterFolder, baseFolder, urlRoot) { + response.writeHead(222) + response.end('CONTENT') + } + }) + + return request(server) + .get('/some/weird/url') + .expect(222, 'CONTENT') + }) + it('should serve 404 for non-existing files', () => { servedFiles(new Set()) @@ -196,6 +214,7 @@ describe('web-server', () => { cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } + customFileHandlers = [] emitter = new EventEmitter() const injector = new di.Injector([{ @@ -206,6 +225,7 @@ describe('web-server', () => { httpsServerOptions: credentials, client: { useIframe: true, useSingleWindow: false } }], + customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], @@ -244,10 +264,12 @@ describe('web-server', () => { cert: fs.readFileSync(path.join(__dirname, '/certificates/server.crt')) } + customFileHandlers = [] emitter = new EventEmitter() const injector = new di.Injector([{ config: ['value', { basePath: '/base/path', urlRoot: '/', httpModule: http2, protocol: 'https:', httpsServerOptions: credentials }], + customFileHandlers: ['value', customFileHandlers], emitter: ['value', emitter], fileList: ['value', { files: { served: [], included: [] } }], filesPromise: ['factory', m.createFilesPromise], From 69baddc843e4852a6770bfc1212fc2bce1f38fe7 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 20 Jan 2021 09:45:44 -0800 Subject: [PATCH 294/374] fix(server): set maxHttpBufferSize to the socket.io v2 default (#3626) Fixes #3621 --- lib/server.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/server.js b/lib/server.js index 8b7823e43..0cf94ce97 100644 --- a/lib/server.js +++ b/lib/server.js @@ -43,7 +43,9 @@ function createSocketIoServer (webServer, executor, config) { transports: config.transports, forceJSONP: config.forceJSONP, // Default is 5000 in socket.io v2.x and v3.x. - pingTimeout: config.pingTimeout || 5000 + pingTimeout: config.pingTimeout || 5000, + // Default in v2 is 1e8 and coverage results can fail at 1e6 + maxHttpBufferSize: 1e8 }) // hack to overcome circular dependency From b29fa10db0fb994f7d7016e2d39edfbb421c5060 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 20 Jan 2021 18:53:36 +0100 Subject: [PATCH 295/374] chore(test): run unit tests without grunt wrapper (#3618) --- gruntfile.js | 22 --- package-lock.json | 494 ---------------------------------------------- package.json | 5 +- test/mocha.opts | 3 + 4 files changed, 4 insertions(+), 520 deletions(-) delete mode 100644 gruntfile.js create mode 100644 test/mocha.opts diff --git a/gruntfile.js b/gruntfile.js deleted file mode 100644 index 40da12beb..000000000 --- a/gruntfile.js +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = function (grunt) { - grunt.initConfig({ - mochaTest: { - options: { - reporter: 'dot', - ui: 'bdd', - quiet: false, - colors: true - }, - unit: { - src: [ - 'test/unit/mocha-globals.js', - 'test/unit/**/*.spec.js' - ] - } - } - }) - - grunt.loadNpmTasks('grunt-mocha-test') - - grunt.registerTask('default', ['mochaTest:unit']) -} diff --git a/package-lock.json b/package-lock.json index b92a4b0a0..69090efe4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2416,12 +2416,6 @@ "through": ">=2.2.7 <3" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -2599,12 +2593,6 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", @@ -2634,12 +2622,6 @@ "is-string": "^1.0.5" } }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -4164,12 +4146,6 @@ "minimalistic-assert": "^1.0.0" } }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, "detective": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", @@ -4912,12 +4888,6 @@ } } }, - "eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - }, "eventemitter3": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", @@ -5021,12 +4991,6 @@ } } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -5062,15 +5026,6 @@ } } }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "ext": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", @@ -5357,49 +5312,6 @@ } } }, - "findup-sync": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", - "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", - "dev": true, - "requires": { - "glob": "~5.0.0" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -5457,15 +5369,6 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "form-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.0.tgz", @@ -5582,12 +5485,6 @@ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true }, - "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", - "dev": true - }, "gherkin": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/gherkin/-/gherkin-5.0.0.tgz", @@ -5649,30 +5546,6 @@ "ini": "^1.3.4" } }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", @@ -5731,147 +5604,6 @@ "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, - "grunt": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.2.1.tgz", - "integrity": "sha512-zgJjn9N56tScvRt/y0+1QA+zDBnKTrkpyeSBqQPLcZvbqTD/oyGMrdZQXmm6I3828s+FmPvxc3Xv+lgKFtudOw==", - "dev": true, - "requires": { - "dateformat": "~3.0.3", - "eventemitter2": "~0.4.13", - "exit": "~0.1.2", - "findup-sync": "~0.3.0", - "glob": "~7.1.6", - "grunt-cli": "~1.3.2", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", - "iconv-lite": "~0.4.13", - "js-yaml": "~3.14.0", - "minimatch": "~3.0.4", - "mkdirp": "~1.0.4", - "nopt": "~3.0.6", - "rimraf": "~3.0.2" - }, - "dependencies": { - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "js-yaml": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", - "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "grunt-cli": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.3.2.tgz", - "integrity": "sha512-8OHDiZZkcptxVXtMfDxJvmN7MVJNE8L/yIcPb4HB7TlyFD1kDvjHrb62uhySsU14wJx9ORMnTuhRMQ40lH/orQ==", - "dev": true, - "requires": { - "grunt-known-options": "~1.1.0", - "interpret": "~1.1.0", - "liftoff": "~2.5.0", - "nopt": "~4.0.1", - "v8flags": "~3.1.1" - }, - "dependencies": { - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, - "grunt-known-options": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", - "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", - "dev": true - }, - "grunt-legacy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", - "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", - "dev": true, - "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.5" - }, - "dependencies": { - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - } - } - }, - "grunt-legacy-log-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", - "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", - "dev": true, - "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" - } - }, - "grunt-legacy-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", - "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", - "dev": true, - "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } - } - }, - "grunt-mocha-test": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/grunt-mocha-test/-/grunt-mocha-test-0.13.3.tgz", - "integrity": "sha512-zQGEsi3d+ViPPi7/4jcj78afKKAKiAA5n61pknQYi25Ugik+aNOuRmiOkmb8mN2CeG8YxT+YdT1H1Q7B/eNkoQ==", - "dev": true, - "requires": { - "hooker": "^0.2.3", - "mkdirp": "^0.5.0" - } - }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -5974,27 +5706,12 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, "hook-std": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-2.0.0.tgz", "integrity": "sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==", "dev": true }, - "hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true - }, "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", @@ -6387,12 +6104,6 @@ "xtend": "^4.0.0" } }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, "into-stream": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-5.1.1.tgz", @@ -6403,16 +6114,6 @@ "p-is-promise": "^3.0.0" } }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -6603,15 +6304,6 @@ "has-symbols": "^1.0.1" } }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, "is-running": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-running/-/is-running-2.1.0.tgz", @@ -6648,15 +6340,6 @@ "text-extensions": "^1.0.0" } }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -6948,45 +6631,6 @@ "type-check": "~0.4.0" } }, - "liftoff": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", - "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", - "dev": true, - "requires": { - "extend": "^3.0.0", - "findup-sync": "^2.0.0", - "fined": "^1.0.1", - "flagged-respawn": "^1.0.0", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.0", - "rechoir": "^0.6.2", - "resolve": "^1.1.7" - }, - "dependencies": { - "findup-sync": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", - "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^3.1.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", @@ -7195,15 +6839,6 @@ "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", "dev": true }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -7699,15 +7334,6 @@ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", "dev": true }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -11352,28 +10978,6 @@ "object-keys": "^1.0.11" } }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -11443,12 +11047,6 @@ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, "os-name": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", @@ -11465,22 +11063,6 @@ "integrity": "sha1-a2LDeRz3kJ6jXtRuF2WLtBfLORc=", "dev": true }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "outpipe": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", @@ -11604,17 +11186,6 @@ "safe-buffer": "^5.1.1" } }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", @@ -11624,12 +11195,6 @@ "error-ex": "^1.2.0" } }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -11682,21 +11247,6 @@ "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", "dev": true }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, "path-to-regexp": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", @@ -12122,15 +11672,6 @@ } } }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "^1.1.6" - } - }, "redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", @@ -12214,16 +11755,6 @@ "path-parse": "^1.0.6" } }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -13744,12 +13275,6 @@ "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", "dev": true }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, "undeclared-identifiers": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", @@ -13763,16 +13288,6 @@ "xtend": "^4.0.1" } }, - "underscore.string": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", - "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", - "dev": true, - "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" - } - }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -13958,15 +13473,6 @@ "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", "dev": true }, - "v8flags": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", - "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/package.json b/package.json index 9fdce2cad..9507faf3a 100644 --- a/package.json +++ b/package.json @@ -449,9 +449,6 @@ "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", - "grunt": "^1.2.1", - "grunt-cli": "^1.1.0", - "grunt-mocha-test": "^0.13.2", "http2": "^3.3.6", "husky": "^4.2.5", "jasmine-core": "^3.6.0", @@ -496,7 +493,7 @@ "scripts": { "lint": "eslint . --ext js --ignore-pattern *.tpl.js", "lint:fix": "eslint . --ext js --ignore-pattern *.tpl.js --fix", - "test:unit": "grunt", + "test:unit": "mocha \"test/unit/**/*.spec.js\"", "test:e2e": "cucumber-js test/e2e/*.feature", "test:client": "node bin/karma start test/client/karma.conf.js", "test": "npm run test:unit && npm run test:e2e && npm run test:client", diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 000000000..58a295fd3 --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1,3 @@ +--reporter dot +--ui bdd +test/unit/mocha-globals.js From e246461c528dd84690b6d086b948986046f28ce7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 20 Jan 2021 18:52:24 +0000 Subject: [PATCH 296/374] chore(release): 6.0.1 [skip ci] ## [6.0.1](https://github.com/karma-runner/karma/compare/v6.0.0...v6.0.1) (2021-01-20) ### Bug Fixes * **server:** set maxHttpBufferSize to the socket.io v2 default ([#3626](https://github.com/karma-runner/karma/issues/3626)) ([69baddc](https://github.com/karma-runner/karma/commit/69baddc843e4852a6770bfc1212fc2bce1f38fe7)), closes [#3621](https://github.com/karma-runner/karma/issues/3621) * restore `customFileHandlers` provider ([#3624](https://github.com/karma-runner/karma/issues/3624)) ([25d9abb](https://github.com/karma-runner/karma/commit/25d9abb76929b6ea8abe1cf040ba6db2f269d50e)) --- CHANGELOG.md | 8 ++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1556bc8d0..495f1241c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [6.0.1](https://github.com/karma-runner/karma/compare/v6.0.0...v6.0.1) (2021-01-20) + + +### Bug Fixes + +* **server:** set maxHttpBufferSize to the socket.io v2 default ([#3626](https://github.com/karma-runner/karma/issues/3626)) ([69baddc](https://github.com/karma-runner/karma/commit/69baddc843e4852a6770bfc1212fc2bce1f38fe7)), closes [#3621](https://github.com/karma-runner/karma/issues/3621) +* restore `customFileHandlers` provider ([#3624](https://github.com/karma-runner/karma/issues/3624)) ([25d9abb](https://github.com/karma-runner/karma/commit/25d9abb76929b6ea8abe1cf040ba6db2f269d50e)) + # [6.0.0](https://github.com/karma-runner/karma/compare/v5.2.3...v6.0.0) (2021-01-13) diff --git a/package-lock.json b/package-lock.json index 69090efe4..8884670bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.0.0", + "version": "6.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9507faf3a..2d7e01c2c 100644 --- a/package.json +++ b/package.json @@ -482,7 +482,7 @@ "engines": { "node": ">= 10" }, - "version": "6.0.0", + "version": "6.0.1", "license": "MIT", "husky": { "hooks": { From 6629e96901dbeae24fbaa4d0bfa009618fb8ee75 Mon Sep 17 00:00:00 2001 From: Long Ho Date: Mon, 25 Jan 2021 13:33:56 -0500 Subject: [PATCH 297/374] fix: avoid ES6+ syntax in client scripts (#3629) * remove template literals and arrow functions that break in IE11 Fixes #3630 --- client/karma.js | 7 ++++--- client/updater.js | 22 +++++++++++----------- static/karma.js | 29 +++++++++++++++-------------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/client/karma.js b/client/karma.js index 0734822ff..20a5e19e0 100644 --- a/client/karma.js +++ b/client/karma.js @@ -191,7 +191,7 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) } socket.emit('karma_error', message) - self.updater.updateTestStatus(`karma_error ${message}`) + self.updater.updateTestStatus('karma_error ' + message) this.complete() return false } @@ -240,8 +240,9 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) // A test could have incorrectly issued a navigate. Wait one turn // to ensure the error from an incorrect navigate is processed. - setTimeout(() => { - if (this.config.clearContext) { + var config = this.config + setTimeout(function () { + if (config.clearContext) { navigateContextTo('about:blank') } diff --git a/client/updater.js b/client/updater.js index 3365b5253..569709e3d 100644 --- a/client/updater.js +++ b/client/updater.js @@ -29,7 +29,7 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { if (!titleElement || !bannerElement) { return } - titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}` + titleElement.textContent = 'Karma v ' + VERSION + ' - ' + connectionText + '; test: ' + testText + '; ' + pingText bannerElement.className = connectionText === 'connected' ? 'online' : 'offline' } @@ -46,32 +46,32 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { updateBanner() } - socket.on('connect', () => { + socket.on('connect', function () { updateConnectionStatus('connected') }) - socket.on('disconnect', () => { + socket.on('disconnect', function () { updateConnectionStatus('disconnected') }) - socket.on('reconnecting', (sec) => { - updateConnectionStatus(`reconnecting in ${sec} seconds`) + socket.on('reconnecting', function (sec) { + updateConnectionStatus('reconnecting in ' + sec + ' seconds') }) - socket.on('reconnect', () => { + socket.on('reconnect', function () { updateConnectionStatus('reconnected') }) - socket.on('reconnect_failed', () => { + socket.on('reconnect_failed', function () { updateConnectionStatus('reconnect_failed') }) socket.on('info', updateBrowsersInfo) - socket.on('disconnect', () => { + socket.on('disconnect', function () { updateBrowsersInfo([]) }) - socket.on('ping', () => { + socket.on('ping', function () { updatePingStatus('ping...') }) - socket.on('pong', (latency) => { - updatePingStatus(`ping ${latency}ms`) + socket.on('pong', function (latency) { + updatePingStatus('ping ' + latency + 'ms') }) return { updateTestStatus: updateTestStatus } diff --git a/static/karma.js b/static/karma.js index 8c08d3fca..1c1111450 100644 --- a/static/karma.js +++ b/static/karma.js @@ -201,7 +201,7 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) } socket.emit('karma_error', message) - self.updater.updateTestStatus(`karma_error ${message}`) + self.updater.updateTestStatus('karma_error ' + message) this.complete() return false } @@ -250,8 +250,9 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) // A test could have incorrectly issued a navigate. Wait one turn // to ensure the error from an incorrect navigate is processed. - setTimeout(() => { - if (this.config.clearContext) { + var config = this.config + setTimeout(function () { + if (config.clearContext) { navigateContextTo('about:blank') } @@ -384,7 +385,7 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { if (!titleElement || !bannerElement) { return } - titleElement.textContent = `Karma v ${VERSION} - ${connectionText}; test: ${testText}; ${pingText}` + titleElement.textContent = 'Karma v ' + VERSION + ' - ' + connectionText + '; test: ' + testText + '; ' + pingText bannerElement.className = connectionText === 'connected' ? 'online' : 'offline' } @@ -401,32 +402,32 @@ function StatusUpdater (socket, titleElement, bannerElement, browsersElement) { updateBanner() } - socket.on('connect', () => { + socket.on('connect', function () { updateConnectionStatus('connected') }) - socket.on('disconnect', () => { + socket.on('disconnect', function () { updateConnectionStatus('disconnected') }) - socket.on('reconnecting', (sec) => { - updateConnectionStatus(`reconnecting in ${sec} seconds`) + socket.on('reconnecting', function (sec) { + updateConnectionStatus('reconnecting in ' + sec + ' seconds') }) - socket.on('reconnect', () => { + socket.on('reconnect', function () { updateConnectionStatus('reconnected') }) - socket.on('reconnect_failed', () => { + socket.on('reconnect_failed', function () { updateConnectionStatus('reconnect_failed') }) socket.on('info', updateBrowsersInfo) - socket.on('disconnect', () => { + socket.on('disconnect', function () { updateBrowsersInfo([]) }) - socket.on('ping', () => { + socket.on('ping', function () { updatePingStatus('ping...') }) - socket.on('pong', (latency) => { - updatePingStatus(`ping ${latency}ms`) + socket.on('pong', function (latency) { + updatePingStatus('ping ' + latency + 'ms') }) return { updateTestStatus: updateTestStatus } From 9a6439cb3ca018b722a68093047ea6c8dc6d6fb4 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Mon, 25 Jan 2021 10:36:00 -0800 Subject: [PATCH 298/374] docs: fix link to Sauce Labs plugin (#3627) The Sauce Labs plugin link goes to a module at version 0.0.0 that hasn't been published in 5 years. Update the link to point to the module that is at version 3.4.3 and was published two months ago. In addition, this module is within the karmar-runner GitHub org. --- docs/config/03-browsers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/config/03-browsers.md b/docs/config/03-browsers.md index 0f69fa12e..2ae47e05e 100644 --- a/docs/config/03-browsers.md +++ b/docs/config/03-browsers.md @@ -16,7 +16,7 @@ Note: Most of the browser launchers need to be loaded as [plugins]. - [JSDOM](https://www.npmjs.com/package/karma-jsdom-launcher) - [Opera](https://www.npmjs.com/package/karma-opera-launcher) - [Internet Explorer](https://www.npmjs.com/package/karma-ie-launcher) -- [SauceLabs](https://www.npmjs.com/package/karma-saucelabs-launcher) +- [SauceLabs](https://www.npmjs.com/package/karma-sauce-launcher) - [BrowserStack](https://www.npmjs.com/package/karma-browserstack-launcher) - [many more](https://www.npmjs.org/browse/keyword/karma-launcher) From b5c0baa075839e03c8f30f0b16d473dc0150d8a8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 25 Jan 2021 21:58:49 +0000 Subject: [PATCH 299/374] chore(release): 6.0.2 [skip ci] ## [6.0.2](https://github.com/karma-runner/karma/compare/v6.0.1...v6.0.2) (2021-01-25) ### Bug Fixes * avoid ES6+ syntax in client scripts ([#3629](https://github.com/karma-runner/karma/issues/3629)) ([6629e96](https://github.com/karma-runner/karma/commit/6629e96901dbeae24fbaa4d0bfa009618fb8ee75)), closes [#3630](https://github.com/karma-runner/karma/issues/3630) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 495f1241c..c55633e0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.0.2](https://github.com/karma-runner/karma/compare/v6.0.1...v6.0.2) (2021-01-25) + + +### Bug Fixes + +* avoid ES6+ syntax in client scripts ([#3629](https://github.com/karma-runner/karma/issues/3629)) ([6629e96](https://github.com/karma-runner/karma/commit/6629e96901dbeae24fbaa4d0bfa009618fb8ee75)), closes [#3630](https://github.com/karma-runner/karma/issues/3630) + ## [6.0.1](https://github.com/karma-runner/karma/compare/v6.0.0...v6.0.1) (2021-01-20) diff --git a/package-lock.json b/package-lock.json index 8884670bd..34025e1a5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.0.1", + "version": "6.0.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 2d7e01c2c..72c1487b2 100644 --- a/package.json +++ b/package.json @@ -257,6 +257,7 @@ "Kostiantyn Kahanskyi ", "Kris Kowal ", "Lenny Urbanowski ", + "Long Ho ", "LoveIsGrief ", "Lucas Theisen ", "Lukasz Zatorski ", @@ -326,6 +327,7 @@ "Remy Sharp ", "Ricardo Melo Joia ", "Rich Kuzsma ", + "Rich Trott ", "Richard Herrera ", "Roarke Gaskill ", "Rob Cherry ", @@ -482,7 +484,7 @@ "engines": { "node": ">= 10" }, - "version": "6.0.1", + "version": "6.0.2", "license": "MIT", "husky": { "hooks": { From 8d589ed9a94e9e8becab9de853fbefce3fdf4807 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 27 Jan 2021 10:58:49 -0800 Subject: [PATCH 300/374] chore(testing): stop log4js output in unit tests (#3634) Use https://log4js-node.github.io/log4js-node/recording.html to verify logs --- test/unit/mocha-globals.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/unit/mocha-globals.js b/test/unit/mocha-globals.js index 8afdd587b..6659714ee 100644 --- a/test/unit/mocha-globals.js +++ b/test/unit/mocha-globals.js @@ -1,6 +1,7 @@ const sinon = require('sinon') const chai = require('chai') const logger = require('../../lib/logger') +const recording = require('log4js/lib/appenders/recording') // publish globals that all specs can use global.expect = chai.expect @@ -15,13 +16,14 @@ chai.use(require('chai-subset')) beforeEach(() => { global.sinon = sinon.createSandbox() - // set logger to log INFO, but do not append to console - // so that we can assert logs by logger.on('info', ...) - logger.setup('INFO', false, []) + // Use https://log4js-node.github.io/log4js-node/recording.html to verify logs + const vcr = { vcr: { type: 'recording' } } + logger.setup('INFO', false, vcr) }) afterEach(() => { global.sinon.restore() + recording.erase() }) // TODO(vojta): move to helpers or something From e02858ae0d0de3f05add976b10e4b6b935cc3dd7 Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 27 Jan 2021 10:59:51 -0800 Subject: [PATCH 301/374] fix(plugins): refactor instantiatePlugin from preproprocessor (#3628) add unit test for plugin.js add comments on role of function and cache --- lib/plugin.js | 38 ++++- lib/preprocessor.js | 36 +--- lib/server.js | 1 + test/unit/plugin.spec.js | 61 +++++++ test/unit/preprocessor.spec.js | 291 +++++++++++++-------------------- 5 files changed, 219 insertions(+), 208 deletions(-) create mode 100644 test/unit/plugin.spec.js diff --git a/lib/plugin.js b/lib/plugin.js index 2e0ad5a24..20a180597 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -50,4 +50,40 @@ function resolve (plugins, emitter) { return modules } -exports.resolve = resolve +/** + Create a function to handle errors in plugin loading. + @param {Object} injector, the dict of dependency injection objects. + @return function closed over injector, which reports errors. +*/ +function createInstantiatePlugin (injector) { + const emitter = injector.get('emitter') + // Cache to avoid report errors multiple times per plugin. + const pluginInstances = new Map() + return function instantiatePlugin (kind, name) { + if (pluginInstances.has(name)) { + return pluginInstances.get(name) + } + + let p + try { + p = injector.get(`${kind}:${name}`) + if (!p) { + log.error(`Failed to instantiate ${kind} ${name}`) + emitter.emit('load_error', kind, name) + } + } catch (e) { + if (e.message.includes(`No provider for "${kind}:${name}"`)) { + log.error(`Cannot load "${name}", it is not registered!\n Perhaps you are missing some plugin?`) + } else { + log.error(`Cannot load "${name}"!\n ` + e.stack) + } + emitter.emit('load_error', kind, name) + } + pluginInstances.set(name, p, `${kind}:${name}`) + return p + } +} + +createInstantiatePlugin.$inject = ['injector'] + +module.exports = { resolve, createInstantiatePlugin } diff --git a/lib/preprocessor.js b/lib/preprocessor.js index 4b56a3633..b6bf75695 100644 --- a/lib/preprocessor.js +++ b/lib/preprocessor.js @@ -70,36 +70,8 @@ async function runProcessors (preprocessors, file, content) { file.sha = CryptoUtils.sha1(content) } -function createPriorityPreprocessor (config = {}, preprocessorPriority, basePath, injector) { - const emitter = injector.get('emitter') - const instances = new Map() - - function instantiatePreprocessor (name) { - if (instances.has(name)) { - return instances.get(name) - } - - let p - try { - p = injector.get('preprocessor:' + name) - if (!p) { - log.error(`Failed to instantiate preprocessor ${name}`) - emitter.emit('load_error', 'preprocessor', name) - } - } catch (e) { - if (e.message.includes(`No provider for "preprocessor:${name}"`)) { - log.error(`Can not load "${name}", it is not registered!\n Perhaps you are missing some plugin?`) - } else { - log.error(`Can not load "${name}"!\n ` + e.stack) - } - emitter.emit('load_error', 'preprocessor', name) - } - - instances.set(name, p) - return p - } - _.union.apply(_, Object.values(config)).forEach(instantiatePreprocessor) - +function createPriorityPreprocessor (config = {}, preprocessorPriority, basePath, instantiatePlugin) { + _.union.apply(_, Object.values(config)).forEach((name) => instantiatePlugin('preprocessor', name)) return async function preprocess (file) { const buffer = await tryToRead(file.originalPath, log) let isBinary = file.isBinary @@ -121,7 +93,7 @@ function createPriorityPreprocessor (config = {}, preprocessorPriority, basePath .sort((a, b) => b[1] - a[1]) .map((duo) => duo[0]) .reduce((preProcs, name) => { - const p = instantiatePreprocessor(name) + const p = instantiatePlugin('preprocessor', name) if (!isBinary || (p && p.handleBinaryFiles)) { preProcs.push(p) @@ -135,5 +107,5 @@ function createPriorityPreprocessor (config = {}, preprocessorPriority, basePath } } -createPriorityPreprocessor.$inject = ['config.preprocessors', 'config.preprocessor_priority', 'config.basePath', 'injector'] +createPriorityPreprocessor.$inject = ['config.preprocessors', 'config.preprocessor_priority', 'config.basePath', 'instantiatePlugin'] exports.createPriorityPreprocessor = createPriorityPreprocessor diff --git a/lib/server.js b/lib/server.js index 0cf94ce97..aa96b76ea 100644 --- a/lib/server.js +++ b/lib/server.js @@ -76,6 +76,7 @@ class Server extends KarmaEventEmitter { watcher: ['value', watcher], launcher: ['factory', Launcher.factory], config: ['value', config], + instantiatePlugin: ['factory', plugin.createInstantiatePlugin], preprocess: ['factory', preprocessor.createPriorityPreprocessor], fileList: ['factory', FileList.factory], webServer: ['factory', createWebServer], diff --git a/test/unit/plugin.spec.js b/test/unit/plugin.spec.js new file mode 100644 index 000000000..3ec9824d1 --- /dev/null +++ b/test/unit/plugin.spec.js @@ -0,0 +1,61 @@ +'use strict' + +const createInstantiatePlugin = require('../../lib/plugin').createInstantiatePlugin + +describe('plugin', () => { + describe('createInstantiatePlugin', () => { + it('creates the instantiatePlugin function', () => { + const fakeGet = sinon.stub() + const fakeInjector = { get: fakeGet } + + expect(typeof createInstantiatePlugin(fakeInjector)).to.be.equal('function') + expect(fakeGet).to.have.been.calledWith('emitter') + }) + + it('creates the instantiatePlugin function', () => { + const fakes = { + emitter: { emit: sinon.stub() } + } + const fakeInjector = { get: (id) => fakes[id] } + + const instantiatePlugin = createInstantiatePlugin(fakeInjector) + expect(typeof instantiatePlugin('kind', 'name')).to.be.equal('undefined') + expect(fakes.emitter.emit).to.have.been.calledWith('load_error', 'kind', 'name') + }) + + it('caches plugins', () => { + const fakes = { + emitter: { emit: sinon.stub() }, + 'kind:name': { my: 'plugin' } + } + const fakeInjector = { + get: (id) => { + return fakes[id] + } + } + + const instantiatePlugin = createInstantiatePlugin(fakeInjector) + expect(instantiatePlugin('kind', 'name')).to.be.equal(fakes['kind:name']) + fakeInjector.get = (id) => { throw new Error('failed to cache') } + expect(instantiatePlugin('kind', 'name')).to.be.equal(fakes['kind:name']) + }) + + it('errors if the injector errors', () => { + const fakes = { + emitter: { emit: sinon.stub() } + } + const fakeInjector = { + get: (id) => { + if (id in fakes) { + return fakes[id] + } + throw new Error('fail') + } + } + + const instantiatePlugin = createInstantiatePlugin(fakeInjector) + expect(typeof instantiatePlugin('unknown', 'name')).to.be.equal('undefined') + expect(fakes.emitter.emit).to.have.been.calledWith('load_error', 'unknown', 'name') + }) + }) +}) diff --git a/test/unit/preprocessor.spec.js b/test/unit/preprocessor.spec.js index 2b5fefbc2..5f0b7860d 100644 --- a/test/unit/preprocessor.spec.js +++ b/test/unit/preprocessor.spec.js @@ -1,18 +1,19 @@ 'use strict' const mocks = require('mocks') -const di = require('di') const path = require('path') -const events = require('../../lib/events') - describe('preprocessor', () => { let m let mockFs - let emitterSetting // mimic first few bytes of a pdf file const binarydata = Buffer.from([0x25, 0x50, 0x44, 0x66, 0x46, 0x00]) + // Each test will define a spy; the fakeInstatiatePlugin will return it. + let fakePreprocessor + + const simpleFakeInstantiatePlugin = () => { return fakePreprocessor } + beforeEach(() => { mockFs = mocks.fs.create({ some: { @@ -32,22 +33,16 @@ describe('preprocessor', () => { 'graceful-fs': mockFs, minimatch: require('minimatch') } - emitterSetting = { emitter: ['value', new events.EventEmitter()] } m = mocks.loadFile(path.join(__dirname, '/../../lib/preprocessor.js'), mocks_) }) it('should preprocess matching file', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { file.path = file.path + '-preprocessed' done(null, 'new-content') }) - const injector = new di.Injector([{ - 'preprocessor:fake': [ - 'factory', function () { return fakePreprocessor } - ] - }, emitterSetting]) - const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } @@ -58,15 +53,12 @@ describe('preprocessor', () => { }) it('should match directories starting with a dot', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { file.path = file.path + '-preprocessed' done(null, 'new-content') }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/.dir/a.js', path: 'path' } @@ -77,15 +69,12 @@ describe('preprocessor', () => { }) it('should get content if preprocessor is an async function or return Promise with content', async () => { - const fakePreprocessor = sinon.spy(async (content, file, done) => { + fakePreprocessor = sinon.spy(async (content, file, done) => { file.path = file.path + '-preprocessed' return 'new-content' }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/.dir/a.js', path: 'path' } @@ -96,15 +85,12 @@ describe('preprocessor', () => { }) it('should get content if preprocessor is an async function still calling done()', async () => { - const fakePreprocessor = sinon.spy(async (content, file, done) => { + fakePreprocessor = sinon.spy(async (content, file, done) => { file.path = file.path + '-preprocessed' done(null, 'new-content') }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/.dir/a.js', path: 'path' } @@ -115,16 +101,13 @@ describe('preprocessor', () => { }) it('should check patterns after creation when invoked', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { file.path = file.path + '-preprocessed' done(null, 'new-content') }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) const config = { '**/*.txt': ['fake'] } - const pp = m.createPriorityPreprocessor(config, {}, null, injector) + const pp = m.createPriorityPreprocessor(config, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } @@ -137,14 +120,11 @@ describe('preprocessor', () => { }) it('should ignore not matching file', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, '') }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/a.txt', path: 'path' } @@ -153,34 +133,33 @@ describe('preprocessor', () => { }) it('should apply all preprocessors', async () => { - const fakePreprocessor1 = sinon.spy((content, file, done) => { - file.path = file.path + '-p1' - done(null, content + '-c1') - }) - - const fakePreprocessor2 = sinon.spy((content, file, done) => { - file.path = file.path + '-p2' - done(content + '-c2') - }) - - const injector = new di.Injector([{ - 'preprocessor:fake1': ['factory', function () { return fakePreprocessor1 }], - 'preprocessor:fake2': ['factory', function () { return fakePreprocessor2 }] - }, emitterSetting]) + const fakes = { + fake1: sinon.spy((content, file, done) => { + file.path = file.path + '-p1' + done(null, content + '-c1') + }), + fake2: sinon.spy((content, file, done) => { + file.path = file.path + '-p2' + done(content + '-c2') + }) + } + function fakeInstatiatePlugin (kind, name) { + return fakes[name] + } - const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake1', 'fake2'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake1', 'fake2'] }, {}, null, fakeInstatiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } await pp(file) - expect(fakePreprocessor1).to.have.been.calledOnce - expect(fakePreprocessor2).to.have.been.calledOnce + expect(fakes.fake1).to.have.been.calledOnce + expect(fakes.fake2).to.have.been.calledOnce expect(file.path).to.equal('path-p1-p2') expect(file.content).to.equal('content-c1-c2') }) it('should compute SHA', async () => { - const pp = m.createPriorityPreprocessor({}, {}, null, new di.Injector([emitterSetting])) + const pp = m.createPriorityPreprocessor({}, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } await pp(file) @@ -198,15 +177,11 @@ describe('preprocessor', () => { }) it('should compute SHA from content returned by a processor', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, content + '-processed') }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/a.js': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/a.js': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const fileProcess = { originalPath: '/some/a.js', path: 'path' } const fileSkip = { originalPath: '/some/b.js', path: 'path' } @@ -221,15 +196,11 @@ describe('preprocessor', () => { }) it('should return error if any preprocessor fails', () => { - const failingPreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(new Error('Some error'), null) }) - const injector = new di.Injector([{ - 'preprocessor:failing': ['factory', function () { return failingPreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*.js': ['failing'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['failing'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } @@ -241,20 +212,20 @@ describe('preprocessor', () => { }) it('should stop preprocessing after an error', async () => { - const failingPreprocessor = sinon.spy((content, file, done) => { - done(new Error('Some error'), null) - }) - - const fakePreprocessor = sinon.spy((content, file, done) => { - done(null, content) - }) + const fakes = { + failing: sinon.spy((content, file, done) => { + done(new Error('Some error'), null) + }), + fake: sinon.spy((content, file, done) => { + done(null, content) + }) + } - const injector = new di.Injector([{ - 'preprocessor:failing': ['factory', function () { return failingPreprocessor }], - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) + function fakeInstantiatePlugin (kind, name) { + return fakes[name] + } - const pp = m.createPriorityPreprocessor({ '**/*.js': ['failing', 'fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['failing', 'fake'] }, {}, null, fakeInstantiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } @@ -263,7 +234,7 @@ describe('preprocessor', () => { }, (err) => { expect(err.message).to.equal('Some error') }) - expect(fakePreprocessor).not.to.have.been.called + expect(fakes.fake).not.to.have.been.called }) describe('when fs.readFile fails', () => { @@ -274,15 +245,11 @@ describe('preprocessor', () => { }) it('should retry up to 3 times', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) await pp(file).then(() => { throw new Error('Should be rejected') @@ -295,9 +262,7 @@ describe('preprocessor', () => { }) it('should throw after 3 retries', async () => { - const injector = new di.Injector([{}, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*.js': [] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*.js': [] }, {}, null, simpleFakeInstantiatePlugin) await pp(file).then(() => { throw new Error('Should be rejected') @@ -309,15 +274,11 @@ describe('preprocessor', () => { }) it('should not preprocess binary files by default', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/photo.png', path: 'path' } @@ -327,15 +288,11 @@ describe('preprocessor', () => { }) it('should not preprocess files configured to be binary', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/proto.pb', path: 'path', isBinary: true } @@ -345,15 +302,11 @@ describe('preprocessor', () => { }) it('should preprocess files configured not to be binary', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) // Explicit false for isBinary const file = { originalPath: '/some/proto.pb', path: 'path', isBinary: false } @@ -364,16 +317,12 @@ describe('preprocessor', () => { }) it('should preprocess binary files if handleBinaryFiles=true', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) fakePreprocessor.handleBinaryFiles = true - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { return fakePreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/photo.png', path: 'path' } @@ -383,15 +332,11 @@ describe('preprocessor', () => { }) it('should not preprocess binary files with capital letters in extension', async () => { - const fakePreprocessor = sinon.spy((content, file, done) => { + fakePreprocessor = sinon.spy((content, file, done) => { done(null, content) }) - const injector = new di.Injector([{ - 'preprocessor:fake': ['factory', function () { fakePreprocessor }] - }, emitterSetting]) - - const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, injector) + const pp = m.createPriorityPreprocessor({ '**/*': ['fake'] }, {}, null, simpleFakeInstantiatePlugin) const file = { originalPath: '/some/CAM_PHOTO.JPG', path: 'path' } @@ -402,72 +347,68 @@ describe('preprocessor', () => { it('should merge lists of preprocessors using default priority', async () => { const callOrder = [] - const fakePreprocessorA = sinon.spy((content, file, done) => { - callOrder.push('a') - done(null, content) - }) - const fakePreprocessorB = sinon.spy((content, file, done) => { - callOrder.push('b') - done(null, content) - }) - const fakePreprocessorC = sinon.spy((content, file, done) => { - callOrder.push('c') - done(null, content) - }) - const fakePreprocessorD = sinon.spy((content, file, done) => { - callOrder.push('d') - done(null, content) - }) - - const injector = new di.Injector([{ - 'preprocessor:fakeA': ['factory', function () { return fakePreprocessorA }], - 'preprocessor:fakeB': ['factory', function () { return fakePreprocessorB }], - 'preprocessor:fakeC': ['factory', function () { return fakePreprocessorC }], - 'preprocessor:fakeD': ['factory', function () { return fakePreprocessorD }] - }, emitterSetting]) + const fakes = { + fakeA: sinon.spy((content, file, done) => { + callOrder.push('a') + done(null, content) + }), + fakeB: sinon.spy((content, file, done) => { + callOrder.push('b') + done(null, content) + }), + fakeC: sinon.spy((content, file, done) => { + callOrder.push('c') + done(null, content) + }), + fakeD: sinon.spy((content, file, done) => { + callOrder.push('d') + done(null, content) + }) + } + function fakeInstantiatePlugin (kind, name) { + return fakes[name] + } const pp = m.createPriorityPreprocessor({ '/*/a.js': ['fakeA', 'fakeB'], '/some/*': ['fakeB', 'fakeC'], '/some/a.js': ['fakeD'] - }, {}, null, injector) + }, {}, null, fakeInstantiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } await pp(file) - expect(fakePreprocessorA).to.have.been.called - expect(fakePreprocessorB).to.have.been.called - expect(fakePreprocessorC).to.have.been.called - expect(fakePreprocessorD).to.have.been.called + expect(fakes.fakeA).to.have.been.called + expect(fakes.fakeB).to.have.been.called + expect(fakes.fakeC).to.have.been.called + expect(fakes.fakeD).to.have.been.called expect(callOrder).to.eql(['a', 'b', 'c', 'd']) }) it('should merge lists of preprocessors obeying priority', async () => { const callOrder = [] - const fakePreprocessorA = sinon.spy((content, file, done) => { - callOrder.push('a') - done(null, content) - }) - const fakePreprocessorB = sinon.spy((content, file, done) => { - callOrder.push('b') - done(null, content) - }) - const fakePreprocessorC = sinon.spy((content, file, done) => { - callOrder.push('c') - done(null, content) - }) - const fakePreprocessorD = sinon.spy((content, file, done) => { - callOrder.push('d') - done(null, content) - }) - - const injector = new di.Injector([{ - 'preprocessor:fakeA': ['factory', function () { return fakePreprocessorA }], - 'preprocessor:fakeB': ['factory', function () { return fakePreprocessorB }], - 'preprocessor:fakeC': ['factory', function () { return fakePreprocessorC }], - 'preprocessor:fakeD': ['factory', function () { return fakePreprocessorD }] - }, emitterSetting]) + const fakes = { + fakeA: sinon.spy((content, file, done) => { + callOrder.push('a') + done(null, content) + }), + fakeB: sinon.spy((content, file, done) => { + callOrder.push('b') + done(null, content) + }), + fakeC: sinon.spy((content, file, done) => { + callOrder.push('c') + done(null, content) + }), + fakeD: sinon.spy((content, file, done) => { + callOrder.push('d') + done(null, content) + }) + } + function fakeInstantiatePlugin (kind, name) { + return fakes[name] + } const priority = { fakeA: -1, fakeB: 1, fakeD: 100 } @@ -475,15 +416,15 @@ describe('preprocessor', () => { '/*/a.js': ['fakeA', 'fakeB'], '/some/*': ['fakeB', 'fakeC'], '/some/a.js': ['fakeD'] - }, priority, null, injector) + }, priority, null, fakeInstantiatePlugin) const file = { originalPath: '/some/a.js', path: 'path' } await pp(file) - expect(fakePreprocessorA).to.have.been.called - expect(fakePreprocessorB).to.have.been.called - expect(fakePreprocessorC).to.have.been.called - expect(fakePreprocessorD).to.have.been.called + expect(fakes.fakeA).to.have.been.called + expect(fakes.fakeB).to.have.been.called + expect(fakes.fakeC).to.have.been.called + expect(fakes.fakeD).to.have.been.called expect(callOrder).to.eql(['d', 'b', 'c', 'a']) }) From 7a1344f5879aed58f620ff1717144d89278937f1 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 27 Jan 2021 22:21:28 +0000 Subject: [PATCH 302/374] chore(release): 6.0.3 [skip ci] ## [6.0.3](https://github.com/karma-runner/karma/compare/v6.0.2...v6.0.3) (2021-01-27) ### Bug Fixes * **plugins:** refactor instantiatePlugin from preproprocessor ([#3628](https://github.com/karma-runner/karma/issues/3628)) ([e02858a](https://github.com/karma-runner/karma/commit/e02858ae0d0de3f05add976b10e4b6b935cc3dd7)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c55633e0a..63f838372 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.0.3](https://github.com/karma-runner/karma/compare/v6.0.2...v6.0.3) (2021-01-27) + + +### Bug Fixes + +* **plugins:** refactor instantiatePlugin from preproprocessor ([#3628](https://github.com/karma-runner/karma/issues/3628)) ([e02858a](https://github.com/karma-runner/karma/commit/e02858ae0d0de3f05add976b10e4b6b935cc3dd7)) + ## [6.0.2](https://github.com/karma-runner/karma/compare/v6.0.1...v6.0.2) (2021-01-25) diff --git a/package-lock.json b/package-lock.json index 34025e1a5..476bd6832 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.0.2", + "version": "6.0.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 72c1487b2..9c132864c 100644 --- a/package.json +++ b/package.json @@ -484,7 +484,7 @@ "engines": { "node": ">= 10" }, - "version": "6.0.2", + "version": "6.0.3", "license": "MIT", "husky": { "hooks": { From dbd1943e6901c4cb86280db7663afde32f9ab86c Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Mon, 1 Feb 2021 18:53:00 +0100 Subject: [PATCH 303/374] fix: ensure that Karma supports running tests on IE 11 (#3642) They were failing because of unsupported arrow function syntax in two places: - in karma.spec.js file (only affecting Karma's own tests) - in socket.io.js file installed from NPM, hence the dependency update (this affected Karma consumers) Enabled BrowserStack tests on IE 11 to prevent regressions. --- package-lock.json | 94 +++++++++++++++++++-------------------- package.json | 2 +- test/client/karma.conf.js | 37 +++++---------- test/client/karma.spec.js | 4 +- 4 files changed, 61 insertions(+), 76 deletions(-) diff --git a/package-lock.json b/package-lock.json index 476bd6832..c05418b26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4297,31 +4297,31 @@ } }, "engine.io": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.5.tgz", - "integrity": "sha512-Ri+whTNr2PKklxQkfbGjwEo+kCBUM4Qxk4wtLqLrhH+b1up2NFL9g9pjYWiCV/oazwB0rArnvF/ZmZN2ab5Hpg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.0.tgz", + "integrity": "sha512-vW7EAtn0HDQ4MtT5QbmCHF17TaYLONv2/JwdYsq9USPRZVM4zG7WB3k0Nc321z8EuSOlhGokrYlYx4176QhD0A==", "requires": { "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", "cors": "~2.8.5", - "debug": "~4.1.0", + "debug": "~4.3.1", "engine.io-parser": "~4.0.0", - "ws": "^7.1.2" + "ws": "~7.4.2" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -12451,54 +12451,54 @@ } }, "socket.io": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.4.tgz", - "integrity": "sha512-Vj1jUoO75WGc9txWd311ZJJqS9Dr8QtNJJ7gk2r7dcM/yGe9sit7qOijQl3GAwhpBOz/W8CwkD7R6yob07nLbA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz", + "integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==", "requires": { "@types/cookie": "^0.4.0", "@types/cors": "^2.8.8", - "@types/node": "^14.14.7", + "@types/node": "^14.14.10", "accepts": "~1.3.4", "base64id": "~2.0.0", - "debug": "~4.1.0", - "engine.io": "~4.0.0", - "socket.io-adapter": "~2.0.3", - "socket.io-parser": "~4.0.1" + "debug": "~4.3.1", + "engine.io": "~4.1.0", + "socket.io-adapter": "~2.1.0", + "socket.io-parser": "~4.0.3" }, "dependencies": { "@types/node": { - "version": "14.14.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.13.tgz", - "integrity": "sha512-vbxr0VZ8exFMMAjCW8rJwaya0dMCDyYW2ZRdTyjtrCvJoENMpdUHOT/eTzvgyA5ZnqRZ/sI0NwqAxNHKYokLJQ==" + "version": "14.14.22", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", + "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==" }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "socket.io-adapter": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz", - "integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", + "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==" }, "socket.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.2.tgz", - "integrity": "sha512-Bs3IYHDivwf+bAAuW/8xwJgIiBNtlvnjYRc4PbXgniLmcP1BrakBoq/QhO24rgtgW7VZ7uAaswRGxutUnlAK7g==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.4.tgz", + "integrity": "sha512-t+b0SS+IxG7Rxzda2EVvyBZbvFPBCjJoyHuE0P//7OAsN23GItzDRdWa6ALxZI/8R5ygK7jAR6t028/z+7295g==", "requires": { "@types/component-emitter": "^1.2.10", "component-emitter": "~1.3.0", - "debug": "~4.1.0" + "debug": "~4.3.1" }, "dependencies": { "component-emitter": { @@ -12507,17 +12507,17 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -13812,9 +13812,9 @@ } }, "ws": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", - "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ==" + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" }, "xmlbuilder": { "version": "12.0.0", diff --git a/package.json b/package.json index 9c132864c..dcd577fb8 100644 --- a/package.json +++ b/package.json @@ -428,7 +428,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.0.4", + "socket.io": "^3.1.0", "source-map": "^0.6.1", "tmp": "0.2.1", "ua-parser-js": "^0.7.23", diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index 0b1281d78..e700b64de 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -14,35 +14,20 @@ const launchers = { browser: 'firefox', os: 'Windows', os_version: '10' - } + }, // bs_safari: { // base: 'BrowserStack', - // browser: 'safari', - // browser_version: '9.0', - // os_version: 'El Capitan', - // os: 'OS X' - // }, - // bs_ie_11: { - // base: 'BrowserStack', - // browser: 'ie', - // browser_version: '11.0', - // os: 'Windows', - // os_version: '10' - // }, - // bs_ie_10: { - // base: 'BrowserStack', - // browser: 'ie', - // browser_version: '10.0', - // os: 'Windows', - // os_version: '8' + // browser: 'Safari', + // os: 'OS X', + // os_version: 'Big Sur' // }, - // bs_ie_9: { - // base: 'BrowserStack', - // browser: 'ie', - // browser_version: '9.0', - // os: 'Windows', - // os_version: '7' - // } + bs_ie: { + base: 'BrowserStack', + browser: 'IE', + browser_version: '11.0', + os: 'Windows', + os_version: '10' + } } // Verify the install. This will run async but that's ok we'll see the log. diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index b1c50a00a..036a4ecbd 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -17,7 +17,7 @@ describe('Karma', function () { beforeEach(function () { mockTestStatus = '' updater = { - updateTestStatus: (s) => { + updateTestStatus: function (s) { mockTestStatus = s } } @@ -454,7 +454,7 @@ describe('Karma', function () { clock.tick(500) ck.complete() - setTimeout(() => { + setTimeout(function () { assert(windowLocation.href === 'http://return.com') done() }, 5) From 9c755e0d61f1e8fb0fed1281fc8a331d5f1734be Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Mon, 1 Feb 2021 19:19:12 +0100 Subject: [PATCH 304/374] fix(cli): temporarily disable strict parameters validation (#3641) As discussed in #3625 there are multiple cases, where Karma users rely on the possibility to pass arbitrary options/arguments to the karma CLI. These arguments are either handled in a `karma.conf.js` file or are consumed by Karma plugins. Given the disruptive effect of the strict parameters validation and the lack of the feasible workarounds, the feature is reverted until we have better understanding of the custom options/arguments use cases and can implement a solution which works for everybody. --- lib/cli.js | 5 +++- test/e2e/cli.feature | 58 ++++++++++++-------------------------------- 2 files changed, 19 insertions(+), 44 deletions(-) diff --git a/lib/cli.js b/lib/cli.js index 0aac17e9a..6e7fdac4f 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -153,7 +153,7 @@ function describeRoot () { .command('stop [configFile]', 'Stop the server.', describeStop) .command('completion', 'Shell completion for karma.', describeCompletion) .demandCommand(1, 'Command not specified.') - .strict() + .strictCommands() .describe('help', 'Print usage and options.') .describe('version', 'Print current version.') } @@ -164,6 +164,7 @@ function describeInit (yargs) { 'INIT - Initialize a config file.\n\n' + 'Usage:\n' + ' $0 init [configFile]') + .strictCommands(false) .version(false) .positional('configFile', { describe: 'Name of the generated Karma configuration file', @@ -215,6 +216,7 @@ function describeRun (yargs) { 'RUN - Run the tests (requires running server).\n\n' + 'Usage:\n' + ' $0 run [configFile] [-- ]') + .strictCommands(false) .version(false) .positional('configFile', { describe: 'Path to the Karma configuration file', @@ -247,6 +249,7 @@ function describeStop (yargs) { 'STOP - Stop the server (requires running server).\n\n' + 'Usage:\n' + ' $0 stop [configFile]') + .strictCommands(false) .version(false) .positional('configFile', { describe: 'Path to the Karma configuration file', diff --git a/test/e2e/cli.feature b/test/e2e/cli.feature index 476d29a8e..e4f235985 100644 --- a/test/e2e/cli.feature +++ b/test/e2e/cli.feature @@ -55,52 +55,24 @@ Feature: CLI --help Print usage and options. [boolean] --version Print current version. [boolean] - Unknown argument: strat + Unknown command: strat """ - Scenario: Error when option is unknown - When I execute Karma with arguments: "start --invalid-option" - Then the stderr is exactly: + Scenario: No error when unknown option and argument are passed in + Given a configuration with: """ - Karma - Spectacular Test Runner for JavaScript. - - START - Start the server / do a single run. - - Usage: - karma start [configFile] - - Positionals: - configFile Path to the Karma configuration file [string] - - Options: - --help Print usage and options. [boolean] - --port Port where the server is running. - --auto-watch Auto watch source files and run on change. - --detached Detach the server. - --no-auto-watch Do not watch source files. - --log-level Level - of logging. - --colors Use colors when reporting and printing logs. - --no-colors Do not use colors when reporting or printing - logs. - --reporters List of reporters (available: dots, progress, - junit, growl, coverage). - --browsers List of browsers to start (eg. --browsers - Chrome,ChromeCanary,Firefox). - --capture-timeout Kill browser if does not capture in - given time [ms]. - --single-run Run the test when browsers captured and exit. - --no-single-run Disable single-run. - --report-slower-than Report tests that are slower than - given time [ms]. - --fail-on-empty-test-suite Fail on empty test suite. - --no-fail-on-empty-test-suite Do not fail on empty test suite. - --fail-on-failing-test-suite Fail on failing test suite. - --no-fail-on-failing-test-suite Do not fail on failing test suite. - --format-error A path to a file that exports the format - function. [string] - - Unknown arguments: invalid-option, invalidOption + files = ['basic/plus.js', 'basic/test.js']; + browsers = ['ChromeHeadlessNoSandbox']; + plugins = [ + 'karma-jasmine', + 'karma-chrome-launcher' + ]; + """ + When I execute Karma with arguments: "start sandbox/karma.conf.js unknown-argument --unknown-option" + Then it passes with: + """ + .. + Chrome Headless """ Scenario: Init command help From 2a57b230cd6b27e1a6e903ca6557c5a6b3e31bf6 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Mon, 1 Feb 2021 20:55:02 +0100 Subject: [PATCH 305/374] fix(client): fix a false positive page reload error in Safari (#3643) Previous code was susceptible to the race condition in Safari browser. Specifically below piece: ``` iframe.src = policy.createURL(url) karmaNavigating = false ``` There is no guarantee that onbeforeunload event will be triggered synchronously after setting `iframe.src`. It was the case in Chrome and Firefox, but not in Safari, where this caused an error every test run. New approach resets the onbeforeunload handler before navigation is triggered by Karma itself to avoid the need for synchronization and this race condition altogether. The handler will be restored by the new context once it is loaded. PS Code is a bit fragile as there is an implicit dependency on `onbeforeunload` from the context, but I can't think of a cleaner approach. --- client/karma.js | 18 ++++++------------ context/karma.js | 6 +++--- static/context.js | 6 +++--- static/karma.js | 18 ++++++------------ test/client/karma.spec.js | 2 +- 5 files changed, 19 insertions(+), 31 deletions(-) diff --git a/client/karma.js b/client/karma.js index 20a5e19e0..5586bdc9e 100644 --- a/client/karma.js +++ b/client/karma.js @@ -5,7 +5,6 @@ var util = require('../common/util') function Karma (updater, socket, iframe, opener, navigator, location, document) { this.updater = updater var startEmitted = false - var karmaNavigating = false var self = this var queryParams = util.parseQueryParams(location.search) var browserId = queryParams.id || util.generateId('manual-') @@ -83,21 +82,21 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) var childWindow = null function navigateContextTo (url) { - karmaNavigating = true if (self.config.useIframe === false) { // run in new window if (self.config.runInParent === false) { // If there is a window already open, then close it // DEV: In some environments (e.g. Electron), we don't have setter access for location if (childWindow !== null && childWindow.closed !== true) { + // The onbeforeunload listener was added by context to catch + // unexpected navigations while running tests. + childWindow.onbeforeunload = undefined childWindow.close() } childWindow = opener(url) - karmaNavigating = false // run context on parent element (client_with_context) // using window.__karma__.scriptUrls to get the html element strings and load them dynamically } else if (url !== 'about:blank') { - karmaNavigating = false var loadScript = function (idx) { if (idx < window.__karma__.scriptUrls.length) { var parser = new DOMParser() @@ -128,15 +127,10 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) } // run in iframe } else { + // The onbeforeunload listener was added by the context to catch + // unexpected navigations while running tests. + iframe.contentWindow.onbeforeunload = undefined iframe.src = policy.createURL(url) - karmaNavigating = false - } - } - - this.onbeforeunload = function () { - if (!karmaNavigating) { - // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) - self.error('Some of your tests did a full page reload!') } } diff --git a/context/karma.js b/context/karma.js index 677767c9a..859d56d19 100644 --- a/context/karma.js +++ b/context/karma.js @@ -77,9 +77,9 @@ function ContextKarma (callParentKarmaMethod) { contextWindow.onerror = function () { return self.error.apply(self, arguments) } - // DEV: We must defined a function since we don't want to pass the event object - contextWindow.onbeforeunload = function (e, b) { - callParentKarmaMethod('onbeforeunload', []) + + contextWindow.onbeforeunload = function () { + return self.error('Some of your tests did a full page reload!') } contextWindow.dump = function () { diff --git a/static/context.js b/static/context.js index 8cc67ebf6..417503165 100644 --- a/static/context.js +++ b/static/context.js @@ -214,9 +214,9 @@ function ContextKarma (callParentKarmaMethod) { contextWindow.onerror = function () { return self.error.apply(self, arguments) } - // DEV: We must defined a function since we don't want to pass the event object - contextWindow.onbeforeunload = function (e, b) { - callParentKarmaMethod('onbeforeunload', []) + + contextWindow.onbeforeunload = function () { + return self.error('Some of your tests did a full page reload!') } contextWindow.dump = function () { diff --git a/static/karma.js b/static/karma.js index 1c1111450..23b7c1ae2 100644 --- a/static/karma.js +++ b/static/karma.js @@ -15,7 +15,6 @@ var util = require('../common/util') function Karma (updater, socket, iframe, opener, navigator, location, document) { this.updater = updater var startEmitted = false - var karmaNavigating = false var self = this var queryParams = util.parseQueryParams(location.search) var browserId = queryParams.id || util.generateId('manual-') @@ -93,21 +92,21 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) var childWindow = null function navigateContextTo (url) { - karmaNavigating = true if (self.config.useIframe === false) { // run in new window if (self.config.runInParent === false) { // If there is a window already open, then close it // DEV: In some environments (e.g. Electron), we don't have setter access for location if (childWindow !== null && childWindow.closed !== true) { + // The onbeforeunload listener was added by context to catch + // unexpected navigations while running tests. + childWindow.onbeforeunload = undefined childWindow.close() } childWindow = opener(url) - karmaNavigating = false // run context on parent element (client_with_context) // using window.__karma__.scriptUrls to get the html element strings and load them dynamically } else if (url !== 'about:blank') { - karmaNavigating = false var loadScript = function (idx) { if (idx < window.__karma__.scriptUrls.length) { var parser = new DOMParser() @@ -138,15 +137,10 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) } // run in iframe } else { + // The onbeforeunload listener was added by the context to catch + // unexpected navigations while running tests. + iframe.contentWindow.onbeforeunload = undefined iframe.src = policy.createURL(url) - karmaNavigating = false - } - } - - this.onbeforeunload = function () { - if (!karmaNavigating) { - // TODO(vojta): show what test (with explanation about jasmine.UPDATE_INTERVAL) - self.error('Some of your tests did a full page reload!') } } diff --git a/test/client/karma.spec.js b/test/client/karma.spec.js index 036a4ecbd..3e7af73d8 100644 --- a/test/client/karma.spec.js +++ b/test/client/karma.spec.js @@ -22,7 +22,7 @@ describe('Karma', function () { } } socket = new MockSocket() - iframe = {} + iframe = { contentWindow: {} } windowNavigator = {} windowLocation = { search: '' } windowStub = sinon.stub().returns({}) From 7cdb43eebc330ba0bb05b09e6fdda81078b6560c Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 1 Feb 2021 22:05:25 +0000 Subject: [PATCH 306/374] chore(release): 6.0.4 [skip ci] ## [6.0.4](https://github.com/karma-runner/karma/compare/v6.0.3...v6.0.4) (2021-02-01) ### Bug Fixes * **cli:** temporarily disable strict parameters validation ([#3641](https://github.com/karma-runner/karma/issues/3641)) ([9c755e0](https://github.com/karma-runner/karma/commit/9c755e0d61f1e8fb0fed1281fc8a331d5f1734be)), closes [#3625](https://github.com/karma-runner/karma/issues/3625) * **client:** fix a false positive page reload error in Safari ([#3643](https://github.com/karma-runner/karma/issues/3643)) ([2a57b23](https://github.com/karma-runner/karma/commit/2a57b230cd6b27e1a6e903ca6557c5a6b3e31bf6)) * ensure that Karma supports running tests on IE 11 ([#3642](https://github.com/karma-runner/karma/issues/3642)) ([dbd1943](https://github.com/karma-runner/karma/commit/dbd1943e6901c4cb86280db7663afde32f9ab86c)) --- CHANGELOG.md | 9 +++++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63f838372..d7b668de7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [6.0.4](https://github.com/karma-runner/karma/compare/v6.0.3...v6.0.4) (2021-02-01) + + +### Bug Fixes + +* **cli:** temporarily disable strict parameters validation ([#3641](https://github.com/karma-runner/karma/issues/3641)) ([9c755e0](https://github.com/karma-runner/karma/commit/9c755e0d61f1e8fb0fed1281fc8a331d5f1734be)), closes [#3625](https://github.com/karma-runner/karma/issues/3625) +* **client:** fix a false positive page reload error in Safari ([#3643](https://github.com/karma-runner/karma/issues/3643)) ([2a57b23](https://github.com/karma-runner/karma/commit/2a57b230cd6b27e1a6e903ca6557c5a6b3e31bf6)) +* ensure that Karma supports running tests on IE 11 ([#3642](https://github.com/karma-runner/karma/issues/3642)) ([dbd1943](https://github.com/karma-runner/karma/commit/dbd1943e6901c4cb86280db7663afde32f9ab86c)) + ## [6.0.3](https://github.com/karma-runner/karma/compare/v6.0.2...v6.0.3) (2021-01-27) diff --git a/package-lock.json b/package-lock.json index c05418b26..5bde7941d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.0.3", + "version": "6.0.4", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index dcd577fb8..9e5f9f4a1 100644 --- a/package.json +++ b/package.json @@ -484,7 +484,7 @@ "engines": { "node": ">= 10" }, - "version": "6.0.3", + "version": "6.0.4", "license": "MIT", "husky": { "hooks": { From a14a24ef81348b29daf70e0ea8406588fdd01f19 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Tue, 2 Feb 2021 01:12:34 +0100 Subject: [PATCH 307/374] chore(test): adjust test to pass in Safari browser (#3645) In Safari stringified Proxy object has ProxyObject as a name, but in other browsers it does not. Enabled Safari tests on BrowserStack to prevent future regressions. --- test/client/karma.conf.js | 12 ++++++------ test/client/stringify.spec.js | 4 +++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index e700b64de..838e3b78d 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -15,12 +15,12 @@ const launchers = { os: 'Windows', os_version: '10' }, - // bs_safari: { - // base: 'BrowserStack', - // browser: 'Safari', - // os: 'OS X', - // os_version: 'Big Sur' - // }, + bs_safari: { + base: 'BrowserStack', + browser: 'Safari', + os: 'OS X', + os_version: 'Big Sur' + }, bs_ie: { base: 'BrowserStack', browser: 'IE', diff --git a/test/client/stringify.spec.js b/test/client/stringify.spec.js index 921ec3366..a3c744ca5 100644 --- a/test/client/stringify.spec.js +++ b/test/client/stringify.spec.js @@ -49,7 +49,9 @@ describe('stringify', function () { if (window.Proxy) { it('should serialize proxied functions', function () { var defProxy = new Proxy(function (d, e, f) { return 'whatever' }, {}) - assert.deepStrictEqual(stringify(defProxy), 'function () { ... }') + // In Safari stringified Proxy object has ProxyObject as a name, but + // in other browsers it does not. + assert.deepStrictEqual(/^function (ProxyObject)?\(\) { ... }$/.test(stringify(defProxy)), true) }) } From 9dba1e20af48d4885e1a1c6da8c08454acb0db9d Mon Sep 17 00:00:00 2001 From: Nick Petruzzelli Date: Tue, 2 Feb 2021 19:33:43 -0500 Subject: [PATCH 308/374] feat(config): improve `karma.config.parseConfig` error handling (#3635) --- lib/config.js | 31 ++++++++++++++++++++-------- lib/server.js | 10 ++++++++- test/unit/config.spec.js | 44 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 75 insertions(+), 10 deletions(-) diff --git a/lib/config.js b/lib/config.js index 1ea49b85c..b08bbde7d 100644 --- a/lib/config.js +++ b/lib/config.js @@ -351,7 +351,26 @@ const CONFIG_SYNTAX_HELP = ' module.exports = function(config) {\n' + ' });\n' + ' };\n' -function parseConfig (configFilePath, cliOptions) { +function parseConfig (configFilePath, cliOptions, parseOptions) { + function fail () { + log.error(...arguments) + if (parseOptions && parseOptions.throwErrors === true) { + const errorMessage = Array.from(arguments).join(' ') + throw new Error(errorMessage) + } else { + const warningMessage = + 'The `parseConfig()` function historically called `process.exit(1)`' + + ' when it failed. This behavior is now deprecated and function will' + + ' throw an error in the next major release. To suppress this warning' + + ' pass `throwErrors: true` as a third argument to opt-in into the new' + + ' behavior and adjust your code to respond to the exception' + + ' accordingly.' + + ' Example: `parseConfig(path, cliOptions, { throwErrors: true })`' + log.warn(warningMessage) + process.exit(1) + } + } + let configModule if (configFilePath) { try { @@ -360,8 +379,6 @@ function parseConfig (configFilePath, cliOptions) { configModule = configModule.default } } catch (e) { - log.error('Error in config file!\n ' + e.stack || e) - const extension = path.extname(configFilePath) if (extension === '.coffee' && !COFFEE_SCRIPT_AVAILABLE) { log.error('You need to install CoffeeScript.\n npm install coffeescript --save-dev') @@ -370,11 +387,10 @@ function parseConfig (configFilePath, cliOptions) { } else if (extension === '.ts' && !TYPE_SCRIPT_AVAILABLE) { log.error('You need to install TypeScript.\n npm install typescript ts-node --save-dev') } - return process.exit(1) + return fail('Error in config file!\n ' + e.stack || e) } if (!helper.isFunction(configModule)) { - log.error('Config file must export a function!\n' + CONFIG_SYNTAX_HELP) - return process.exit(1) + return fail('Config file must export a function!\n' + CONFIG_SYNTAX_HELP) } } else { configModule = () => {} // if no config file path is passed, we define a dummy config module. @@ -395,8 +411,7 @@ function parseConfig (configFilePath, cliOptions) { try { configModule(config) } catch (e) { - log.error('Error in config file!\n', e) - return process.exit(1) + return fail('Error in config file!\n', e) } // merge the config from config file and cliOptions (precedence) diff --git a/lib/server.js b/lib/server.js index aa96b76ea..a6ae81dab 100644 --- a/lib/server.js +++ b/lib/server.js @@ -63,7 +63,15 @@ class Server extends KarmaEventEmitter { this.loadErrors = [] - const config = cfg.parseConfig(cliOptions.configFile, cliOptions) + let config + try { + config = cfg.parseConfig(cliOptions.configFile, cliOptions, { throwErrors: true }) + } catch (parseConfigError) { + // TODO: change how `done` falls back to exit in next major version + // SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378 + (done || process.exit)(1) + return + } this.log.debug('Final config', util.inspect(config, false, /** depth **/ null)) diff --git a/test/unit/config.spec.js b/test/unit/config.spec.js index 169c418af..d115a2b6e 100644 --- a/test/unit/config.spec.js +++ b/test/unit/config.spec.js @@ -46,6 +46,8 @@ describe('config', () => { '/conf/invalid.js': () => { throw new SyntaxError('Unexpected token =') }, + '/conf/export-not-function.js': 'not-a-function', + // '/conf/export-null.js': null, // Same as `/conf/not-exist.js`? '/conf/exclude.js': wrapCfg({ exclude: ['one.js', 'sub/two.js'] }), '/conf/absolute.js': wrapCfg({ files: ['http://some.com', 'https://more.org/file.js'] }), '/conf/both.js': wrapCfg({ files: ['one.js', 'two.js'], exclude: ['third.js'] }), @@ -57,6 +59,7 @@ describe('config', () => { m = loadFile(path.join(__dirname, '/../../lib/config.js'), mocks, { global: {}, process: mocks.process, + Error: Error, // Without this, chai's `.throw()` assertion won't correctly check against constructors. require (path) { if (mockConfigs[path]) { return mockConfigs[path] @@ -123,7 +126,20 @@ describe('config', () => { expect(mocks.process.exit).to.have.been.calledWith(1) }) - it('should throw and log error if invalid file', () => { + it('should log error and throw if file does not exist AND throwErrors is true', () => { + function parseConfig () { + e.parseConfig('/conf/not-exist.js', {}, { throwErrors: true }) + } + + expect(parseConfig).to.throw(Error, 'Error in config file!\n Error: Cannot find module \'/conf/not-exist.js\'') + expect(logSpy).to.have.been.called + const event = logSpy.lastCall.args + expect(event.toString().split('\n').slice(0, 2)).to.be.deep.equal( + ['Error in config file!', ' Error: Cannot find module \'/conf/not-exist.js\'']) + expect(mocks.process.exit).not.to.have.been.called + }) + + it('should log an error and exit if invalid file', () => { e.parseConfig('/conf/invalid.js', {}) expect(logSpy).to.have.been.called @@ -133,6 +149,32 @@ describe('config', () => { expect(mocks.process.exit).to.have.been.calledWith(1) }) + it('should log an error and throw if invalid file AND throwErrors is true', () => { + function parseConfig () { + e.parseConfig('/conf/invalid.js', {}, { throwErrors: true }) + } + + expect(parseConfig).to.throw(Error, 'Error in config file!\n SyntaxError: Unexpected token =') + expect(logSpy).to.have.been.called + const event = logSpy.lastCall.args + expect(event[0]).to.eql('Error in config file!\n') + expect(event[1].message).to.eql('Unexpected token =') + expect(mocks.process.exit).not.to.have.been.called + }) + + it('should log error and throw if file does not export a function AND throwErrors is true', () => { + function parseConfig () { + e.parseConfig('/conf/export-not-function.js', {}, { throwErrors: true }) + } + + expect(parseConfig).to.throw(Error, 'Config file must export a function!\n') + expect(logSpy).to.have.been.called + const event = logSpy.lastCall.args + expect(event.toString().split('\n').slice(0, 1)).to.be.deep.equal( + ['Config file must export a function!']) + expect(mocks.process.exit).not.to.have.been.called + }) + it('should override config with given cli options', () => { const config = e.parseConfig('/home/config4.js', { port: 456, autoWatch: false }) From 3cb26e353202c773438f422e41cd01856879b464 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 3 Feb 2021 01:29:39 +0000 Subject: [PATCH 309/374] chore(release): 6.1.0 [skip ci] # [6.1.0](https://github.com/karma-runner/karma/compare/v6.0.4...v6.1.0) (2021-02-03) ### Features * **config:** improve `karma.config.parseConfig` error handling ([#3635](https://github.com/karma-runner/karma/issues/3635)) ([9dba1e2](https://github.com/karma-runner/karma/commit/9dba1e20af48d4885e1a1c6da8c08454acb0db9d)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 5 +++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7b668de7..a094bdc61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [6.1.0](https://github.com/karma-runner/karma/compare/v6.0.4...v6.1.0) (2021-02-03) + + +### Features + +* **config:** improve `karma.config.parseConfig` error handling ([#3635](https://github.com/karma-runner/karma/issues/3635)) ([9dba1e2](https://github.com/karma-runner/karma/commit/9dba1e20af48d4885e1a1c6da8c08454acb0db9d)) + ## [6.0.4](https://github.com/karma-runner/karma/compare/v6.0.3...v6.0.4) (2021-02-01) diff --git a/package-lock.json b/package-lock.json index 5bde7941d..fcebd843a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.0.4", + "version": "6.1.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9e5f9f4a1..fc9e84e62 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,8 @@ "Karma Bot ", "Maksim Ryzhikov ", "ukasz Usarz ", - "Christian Budde Christensen ", "semantic-release-bot ", + "Christian Budde Christensen ", "Wesley Cho ", "taichi ", "Liam Newman ", @@ -292,6 +292,7 @@ "Nick Carter ", "Nick McCurdy ", "Nick Payne ", + "Nick Petruzzelli ", "Nick Williams ", "Nicolas Artman ", "Nicolas Ferrero ", @@ -484,7 +485,7 @@ "engines": { "node": ">= 10" }, - "version": "6.0.4", + "version": "6.1.0", "license": "MIT", "husky": { "hooks": { From 7ab86be25c334b07747632b0a6bdb1d650d881bc Mon Sep 17 00:00:00 2001 From: Chris Bottin Date: Wed, 3 Feb 2021 21:18:29 +0000 Subject: [PATCH 310/374] fix: report launcher process error when exit event is not emitted (#3647) Co-authored-by: Chris Bottin --- lib/launchers/process.js | 5 +++ test/unit/launchers/process.spec.js | 64 +++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 18 deletions(-) diff --git a/lib/launchers/process.js b/lib/launchers/process.js index 072c15b81..a7aa101ce 100644 --- a/lib/launchers/process.js +++ b/lib/launchers/process.js @@ -93,6 +93,7 @@ function ProcessLauncher (spawn, tempDir, timer, processKillTimeout) { } else { errorOutput += err.toString() } + self._onProcessExit(-1, null, errorOutput) }) self._process.stderr.on('data', function (errBuff) { @@ -101,6 +102,10 @@ function ProcessLauncher (spawn, tempDir, timer, processKillTimeout) { } this._onProcessExit = function (code, signal, errorOutput) { + if (!self._process) { + // Both exit and error events trigger _onProcessExit(), but we only need one cleanup. + return + } log.debug(`Process ${self.name} exited with code ${code} and signal ${signal}`) let error = null diff --git a/test/unit/launchers/process.spec.js b/test/unit/launchers/process.spec.js index 6dfc29b40..489d7ecdf 100644 --- a/test/unit/launchers/process.spec.js +++ b/test/unit/launchers/process.spec.js @@ -7,18 +7,25 @@ const CaptureTimeoutLauncher = require('../../../lib/launchers/capture_timeout') const ProcessLauncher = require('../../../lib/launchers/process') const EventEmitter = require('../../../lib/events').EventEmitter const createMockTimer = require('../mocks/timer') +const logger = require('../../../lib/logger') describe('launchers/process.js', () => { let emitter let mockSpawn let mockTempDir let launcher + let logErrorSpy + let logDebugSpy const BROWSER_PATH = path.normalize('/usr/bin/browser') beforeEach(() => { emitter = new EventEmitter() launcher = new BaseLauncher('fake-id', emitter) + launcher.name = 'fake-name' + launcher.ENV_CMD = 'fake-ENV-CMD' + logErrorSpy = sinon.spy(logger.create('launcher'), 'error') + logDebugSpy = sinon.spy(logger.create('launcher'), 'debug') mockSpawn = sinon.spy(function (cmd, args) { const process = new EventEmitter() @@ -74,7 +81,7 @@ describe('launchers/process.js', () => { }) describe('with RetryLauncher', () => { - it('should handle spawn ENOENT error and not even retry', (done) => { + function assertSpawnError ({ errorCode, emitExit, expectedError }, done) { ProcessLauncher.call(launcher, mockSpawn, mockTempDir) RetryLauncher.call(launcher, 2) launcher._getCommand = () => BROWSER_PATH @@ -83,35 +90,56 @@ describe('launchers/process.js', () => { emitter.on('browser_process_failure', failureSpy) launcher.start('http://host:9876/') - mockSpawn._processes[0].emit('error', { code: 'ENOENT' }) - mockSpawn._processes[0].emit('exit', 1) + mockSpawn._processes[0].emit('error', { code: errorCode }) + if (emitExit) { + mockSpawn._processes[0].emit('exit', 1) + } mockTempDir.remove.callArg(1) _.defer(() => { expect(launcher.state).to.equal(launcher.STATE_FINISHED) expect(failureSpy).to.have.been.called + expect(logDebugSpy).to.have.been.callCount(5) + expect(logDebugSpy.getCall(0)).to.have.been.calledWithExactly('null -> BEING_CAPTURED') + expect(logDebugSpy.getCall(1)).to.have.been.calledWithExactly(`${BROWSER_PATH} http://host:9876/?id=fake-id`) + expect(logDebugSpy.getCall(2)).to.have.been.calledWithExactly('Process fake-name exited with code -1 and signal null') + expect(logDebugSpy.getCall(3)).to.have.been.calledWithExactly('fake-name failed (cannot start). Not restarting.') + expect(logDebugSpy.getCall(4)).to.have.been.calledWithExactly('BEING_CAPTURED -> FINISHED') + expect(logErrorSpy).to.have.been.calledWith(expectedError) done() }) + } + + it('should handle spawn ENOENT error and not even retry', (done) => { + assertSpawnError({ + errorCode: 'ENOENT', + emitExit: true, + expectedError: `Cannot start fake-name\n\tCan not find the binary ${BROWSER_PATH}\n\tPlease set env variable fake-ENV-CMD` + }, done) }) it('should handle spawn EACCES error and not even retry', (done) => { - ProcessLauncher.call(launcher, mockSpawn, mockTempDir) - RetryLauncher.call(launcher, 2) - launcher._getCommand = () => BROWSER_PATH - - const failureSpy = sinon.spy() - emitter.on('browser_process_failure', failureSpy) + assertSpawnError({ + errorCode: 'EACCES', + emitExit: true, + expectedError: `Cannot start fake-name\n\tPermission denied accessing the binary ${BROWSER_PATH}\n\tMaybe it's a directory?` + }, done) + }) - launcher.start('http://host:9876/') - mockSpawn._processes[0].emit('error', { code: 'EACCES' }) - mockSpawn._processes[0].emit('exit', 1) - mockTempDir.remove.callArg(1) + it('should handle spawn ENOENT error and report the error when exit event is not emitted', (done) => { + assertSpawnError({ + errorCode: 'ENOENT', + emitExit: false, + expectedError: `Cannot start fake-name\n\tCan not find the binary ${BROWSER_PATH}\n\tPlease set env variable fake-ENV-CMD` + }, done) + }) - _.defer(() => { - expect(launcher.state).to.equal(launcher.STATE_FINISHED) - expect(failureSpy).to.have.been.called - done() - }) + it('should handle spawn EACCES error and report the error when exit event is not emitted', (done) => { + assertSpawnError({ + errorCode: 'EACCES', + emitExit: false, + expectedError: `Cannot start fake-name\n\tPermission denied accessing the binary ${BROWSER_PATH}\n\tMaybe it's a directory?` + }, done) }) }) From 474f4e1caff469cce87f19a11d9179e4e05552f9 Mon Sep 17 00:00:00 2001 From: xel23 Date: Fri, 12 Feb 2021 20:35:46 +0300 Subject: [PATCH 311/374] fix(config): check extension before ts-node register (#3651) Call require('ts-node').register() after checking configFilePath has `.ts` extension Fixes #3329 --- lib/config.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/config.js b/lib/config.js index b08bbde7d..30e874ee6 100644 --- a/lib/config.js +++ b/lib/config.js @@ -27,7 +27,7 @@ try { } catch (e) {} try { - require('ts-node').register() + require('ts-node') TYPE_SCRIPT_AVAILABLE = true } catch (e) {} @@ -374,6 +374,9 @@ function parseConfig (configFilePath, cliOptions, parseOptions) { let configModule if (configFilePath) { try { + if (path.extname(configFilePath) === '.ts' && TYPE_SCRIPT_AVAILABLE) { + require('ts-node').register() + } configModule = require(configFilePath) if (typeof configModule === 'object' && typeof configModule.default !== 'undefined') { configModule = configModule.default From 99908c3f5b5e48bc2e2158d090ca2e9d514fcb03 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Fri, 12 Feb 2021 18:40:47 +0100 Subject: [PATCH 312/374] docs(plugins): add more information about plugins (#3649) Changes: - Promote `require('karma-plugin')` form over `'karma-plugin'` form. Former makes it more clear that plugin is imported from an NPM package and it is a regular JS object, there is no magic behind it. This is inspired by #3498 where user is not aware that it is even possible. This also should make it easier with plug'n'play package managers (like Yarn 2). - Explain that `plugins` array does not activate plugins, but only registers them to clarify https://github.com/karma-runner/karma/issues/1247#issuecomment-312267740. - Explain the plugin structure, DI and how to build a new plugin. - Re-arrange "Developing plugins" page to make it easier to add more information about every plugin type. Adding actual information should be done in the separate PRs though. Fixes #1247 --- docs/config/01-configuration-file.md | 10 +- docs/config/05-plugins.md | 50 +++++--- docs/dev/05-plugins.md | 184 ++++++++++++++++++++------- lib/config.js | 2 +- lib/plugin.js | 2 +- 5 files changed, 175 insertions(+), 73 deletions(-) diff --git a/docs/config/01-configuration-file.md b/docs/config/01-configuration-file.md index 24646e6c4..6d1c73f53 100644 --- a/docs/config/01-configuration-file.md +++ b/docs/config/01-configuration-file.md @@ -548,12 +548,9 @@ mime: { **Default:** `['karma-*']` -**Description:** List of plugins to load. A plugin can be a string (in which case it will be required by Karma) or an inlined plugin - Object. -By default, Karma loads all sibling NPM modules which have a name starting with `karma-*`. +**Description:** List of plugins to load. A plugin can be either a plugin object, or a string containing name of the module which exports a plugin object. See [plugins] for more information on how to install and use plugins. -Note: Just about all plugins in Karma require an additional library to be installed (via NPM). - -See [plugins] for more information. +By default, Karma loads plugins from all sibling NPM packages which have a name starting with `karma-*`. ## port @@ -587,8 +584,7 @@ If, after test execution or after Karma attempts to kill the browser, browser is Preprocessors can be loaded through [plugins]. -Note: Just about all preprocessors in Karma (other than CoffeeScript and some other defaults) -require an additional library to be installed (via NPM). +Note: Just about all preprocessors in Karma require an additional library to be installed (via NPM). Be aware that preprocessors may be transforming the files and file types that are available at run time. For instance, if you are using the "coverage" preprocessor on your source files, if you then attempt to interactively debug diff --git a/docs/config/05-plugins.md b/docs/config/05-plugins.md index 6272fc80f..4cf8b9203 100644 --- a/docs/config/05-plugins.md +++ b/docs/config/05-plugins.md @@ -1,11 +1,12 @@ -Karma can be easily extended through plugins. -In fact, all the existing preprocessors, reporters, browser launchers and frameworks are also plugins. +Karma can be easily extended through plugins. In fact, all the existing preprocessors, reporters, browser launchers and frameworks are plugins. -## Installation +You can install [existing plugins] from NPM or you can write [your own plugins][developing plugins] for Karma. -Karma plugins are NPM modules, so the recommended way to install them are as project dependencies in your `package.json`: +## Installing Plugins -```javascript +The recommended way to install plugins is to add them as project dependencies in your `package.json`: + +```json { "devDependencies": { "karma": "~0.10", @@ -22,26 +23,35 @@ Therefore, a simple way to install a plugin is: npm install karma- --save-dev ``` - ## Loading Plugins -By default, Karma loads all sibling NPM modules which have a name starting with `karma-*`. -You can also explicitly list plugins you want to load via the `plugins` configuration setting. The configuration value can either be -a string (module name), which will be required by Karma, or an object (inlined plugin). +By default, Karma loads plugins from all sibling NPM packages which have a name starting with `karma-*`. + +You can also override this behavior and explicitly list plugins you want to load via the `plugins` configuration setting: ```javascript -plugins: [ - // Karma will require() these plugins - 'karma-jasmine', - 'karma-chrome-launcher' - - // inlined plugins - {'framework:xyz': ['factory', factoryFn]}, - require('./plugin-required-from-config') -] +config.set({ + plugins: [ + // Load a plugin you installed from NPM. + require('karma-jasmine'), + + // Load a plugin from the file in your project. + require('./my-custom-plugin'), + + // Define a plugin inline. + { 'framework:xyz': ['factory', factoryFn] }, + + // Specify a module name or path which Karma will require() and load its + // default export as a plugin. + 'karma-chrome-launcher', + './my-fancy-plugin' + ] +}) ``` -There are already many [existing plugins]. Of course, you can write [your own plugins] too! +## Activating Plugins + +Adding a plugin to the `plugins` array only makes Karma aware of the plugin, but it does not activate it. Depending on the plugin type you'll need to add a plugin name into `frameworks`, `reporters`, `preprocessors`, `middleware` or `browsers` configuration key to activate it. For the detailed information refer to the corresponding plugin documentation or check out [Developing plugins][developing plugins] guide for more in-depth explanation of how plugins work. [existing plugins]: https://npmjs.org/browse/keyword/karma-plugin -[your own plugins]: ../dev/plugins.html +[developing plugins]: ../dev/plugins.html diff --git a/docs/dev/05-plugins.md b/docs/dev/05-plugins.md index d9371e46a..d7cae9e6d 100644 --- a/docs/dev/05-plugins.md +++ b/docs/dev/05-plugins.md @@ -1,61 +1,109 @@ pageTitle: Developing Plugins -Karma can be extended through plugins. A plugin is essentially an NPM module. Typically, there are four kinds of plugins: **frameworks**, **reporters**, **launchers** and **preprocessors**. The best way to understand how this works is to take a look at some of the existing plugins. Following sections list some of the plugins that you might use as a reference. +Karma can be extended through plugins. There are five kinds of plugins: *framework*, *reporter*, *launcher*, *preprocessor* and *middleware*. Each type allows to modify a certain aspect of the Karma behavior. -## Frameworks -- example plugins: [karma-jasmine], [karma-mocha], [karma-requirejs] -- use naming convention is `karma-*` -- use NPM keywords `karma-plugin`, `karma-framework`. +- A *framework* connects a testing framework (like Mocha) to a Karma API, so browser can send test results back to a Karma server. +- A *reporter* defines how test results are reported to a user. +- A *launcher* allows Karma to launch different browsers to run tests in. +- A *preprocessor* is responsible for transforming/transpiling source files before loading them into a browser. +- A *middleware* can be used to customise how files are served to a browser. -## Reporters -- example plugins: [karma-growl-reporter], [karma-junit-reporter], [karma-material-reporter] -- use naming convention is `karma-*-reporter` -- use NPM keywords `karma-plugin`, `karma-reporter` +## Dependency injection -## Launchers -- example plugins: [karma-chrome-launcher], [karma-sauce-launcher] -- use naming convention is `karma-*-launcher` -- use NPM keywords `karma-plugin`, `karma-launcher` +Karma is assembled using [*dependency injection*](https://en.wikipedia.org/wiki/Dependency_injection). It is important to understand this concept to be able to develop plugins. -## Preprocessors +On the very high level you can think of Karma as an object where each key (a *DI token*) is mapped to a certain Karma object (a *service*). For example, `config` DI token maps to `Config` instance, which holds current Karma configuration. Plugins can request (or *inject*) various Karma objects by specifying a corresponding DI token. Upon injection a plugin can interact with injected services to implement their functionality. -A preprocessor is a function that accepts three arguments (`content`, `file`, and `next`), mutates the content in some way, and passes it on to the next preprocessor. +There is no exhaustive list of all available services and their DI tokens, but you can discover them by reading Karma's or other plugins' source code. -- arguments passed to preprocessor plugins: - - **`content`** of the file being processed - - **`file`** object describing the file being processed - - **path:** the current file, mutable file path. e. g. `some/file.coffee` -> `some/file.coffee.js` _This path is mutable and may not actually exist._ - - **originalPath:** the original, unmutated path - - **encodings:** A mutable, keyed object where the keys are a valid encoding type ('gzip', 'compress', 'br', etc.) and the values are the encoded content. Encoded content should be stored here and not resolved using `next(null, encodedContent)` - - **type:** determines how to include a file, when serving - - **`next`** function to be called when preprocessing is complete, should be called as `next(null, processedContent)` or `next(error)` -- example plugins: [karma-coffee-preprocessor], [karma-ng-html2js-preprocessor] -- use naming convention is `karma-*-preprocessor` -- user NPM keywords `karma-plugin`, `karma-preprocessor` +## Plugin structure -## Crazier stuff -Karma is assembled by Dependency Injection and a plugin is just an additional DI module (see [node-di] for more), that can be loaded by Karma. Therefore, it can ask for pretty much any Karma component and interact with it. There are a couple of plugins that do more interesting stuff like this, check out [karma-closure], [karma-intellij]. +Each plugin is essentially a service with its associated DI token. When user [activates a plugin][plugins] in their config, Karma looks for a corresponding DI token and instantiates a service linked to this DI token. +To declare a plugin one should define a DI token for the plugin and explain Karma how to instantiate it. A DI token consists of two parts: a plugin type and plugin's unique name. The former defines what a plugin can do, requirements to the service's API and when it is instantiated. The latter is a unique name, which a plugin user will use to activate a plugin. -[karma-jasmine]: https://github.com/karma-runner/karma-jasmine -[karma-mocha]: https://github.com/karma-runner/karma-mocha +It is totally valid for a plugin to define multiple services. This can be done by adding more keys to the object exported by the plugin. Common example of this would be `framework` + `reporter` plugins, which usually come together. -[karma-requirejs]: https://github.com/karma-runner/karma-requirejs -[karma-growl-reporter]: https://github.com/karma-runner/karma-growl-reporter -[karma-junit-reporter]: https://github.com/karma-runner/karma-junit-reporter -[karma-chrome-launcher]: https://github.com/karma-runner/karma-chrome-launcher -[karma-sauce-launcher]: https://github.com/karma-runner/karma-sauce-launcher -[karma-coffee-preprocessor]: https://github.com/karma-runner/karma-coffee-preprocessor -[karma-ng-html2js-preprocessor]: https://github.com/karma-runner/karma-ng-html2js-preprocessor -[karma-closure]: https://github.com/karma-runner/karma-closure -[karma-intellij]: https://github.com/karma-runner/karma-intellij -[node-di]: https://github.com/vojtajina/node-di -[karma-material-reporter]: https://github.com/ameerthehacker/karma-material-reporter +Let's make a very simple plugin, which prints "Hello, world!" when instantiated. We'll use a `framework` type as it is instantiated early in the Karma lifecycle and does not have any requirements to its API. Let's call our plugin "hello", so its unique name will be `hello`. Joining these two parts we get a DI token for our plugin `framework:hello`. Let's declare it. + +```js +// hello-plugin.js + +// A factory function for our plugin, it will be called, when Karma needs to +// instantiate a plugin. Normally it should return an instance of the service +// conforming to the API requirements of the plugin type (more on that below), +// but for our simple example we don't need any service and just print +// a message when function is called. +function helloFrameworkFactory() { + console.log('Hello, world!') +} + +module.exports = { + // Declare the plugin, so Karma knows that it exists. + // 'factory' tells Karma that it should call `helloFrameworkFactory` + // function and use whatever it returns as a service for the DI token + // `framework:hello`. + 'framework:hello': ['factory', helloFrameworkFactory] +}; +``` + +```js +// karma.conf.js + +module.exports = (config) => { + config.set({ + plugins: [ + require('./hello-plugin') + ], + // Activate our plugin by specifying its unique name in the + // corresponding configuration key. + frameworks: ['hello'] + }) +} +``` + +## Injecting dependencies + +In "Dependency injection" section we discussed that it is possible to inject any Karma services into a plugin and interact with them. This can be done by setting an `$inject` property on the plugin's factory function to an array of DI tokens plugin wishes to interact with. Karma will pick up this property and pass requested services to the factory functions as parameters. + +Let's make the `hello` framework a bit more useful and make it add `hello.js` file to the `files` array. This way users of the plugin can, for example, access a function defined in `hello.js` from their tests. + +```js +// hello-plugin.js + +// Add parameters to the function to receive requested services. +function helloFrameworkFactory(config) { + config.files.unshift({ + pattern: __dirname + '/hello.js', + included: true, + served: true, + watched: false + }) +} + +// Declare DI tokens plugin wants to inject. +helloFrameworkFactory.$inject = ['config'] + +module.exports = { + 'framework:hello': ['factory', helloFrameworkFactory] +}; +``` + +The Karma config is unchanged and is omitted for brevity. See above example for the plugin usage. + +Note: Currently, Karma uses [node-di] library as a DI implementation. The library is more powerful than what's documented above, however, the DI implementation may change in the future, so we recommend not to rely on the node-di implementation details. + +## Plugin types -## Karma Framework API +This section outlines API requirements and conventions for different plugin types. There also links to some plugins, which you can use for inspiration. -Karma Framework connects existing testing libraries to Karma's API, so that their -results can be displayed in a browser and sent back to the server. +### Frameworks + +- example plugins: [karma-jasmine], [karma-mocha], [karma-requirejs] +- use naming convention is `karma-*` +- use NPM keywords `karma-plugin`, `karma-framework`. + +A framework connects existing testing libraries to Karma's API, so that their results can be displayed in a browser and sent back to the server. Karma frameworks _must_ implement a `window.__karma__.start` method that Karma will call to start test execution. This function is called with an object that has methods @@ -89,3 +137,51 @@ statuses. The method takes an object of the form: skipped: Boolean // skipped / ran } ``` + +### Reporters + +- example plugins: [karma-growl-reporter], [karma-junit-reporter], [karma-material-reporter] +- use naming convention is `karma-*-reporter` +- use NPM keywords `karma-plugin`, `karma-reporter` + +### Launchers + +- example plugins: [karma-chrome-launcher], [karma-sauce-launcher] +- use naming convention is `karma-*-launcher` +- use NPM keywords `karma-plugin`, `karma-launcher` + +### Preprocessors + +- example plugins: [karma-coffee-preprocessor], [karma-ng-html2js-preprocessor] +- use naming convention is `karma-*-preprocessor` +- user NPM keywords `karma-plugin`, `karma-preprocessor` + +A preprocessor is a function that accepts three arguments (`content`, `file`, and `next`), mutates the content in some way, and passes it on to the next preprocessor. + +- arguments passed to preprocessor plugins: + - **`content`** of the file being processed + - **`file`** object describing the file being processed + - **path:** the current file, mutable file path. e. g. `some/file.coffee` -> `some/file.coffee.js` _This path is mutable and may not actually exist._ + - **originalPath:** the original, unmutated path + - **encodings:** A mutable, keyed object where the keys are a valid encoding type ('gzip', 'compress', 'br', etc.) and the values are the encoded content. Encoded content should be stored here and not resolved using `next(null, encodedContent)` + - **type:** determines how to include a file, when serving + - **`next`** function to be called when preprocessing is complete, should be called as `next(null, processedContent)` or `next(error)` + +### Crazier stuff + +As Karma is assembled by dependency injection, a plugin can ask for pretty much any Karma component and interact with it. There are a couple of plugins that do more interesting stuff like this, check out [karma-closure], [karma-intellij]. + +[karma-jasmine]: https://github.com/karma-runner/karma-jasmine +[karma-mocha]: https://github.com/karma-runner/karma-mocha +[karma-requirejs]: https://github.com/karma-runner/karma-requirejs +[karma-growl-reporter]: https://github.com/karma-runner/karma-growl-reporter +[karma-junit-reporter]: https://github.com/karma-runner/karma-junit-reporter +[karma-chrome-launcher]: https://github.com/karma-runner/karma-chrome-launcher +[karma-sauce-launcher]: https://github.com/karma-runner/karma-sauce-launcher +[karma-coffee-preprocessor]: https://github.com/karma-runner/karma-coffee-preprocessor +[karma-ng-html2js-preprocessor]: https://github.com/karma-runner/karma-ng-html2js-preprocessor +[karma-closure]: https://github.com/karma-runner/karma-closure +[karma-intellij]: https://github.com/karma-runner/karma-intellij +[node-di]: https://github.com/vojtajina/node-di +[karma-material-reporter]: https://github.com/ameerthehacker/karma-material-reporter +[plugins]: ../config/plugins.html diff --git a/lib/config.js b/lib/config.js index 30e874ee6..1192afbac 100644 --- a/lib/config.js +++ b/lib/config.js @@ -226,7 +226,7 @@ function normalizeConfig (config, configFilePath) { ? [preprocessors[pattern]] : preprocessors[pattern] }) - // define custom launchers/preprocessors/reporters - create an inlined plugin + // define custom launchers/preprocessors/reporters - create a new plugin const module = Object.create(null) let hasSomeInlinedPlugin = false const types = ['launcher', 'preprocessor', 'reporter'] diff --git a/lib/plugin.js b/lib/plugin.js index 20a180597..53dfc68a2 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -39,7 +39,7 @@ function resolve (plugins, emitter) { .filter((pluginName) => !IGNORED_PACKAGES.includes(pluginName) && regexp.test(pluginName)) .forEach((pluginName) => requirePlugin(`${pluginDirectory}/${pluginName}`)) } else if (helper.isObject(plugin)) { - log.debug(`Loading inlined plugin (defining ${Object.keys(plugin).join(', ')}).`) + log.debug(`Loading inline plugin defining ${Object.keys(plugin).join(', ')}.`) modules.push(plugin) } else { log.error(`Invalid plugin ${plugin}`) From f52a07199f7f589ab2bee1c1f2eb0cd2c05a0ce2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 12 Feb 2021 18:28:19 +0000 Subject: [PATCH 313/374] chore(release): 6.1.1 [skip ci] ## [6.1.1](https://github.com/karma-runner/karma/compare/v6.1.0...v6.1.1) (2021-02-12) ### Bug Fixes * **config:** check extension before ts-node register ([#3651](https://github.com/karma-runner/karma/issues/3651)) ([474f4e1](https://github.com/karma-runner/karma/commit/474f4e1caff469cce87f19a11d9179e4e05552f9)), closes [#3329](https://github.com/karma-runner/karma/issues/3329) * report launcher process error when exit event is not emitted ([#3647](https://github.com/karma-runner/karma/issues/3647)) ([7ab86be](https://github.com/karma-runner/karma/commit/7ab86be25c334b07747632b0a6bdb1d650d881bc)) --- CHANGELOG.md | 8 ++++++++ package-lock.json | 2 +- package.json | 4 +++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a094bdc61..ea0f26066 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [6.1.1](https://github.com/karma-runner/karma/compare/v6.1.0...v6.1.1) (2021-02-12) + + +### Bug Fixes + +* **config:** check extension before ts-node register ([#3651](https://github.com/karma-runner/karma/issues/3651)) ([474f4e1](https://github.com/karma-runner/karma/commit/474f4e1caff469cce87f19a11d9179e4e05552f9)), closes [#3329](https://github.com/karma-runner/karma/issues/3329) +* report launcher process error when exit event is not emitted ([#3647](https://github.com/karma-runner/karma/issues/3647)) ([7ab86be](https://github.com/karma-runner/karma/commit/7ab86be25c334b07747632b0a6bdb1d650d881bc)) + # [6.1.0](https://github.com/karma-runner/karma/compare/v6.0.4...v6.1.0) (2021-02-03) diff --git a/package-lock.json b/package-lock.json index fcebd843a..7e44ef44e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.1.0", + "version": "6.1.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fc9e84e62..93f23a5db 100644 --- a/package.json +++ b/package.json @@ -174,6 +174,7 @@ "Chang Wang ", "Chelsea Urquhart ", "Chris ", + "Chris Bottin ", "Chris Chua ", "Chris Dawson ", "Christian Weiss ", @@ -407,6 +408,7 @@ "thetrevdev ", "thorn0 ", "toran billups ", + "xel23 ", "chalkerx@gmail.com>", "weiran.zsd@outlook.com>" ], @@ -485,7 +487,7 @@ "engines": { "node": ">= 10" }, - "version": "6.1.0", + "version": "6.1.1", "license": "MIT", "husky": { "hooks": { From 5bfcf5f37de6f0a12abcf9914c2fad510395b4d6 Mon Sep 17 00:00:00 2001 From: Charles Suh Date: Mon, 8 Mar 2021 15:59:02 -0800 Subject: [PATCH 314/374] fix: patch karma to allow loading virtual packages (#3663) * fix: patch karma to allow loading virtual packages * fix: additional patch to handle SCRIPT_URL_ARRAY Co-authored-by: Shahriyar Nasir --- lib/middleware/karma.js | 6 ++-- test/unit/middleware/karma.spec.js | 45 ++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index 3a34b4e58..37e9a46c8 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -222,10 +222,10 @@ function createKarmaMiddleware ( }) : [] return data - .replace('%SCRIPTS%', scriptTags.join('\n')) + .replace('%SCRIPTS%', () => scriptTags.join('\n')) .replace('%CLIENT_CONFIG%', 'window.__karma__.config = ' + JSON.stringify(client) + ';\n') - .replace('%SCRIPT_URL_ARRAY%', 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n') - .replace('%MAPPINGS%', 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n') + .replace('%SCRIPT_URL_ARRAY%', () => 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n') + .replace('%MAPPINGS%', () => 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n') .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) }) }) diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js index 8a968262c..b6a0d5d59 100644 --- a/test/unit/middleware/karma.spec.js +++ b/test/unit/middleware/karma.spec.js @@ -28,6 +28,7 @@ describe('middleware.karma', () => { karma: { static: { 'client.html': mocks.fs.file(0, 'CLIENT HTML\n%X_UA_COMPATIBLE%%X_UA_COMPATIBLE_URL%'), + 'client_with_context.html': mocks.fs.file(0, 'CLIENT_WITH_CONTEXT\n%SCRIPT_URL_ARRAY%'), 'context.html': mocks.fs.file(0, 'CONTEXT\n%SCRIPTS%'), 'debug.html': mocks.fs.file(0, 'DEBUG\n%SCRIPTS%\n%X_UA_COMPATIBLE%'), 'karma.js': mocks.fs.file(0, 'root: %KARMA_URL_ROOT%, proxy: %KARMA_PROXY_PATH%, v: %KARMA_VERSION%') @@ -214,6 +215,21 @@ describe('middleware.karma', () => { callHandlerWith('/__karma__/context.html') }) + it('should serve context.html without using special patterns when replacing script tags', (done) => { + includedFiles([ + new MockFile('/.yarn/$$virtual/first.js', 'sha123'), + new MockFile('/.yarn/$$virtual/second.dart', 'sha456') + ]) + + response.once('end', () => { + expect(nextSpy).not.to.have.been.called + expect(response).to.beServedAs(200, 'CONTEXT\n\n') + done() + }) + + callHandlerWith('/__karma__/context.html') + }) + it('should serve context.html with replaced link tags', (done) => { includedFiles([ new MockFile('/first.css', 'sha007'), @@ -373,6 +389,20 @@ describe('middleware.karma', () => { callHandlerWith('/__karma__/context.html') }) + it('should inline mappings without using special patterns', (done) => { + fsMock._touchFile('/karma/static/context.html', 0, '%MAPPINGS%') + servedFiles([ + new MockFile('/.yarn/$$virtual/abc/a.js', 'sha_a') + ]) + + response.once('end', () => { + expect(response).to.beServedAs(200, "window.__karma__.files = {\n '/__proxy__/__karma__/absolute/.yarn/$$virtual/abc/a.js': 'sha_a'\n};\n") + done() + }) + + callHandlerWith('/__karma__/context.html') + }) + it('should escape quotes in mappings with all served files', (done) => { fsMock._touchFile('/karma/static/context.html', 0, '%MAPPINGS%') servedFiles([ @@ -490,4 +520,19 @@ describe('middleware.karma', () => { callHandlerWith('/__karma__/debug.html') }) + + it('should serve client_with_context.html without using special patterns when replacing script urls', (done) => { + includedFiles([ + new MockFile('/.yarn/$$virtual/first.js', 'sha123'), + new MockFile('/.yarn/$$virtual/second.dart', 'sha456') + ]) + + response.once('end', () => { + expect(nextSpy).not.to.have.been.called + expect(response).to.beServedAs(200, 'CLIENT_WITH_CONTEXT\nwindow.__karma__.scriptUrls = ["\\\\x3Cscript type=\\"text/javascript\\" src=\\"/__proxy__/__karma__/absolute/.yarn/$$virtual/first.js\\" crossorigin=\\"anonymous\\"\\\\x3E\\\\x3C/script\\\\x3E","\\\\x3Cscript type=\\"text/javascript\\" src=\\"/__proxy__/__karma__/absolute/.yarn/$$virtual/second.dart\\" crossorigin=\\"anonymous\\"\\\\x3E\\\\x3C/script\\\\x3E"];\n') + done() + }) + + callHandlerWith('/__karma__/client_with_context.html') + }) }) From 3fc6fdadd6b0ed6838de048c15485b1bd815fe23 Mon Sep 17 00:00:00 2001 From: Chris Bottin Date: Tue, 9 Mar 2021 00:06:33 +0000 Subject: [PATCH 315/374] fix(commitlint): skip task on master (#3650) --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7c1e548d8..e6bee9aca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,9 @@ jobs: - node_js: "14" script: - npm run init - - commitlint-travis + - if [[ "$TRAVIS_BRANCH" != "master" ]]; then + commitlint-travis; + fi; - npm run lint - npm run build:check - npm run test:unit From 10afab16bfc10b5199bb97207413c0045de442c1 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 9 Mar 2021 00:16:48 +0000 Subject: [PATCH 316/374] chore(release): 6.1.2 [skip ci] ## [6.1.2](https://github.com/karma-runner/karma/compare/v6.1.1...v6.1.2) (2021-03-09) ### Bug Fixes * **commitlint:** skip task on master ([#3650](https://github.com/karma-runner/karma/issues/3650)) ([3fc6fda](https://github.com/karma-runner/karma/commit/3fc6fdadd6b0ed6838de048c15485b1bd815fe23)) * patch karma to allow loading virtual packages ([#3663](https://github.com/karma-runner/karma/issues/3663)) ([5bfcf5f](https://github.com/karma-runner/karma/commit/5bfcf5f37de6f0a12abcf9914c2fad510395b4d6)) --- CHANGELOG.md | 8 ++++++++ package-lock.json | 2 +- package.json | 5 +++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea0f26066..e614239ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## [6.1.2](https://github.com/karma-runner/karma/compare/v6.1.1...v6.1.2) (2021-03-09) + + +### Bug Fixes + +* **commitlint:** skip task on master ([#3650](https://github.com/karma-runner/karma/issues/3650)) ([3fc6fda](https://github.com/karma-runner/karma/commit/3fc6fdadd6b0ed6838de048c15485b1bd815fe23)) +* patch karma to allow loading virtual packages ([#3663](https://github.com/karma-runner/karma/issues/3663)) ([5bfcf5f](https://github.com/karma-runner/karma/commit/5bfcf5f37de6f0a12abcf9914c2fad510395b4d6)) + ## [6.1.1](https://github.com/karma-runner/karma/compare/v6.1.0...v6.1.1) (2021-02-12) diff --git a/package-lock.json b/package-lock.json index 7e44ef44e..9bcac86e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.1.1", + "version": "6.1.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 93f23a5db..95562fd7e 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "Bryan Smith ", "Bulat Shakirzyanov ", "ChangZhuo Chen (陳昌倬) ", + "Chris Bottin ", "Cyrus Chan ", "DarthCharles ", "David Herges ", @@ -172,9 +173,9 @@ "Carl Goldberg ", "Chad Smith ", "Chang Wang ", + "Charles Suh ", "Chelsea Urquhart ", "Chris ", - "Chris Bottin ", "Chris Chua ", "Chris Dawson ", "Christian Weiss ", @@ -487,7 +488,7 @@ "engines": { "node": ">= 10" }, - "version": "6.1.1", + "version": "6.1.2", "license": "MIT", "husky": { "hooks": { From 39831b1c2f9cbeebdba94c73ce353efb7c44e802 Mon Sep 17 00:00:00 2001 From: hdmr14 <58992133+hdmr14@users.noreply.github.com> Date: Thu, 11 Mar 2021 08:26:24 +0900 Subject: [PATCH 317/374] feat(plugins): add support wildcard config for scoped package plugin (#3659) * feat(plugins): add support wildcard config for scoped package plugin * fix(plugins): support Node 10 --- lib/plugin.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/plugin.js b/lib/plugin.js index 53dfc68a2..8805a288d 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -32,12 +32,21 @@ function resolve (plugins, emitter) { return } const pluginDirectory = path.normalize(path.join(__dirname, '/../..')) - const regexp = new RegExp(`^${plugin.replace('*', '.*')}`) + const regexp = new RegExp(`^${plugin.replace(/\*/g, '.*').replace(/\//g, '[/\\\\]')}`) log.debug(`Loading ${plugin} from ${pluginDirectory}`) fs.readdirSync(pluginDirectory) - .filter((pluginName) => !IGNORED_PACKAGES.includes(pluginName) && regexp.test(pluginName)) - .forEach((pluginName) => requirePlugin(`${pluginDirectory}/${pluginName}`)) + .map((e) => { + const modulePath = path.join(pluginDirectory, e) + if (e[0] === '@') { + return fs.readdirSync(modulePath).map((e) => path.join(modulePath, e)) + } + return modulePath + }) + .reduce((a, x) => a.concat(x), []) + .map((modulePath) => path.relative(pluginDirectory, modulePath)) + .filter((moduleName) => !IGNORED_PACKAGES.includes(moduleName) && regexp.test(moduleName)) + .forEach((pluginName) => requirePlugin(path.join(pluginDirectory, pluginName))) } else if (helper.isObject(plugin)) { log.debug(`Loading inline plugin defining ${Object.keys(plugin).join(', ')}.`) modules.push(plugin) From a2bca0df0b9ca23ce8620eee1fc3935515ab8840 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 10 Mar 2021 23:35:19 +0000 Subject: [PATCH 318/374] chore(release): 6.2.0 [skip ci] # [6.2.0](https://github.com/karma-runner/karma/compare/v6.1.2...v6.2.0) (2021-03-10) ### Features * **plugins:** add support wildcard config for scoped package plugin ([#3659](https://github.com/karma-runner/karma/issues/3659)) ([39831b1](https://github.com/karma-runner/karma/commit/39831b1c2f9cbeebdba94c73ce353efb7c44e802)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e614239ee..3fff01afc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [6.2.0](https://github.com/karma-runner/karma/compare/v6.1.2...v6.2.0) (2021-03-10) + + +### Features + +* **plugins:** add support wildcard config for scoped package plugin ([#3659](https://github.com/karma-runner/karma/issues/3659)) ([39831b1](https://github.com/karma-runner/karma/commit/39831b1c2f9cbeebdba94c73ce353efb7c44e802)) + ## [6.1.2](https://github.com/karma-runner/karma/compare/v6.1.1...v6.1.2) (2021-03-09) diff --git a/package-lock.json b/package-lock.json index 9bcac86e7..ab7b36418 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.1.2", + "version": "6.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 95562fd7e..5c2110653 100644 --- a/package.json +++ b/package.json @@ -393,6 +393,7 @@ "deepak1556 ", "dorey ", "grifball ", + "hdmr14 <58992133+hdmr14@users.noreply.github.com>", "hrgdavor ", "ianjobling ", "inf3rno ", @@ -488,7 +489,7 @@ "engines": { "node": ">= 10" }, - "version": "6.1.2", + "version": "6.2.0", "license": "MIT", "husky": { "hooks": { From d3ff91a5a2f7ff84141096bb47aa31ff73f81cca Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Thu, 11 Mar 2021 01:06:11 +0100 Subject: [PATCH 319/374] test(plugins): add missing tests for plugin resolution logic (#3661) --- test/unit/plugin.spec.js | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/test/unit/plugin.spec.js b/test/unit/plugin.spec.js index 3ec9824d1..eac0c6ecf 100644 --- a/test/unit/plugin.spec.js +++ b/test/unit/plugin.spec.js @@ -1,5 +1,7 @@ 'use strict' +const path = require('path') +const proxyquire = require('proxyquire') const createInstantiatePlugin = require('../../lib/plugin').createInstantiatePlugin describe('plugin', () => { @@ -58,4 +60,51 @@ describe('plugin', () => { expect(fakes.emitter.emit).to.have.been.calledWith('load_error', 'unknown', 'name') }) }) + + describe('resolve', () => { + // Base path should be the same as the one produced by the code under test. + const base = path.resolve(__dirname, '..', '..', '..') + const directories = { + [base]: ['karma-fancy-plugin', 'other-package', 'karma-powerful-plugin', 'yet-another-package', '@scope'], + [path.join(base, '@scope')]: ['karma-super-plugin', 'not-a-plugin'] + } + + const { resolve } = proxyquire( + '../../lib/plugin', + { + 'graceful-fs': { readdirSync: (dir) => directories[dir] }, + 'karma-fancy-plugin': { name: 'karma-fancy-plugin', '@noCallThru': true }, + 'karma-powerful-plugin': { name: 'karma-powerful-plugin', '@noCallThru': true }, + '@scope/karma-super-plugin': { name: '@scope/karma-super-plugin', '@noCallThru': true }, + // Plugins are require()'d using an absolute path if they were resolved from the glob. + [path.join(base, 'karma-fancy-plugin')]: { name: 'karma-fancy-plugin', '@noCallThru': true }, + [path.join(base, 'karma-powerful-plugin')]: { name: 'karma-powerful-plugin', '@noCallThru': true }, + [path.join(base, '@scope/karma-super-plugin')]: { name: '@scope/karma-super-plugin', '@noCallThru': true } + } + ) + + it('loads simple plugin', () => { + const modules = resolve(['karma-powerful-plugin'], null) + + expect(modules.map((m) => m.name)).to.deep.equal(['karma-powerful-plugin']) + }) + + it('loads scoped plugin', () => { + const modules = resolve(['@scope/karma-super-plugin'], null) + + expect(modules.map((m) => m.name)).to.deep.equal(['@scope/karma-super-plugin']) + }) + + it('loads simple plugins with globs', () => { + const modules = resolve(['karma-*'], null) + + expect(modules.map((m) => m.name)).to.deep.equal(['karma-fancy-plugin', 'karma-powerful-plugin']) + }) + + it('loads scoped plugins with globs', () => { + const modules = resolve(['@*/karma-*'], null) + + expect(modules.map((m) => m.name)).to.deep.equal(['@scope/karma-super-plugin']) + }) + }) }) From 4c9097a59c666671aaa55177e03e8738e047e886 Mon Sep 17 00:00:00 2001 From: Nick Petruzzelli Date: Tue, 23 Mar 2021 16:25:46 -0400 Subject: [PATCH 320/374] feat: support asynchronous `config.set()` call in karma.conf.js (#3660) The existing sync behavior co-exists with the new async behavior. * add promise support to `parseConfig` * add async config support to `cli`, `runner`, and `stopper` * Additional API for `Server()` accepting parsed config. Older API is deprecated. * update documentation for parseConfig * add warning for deprecated use of CLI options * update Server constructor, runner, and stopper docs --- docs/dev/04-public-api.md | 289 ++++++++++++++++++++++++++++++++++---- lib/cli.js | 66 ++++++--- lib/config.js | 140 +++++++++++++++--- lib/runner.js | 37 ++++- lib/server.js | 43 ++++-- lib/stopper.js | 36 ++++- test/unit/cli.spec.js | 249 ++++++++++++++++++++++++++++++++ test/unit/config.spec.js | 139 +++++++++++++++--- test/unit/server.spec.js | 39 ++++- 9 files changed, 923 insertions(+), 115 deletions(-) diff --git a/docs/dev/04-public-api.md b/docs/dev/04-public-api.md index ff327a41a..717eb1855 100644 --- a/docs/dev/04-public-api.md +++ b/docs/dev/04-public-api.md @@ -4,7 +4,18 @@ You can, however, call Karma programmatically from your node module. Here is the ## karma.Server(options, [callback=process.exit]) -### Constructor +### `constructor` + +- **Returns:** `Server` instance. + +#### Usage + +Notice the capital 'S' on `require('karma').Server`. + +##### Deprecated Behavior + +The following still works, but the way it behaves is deprecated and will be +changed in a future major version. ```javascript var Server = require('karma').Server @@ -15,9 +26,29 @@ var server = new Server(karmaConfig, function(exitCode) { }) ``` -Notice the capital 'S' on `require('karma').Server`. +##### New Behavior + +```javascript +const karma = require('karma') +const parseConfig = karma.config.parseConfig +const Server = karma.Server + +parseConfig( + null, + { port: 9876 }, + { promiseConfig: true, throwErrors: true } +).then( + (karmaConfig) => { + const server = new Server(karmaConfig, function doneCallback(exitCode) { + console.log('Karma has exited with ' + exitCode) + process.exit(exitCode) + }) + }, + (rejectReason) => { /* respond to the rejection reason error */ } +); +``` -### **server.start()** +### `server.start()` Equivalent of `karma start`. @@ -25,7 +56,7 @@ Equivalent of `karma start`. server.start() ``` -### **server.refreshFiles()** +### `server.refreshFiles()` Trigger a file list refresh. Returns a promise. @@ -33,7 +64,7 @@ Trigger a file list refresh. Returns a promise. server.refreshFiles() ``` -### **server.refreshFile(path)** +### `server.refreshFile(path)` Trigger a file refresh. Returns a promise. @@ -117,10 +148,19 @@ This event gets triggered whenever all the browsers, which belong to a test run, ## karma.runner -### **runner.run(options, [callback=process.exit])** +### `runner.run(options, [callback=process.exit])` + +- **Returns:** `EventEmitter` The equivalent of `karma run`. +#### Usage + +##### Deprecated Behavior + +The following still works, but the way it behaves is deprecated and will be +changed in a future major version. + ```javascript var runner = require('karma').runner runner.run({port: 9876}, function(exitCode) { @@ -129,6 +169,35 @@ runner.run({port: 9876}, function(exitCode) { }) ``` +##### New Behavior + +```javascript +const karma = require('karma') + +karma.config.parseConfig( + null, + { port: 9876 }, + { promiseConfig: true, throwErrors: true } +).then( + (karmaConfig) => { + karma.runner.run(karmaConfig, function doneCallback(exitCode, possibleErrorCode) { + console.log('Karma has exited with ' + exitCode) + process.exit(exitCode) + }) + }, + (rejectReason) => { /* respond to the rejection reason error */ } +); +``` + +#### `callback` argument + +The callback receives the exit code as the first argument. + +If there is an error, the error code will be provided as the second parameter to +the error callback. + +#### runner Events + `runner.run()` returns an `EventEmitter` which emits a `progress` event passing the reporter output as a `Buffer` object. @@ -142,9 +211,17 @@ runner.run({port: 9876}).on('progress', function(data) { ## karma.stopper -### **stopper.stop(options, [callback=process.exit])** +### `stopper.stop(options, [callback=process.exit])` + +This function will signal a running server to stop. The equivalent of +`karma stop`. + +#### Usage + +##### Deprecated Behavior -This function will signal a running server to stop. The equivalent of `karma stop`. +The following still works, but the way it behaves is deprecated and will be +changed in a future major version. ```javascript var stopper = require('karma').stopper @@ -156,78 +233,228 @@ stopper.stop({port: 9876}, function(exitCode) { }) ``` -## karma.config.parseConfig([configFilePath], [cliOptions]) +##### New Behavior + +```javascript +const karma = require('karma') + +karma.config.parseConfig( + null, + { port: 9876 }, + { promiseConfig: true, throwErrors: true } +).then( + (karmaConfig) => { + karma.stopper.stop(karmaConfig, function doneCallback(exitCode, possibleErrorCode) { + if (exitCode === 0) { + console.log('Server stop as initiated') + } + process.exit(exitCode) + }) + }, + (rejectReason) => { /* respond to the rejection reason error */ } +); +``` + +#### `callback` argument + +The callback receives the exit code as the first argument. + +If there is an error, the error code will be provided as the second parameter to +the error callback. + +## karma.config + +### `config.parseConfig([configFilePath], [cliOptions], [parseOptions])` This function will load given config file and returns a filled config object. This can be useful if you want to integrate karma into another tool and want to load -the karma config while honoring the karma defaults. For example, the [stryker-karma-runner](https://github.com/stryker-mutator/stryker-karma-runner) -uses this to load your karma configuration and use that in the stryker configuration. +the karma config while honoring the karma defaults. + +#### Usage + +##### Deprecated Behavior + +The following still works, but the way it behaves is deprecated and will be +changed in a future major version. + +```javascript +const cfg = require('karma').config; +const path = require('path'); +// Read karma.conf.js, but override port with 1337 +const karmaConfig = cfg.parseConfig( + path.resolve('./karma.conf.js'), + { port: 1337 } +); +``` + +The new behavior in the future will involve throwing exceptions instead of +exiting the process and aynchronous config files will be supported through the +use of promises. + +##### New Behavior ```javascript const cfg = require('karma').config; const path = require('path'); // Read karma.conf.js, but override port with 1337 -const karmaConfig = cfg.parseConfig(path.resolve('./karma.conf.js'), { port: 1337 } ); +cfg.parseConfig( + path.resolve('./karma.conf.js'), + { port: 1337 }, + { promiseConfig: true, throwErrors: true } +).then( + (karmaConfig) => { /* use the config with the public API */ }, + (rejectReason) => { /* respond to the rejection reason error */ } +); ``` -## karma.constants -### **constants.VERSION** +#### `configFilePath` argument + +- **Type:** String | `null` | `undefined` +- **Default Value:** `undefined` + +A string representing a file system path pointing to the config file whose +default export is a function that will be used to set Karma configuration +options. This function will be passed an instance of the `Config` class as its +first argument. If this option is not provided, then only the options provided +by the `cliOptions` argument will be set. + +- JavaScript must use CommonJS modules. +- ECMAScript modules are not currently supported by Karma when using + JavaScript. + - Other formats, such as TypeScript, may support ECMAScript modules. + + +#### `cliOptions` argument + +- **Type:** Object | `null` | `undefined` +- **Default Value:** `undefined` + +An object whose values will take priority over options set in the config file. +The config object passed to function exported by the config file will already +have these options applied. Any changes the config file makes to these options +will effectively be ignored in the final configuration. + +Supports all the same options as the config file and is applied using the same +`config.set()` method. + +The expected source of this argument is parsed command line options, but +programatic users may construct this object or leave it out entirely. + + +#### `parseOptions` argument + +- **Type:** Object | `null` | `undefined` +- **Default Value:** `undefined` + +`parseOptions` is an object whose properties are configuration options that +allow additional control over parsing and opt-in access to new behaviors or +features. + +These options are only related to parsing configuration files and object and are +not related to the configuration of Karma itself. + + +##### `parseOptions.promiseConfig` option + +- **Type:** Boolean +- **Default Value:** `false` + +When `parseOptions.promiseConfig === true`, then `parseConfig` will return a +promise instead of a configuration object. + +When this option is `true`, then the function exported by the config file may +return a promise. The resolution of that promise indicates that all asynchronous +activity has been completed. Internally, the resolved/fulfilled value is +ignored. As with synchronous usage, all changes to the config object must be +done with the `config.set()` method. + +If the function exported by the config file does not return a promise, then +parsing is completed and an immediately fulfilled promise is returned. + +Whether the function exported by the config file returns a promise or not, the +promise returned by `parseConfig()` will resolve with a parsed configuration +object, an instance of the `Config` class, as the value. + +_**In most cases, `parseOptions.throwErrors = true` should also be set. This +disables process exiting and allows errors to result in rejected promises.**_ + + +##### `parseOptions.throwErrors` option + +- **Type:** Boolean +- **Default Value:** `false` + +In the past, `parseConfig()` would call `process.exit(exitCode)` when it +encountered a critical failure. This meant that your own code had no way of +responding to failures before the Node.js process exited. + +By passing `parseOptions.throwErrors = true`, `parseConfig()` will disable +process exiting. + +For synchronous usage, it will throw an exception instead of exiting the +process. Your code can then catch the exception and respond how ever it needs +to. + +If the asynchronous API (`parseOptions.promiseConfig = true`) is being used, +then `parseOptions.throwErrors = true` allows the promise to be rejected +instead of exiting the process. + + +## `karma.constants` + +### `constants.VERSION` The current version of karma -### **constants.DEFAULT_PORT** +### `constants.DEFAULT_PORT` The default port used for the karma server -### **constants.DEFAULT_HOSTNAME** +### `constants.DEFAULT_HOSTNAME` The default hostname used for the karma server -### **constants.DEFAULT_LISTEN_ADDR** +### `constants.DEFAULT_LISTEN_ADDR` The default address use for the karma server to listen on -### **constants.LOG_DISABLE** +### `constants.LOG_DISABLE` The value for disabling logs -### **constants.LOG_ERROR** +### `constants.LOG_ERROR` The value for the log `error` level -### **constants.LOG_WARN** +### `constants.LOG_WARN` The value for the log `warn` level -### **constants.LOG_INFO** +### `constants.LOG_INFO` The value for the log `info` level -### **constants.LOG_DEBUG** +### `constants.LOG_DEBUG` The value for the log `debug` level -### **constants.LOG_PRIORITIES** +### `constants.LOG_PRIORITIES` An array of log levels in descending order, i.e. `LOG_DISABLE`, `LOG_ERROR`, `LOG_WARN`, `LOG_INFO`, and `LOG_DEBUG` -### **constants.COLOR_PATTERN** +### `constants.COLOR_PATTERN` The default color pattern for log output -### **constants.NO_COLOR_PATTERN** +### `constants.NO_COLOR_PATTERN` The default pattern for log output without color -### **constants.CONSOLE_APPENDER** +### `constants.CONSOLE_APPENDER` The default console appender -### **constants.EXIT_CODE** +### `constants.EXIT_CODE` The exit code - -## Callback function notes - -- If there is an error, the error code will be provided as the second parameter to the error callback. diff --git a/lib/cli.js b/lib/cli.js index 6e7fdac4f..41950abd4 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -7,6 +7,7 @@ const fs = require('graceful-fs') const Server = require('./server') const helper = require('./helper') const constant = require('./constants') +const cfg = require('./config') function processArgs (argv, options, fs, path) { Object.getOwnPropertyNames(argv).forEach(function (name) { @@ -277,27 +278,50 @@ exports.process = () => { return processArgs(argv, { cmd: argv._.shift() }, fs, path) } -exports.run = () => { - const config = exports.process() - - switch (config.cmd) { - case 'start': - new Server(config).start() - break - case 'run': - require('./runner') - .run(config) - .on('progress', printRunnerProgress) - break - case 'stop': - require('./stopper').stop(config) - break - case 'init': - require('./init').init(config) - break - case 'completion': - require('./completion').completion(config) - break +exports.run = async () => { + const cliOptions = exports.process() + const cmd = cliOptions.cmd // prevent config from changing the command + const cmdNeedsConfig = cmd === 'start' || cmd === 'run' || cmd === 'stop' + if (cmdNeedsConfig) { + let config + try { + config = await cfg.parseConfig( + cliOptions.configFile, + cliOptions, + { + promiseConfig: true, + throwErrors: true + } + ) + } catch (karmaConfigException) { + // The reject reason/exception isn't used to log a message since + // parseConfig already calls a configured logger method with an almost + // identical message. + + // The `run` function is a private application, not a public API. We don't + // need to worry about process.exit vs throw vs promise rejection here. + process.exit(1) + } + switch (cmd) { + case 'start': { + const server = new Server(config) + await server.start() + return server + } + case 'run': + return require('./runner') + .run(config) + .on('progress', printRunnerProgress) + case 'stop': + return require('./stopper').stop(config) + } + } else { + switch (cmd) { + case 'init': + return require('./init').init(cliOptions) + case 'completion': + return require('./completion').completion(cliOptions) + } } } diff --git a/lib/config.js b/lib/config.js index 1192afbac..cd9510bfd 100644 --- a/lib/config.js +++ b/lib/config.js @@ -268,6 +268,9 @@ function normalizeConfig (config, configFilePath) { return config } +/** + * @class + */ class Config { constructor () { this.LOG_DISABLE = constant.LOG_DISABLE @@ -351,12 +354,61 @@ const CONFIG_SYNTAX_HELP = ' module.exports = function(config) {\n' + ' });\n' + ' };\n' +/** + * Retrieve a parsed and finalized Karma `Config` instance. This `karmaConfig` + * object may be used to configure public API methods such a `Server`, + * `runner.run`, and `stopper.stop`. + * + * @param {?string} [configFilePath=null] + * A string representing a file system path pointing to the config file + * whose default export is a function that will be used to set Karma + * configuration options. This function will be passed an instance of the + * `Config` class as its first argument. If this option is not provided, + * then only the options provided by the `cliOptions` argument will be + * set. + * @param {Object} cliOptions + * An object whose values will take priority over options set in the + * config file. The config object passed to function exported by the + * config file will already have these options applied. Any changes the + * config file makes to these options will effectively be ignored in the + * final configuration. + * + * `cliOptions` all the same options as the config file and is applied + * using the same `config.set()` method. + * @param {Object} parseOptions + * @param {boolean} [parseOptions.promiseConfig=false] + * When `true`, a promise that resolves to a `Config` object will be + * returned. This also allows the function exported by config files (if + * provided) to be asynchronous by returning a promise. Resolving this + * promise indicates that all async activity has completed. The resolution + * value itself is ignored, all configuration must be done with + * `config.set`. + * @param {boolean} [parseOptions.throwErrors=false] + * When `true`, process exiting on critical failures will be disabled. In + * The error will be thrown as an exception. If + * `parseOptions.promiseConfig` is also `true`, then the error will + * instead be used as the promise's reject reason. + * @returns {Config|Promise} + */ function parseConfig (configFilePath, cliOptions, parseOptions) { + const promiseConfig = parseOptions && parseOptions.promiseConfig === true + const throwErrors = parseOptions && parseOptions.throwErrors === true + const shouldSetupLoggerEarly = promiseConfig + if (shouldSetupLoggerEarly) { + // `setupFromConfig` provides defaults for `colors` and `logLevel`. + // `setup` provides defaults for `appenders` + // The first argument MUST BE an object + logger.setupFromConfig({}) + } function fail () { log.error(...arguments) - if (parseOptions && parseOptions.throwErrors === true) { + if (throwErrors) { const errorMessage = Array.from(arguments).join(' ') - throw new Error(errorMessage) + const err = new Error(errorMessage) + if (promiseConfig) { + return Promise.reject(err) + } + throw err } else { const warningMessage = 'The `parseConfig()` function historically called `process.exit(1)`' + @@ -411,34 +463,76 @@ function parseConfig (configFilePath, cliOptions, parseOptions) { // add the user's configuration in config.set(cliOptions) + let configModuleReturn try { - configModule(config) + configModuleReturn = configModule(config) } catch (e) { return fail('Error in config file!\n', e) } + function finalizeConfig (config) { + // merge the config from config file and cliOptions (precedence) + config.set(cliOptions) - // merge the config from config file and cliOptions (precedence) - config.set(cliOptions) - - // if the user changed listenAddress, but didn't set a hostname, warn them - if (config.hostname === null && config.listenAddress !== null) { - log.warn(`ListenAddress was set to ${config.listenAddress} but hostname was left as the default: ` + + // if the user changed listenAddress, but didn't set a hostname, warn them + if (config.hostname === null && config.listenAddress !== null) { + log.warn(`ListenAddress was set to ${config.listenAddress} but hostname was left as the default: ` + `${defaultHostname}. If your browsers fail to connect, consider changing the hostname option.`) - } - // restore values that weren't overwritten by the user - if (config.hostname === null) { - config.hostname = defaultHostname - } - if (config.listenAddress === null) { - config.listenAddress = defaultListenAddress - } - - // configure the logger as soon as we can - logger.setup(config.logLevel, config.colors, config.loggers) - - log.debug(configFilePath ? `Loading config ${configFilePath}` : 'No config file specified.') + } + // restore values that weren't overwritten by the user + if (config.hostname === null) { + config.hostname = defaultHostname + } + if (config.listenAddress === null) { + config.listenAddress = defaultListenAddress + } - return normalizeConfig(config, configFilePath) + // configure the logger as soon as we can + logger.setup(config.logLevel, config.colors, config.loggers) + + log.debug(configFilePath ? `Loading config ${configFilePath}` : 'No config file specified.') + + return normalizeConfig(config, configFilePath) + } + + /** + * Return value is a function or (non-null) object that has a `then` method. + * + * @type {boolean} + * @see {@link https://promisesaplus.com/} + */ + const returnIsThenable = ( + ( + (configModuleReturn != null && typeof configModuleReturn === 'object') || + typeof configModuleReturn === 'function' + ) && typeof configModuleReturn.then === 'function' + ) + if (returnIsThenable) { + if (promiseConfig !== true) { + const errorMessage = + 'The `parseOptions.promiseConfig` option must be set to `true` to ' + + 'enable promise return values from configuration files. ' + + 'Example: `parseConfig(path, cliOptions, { promiseConfig: true })`' + return fail(errorMessage) + } + return configModuleReturn.then( + function onKarmaConfigModuleFulfilled (/* ignoredResolutionValue */) { + return finalizeConfig(config) + }, + function onKarmaConfigModuleRejected (reason) { + return fail('Error in config file!\n', reason) + } + ) + } else { + if (promiseConfig) { + try { + return Promise.resolve(finalizeConfig(config)) + } catch (exception) { + return Promise.reject(exception) + } + } else { + return finalizeConfig(config) + } + } } // PUBLIC API diff --git a/lib/runner.js b/lib/runner.js index e98a39da1..7d07bb08b 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -32,14 +32,39 @@ function parseExitCode (buffer, defaultExitCode, failOnEmptyTestSuite) { } // TODO(vojta): read config file (port, host, urlRoot) -function run (config, done) { - config = config || {} - - logger.setupFromConfig(config) - +function run (cliOptionsOrConfig, done) { + cliOptionsOrConfig = cliOptionsOrConfig || {} done = helper.isFunction(done) ? done : process.exit - config = cfg.parseConfig(config.configFile, config) + let config + if (cliOptionsOrConfig instanceof cfg.Config) { + config = cliOptionsOrConfig + } else { + logger.setupFromConfig({ + colors: cliOptionsOrConfig.colors, + logLevel: cliOptionsOrConfig.logLevel + }) + const deprecatedCliOptionsMessage = + 'Passing raw CLI options to `runner(config, done)` is deprecated. Use ' + + '`parseConfig(configFilePath, cliOptions, {promiseConfig: true, throwErrors: true})` ' + + 'to prepare a processed `Config` instance and pass that as the ' + + '`config` argument instead.' + log.warn(deprecatedCliOptionsMessage) + try { + config = cfg.parseConfig( + cliOptionsOrConfig.configFile, + cliOptionsOrConfig, + { + promiseConfig: false, + throwErrors: true + } + ) + } catch (parseConfigError) { + // TODO: change how `done` falls back to exit in next major version + // SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378 + done(1) + } + } let exitCode = 1 const emitter = new EventEmitter() const options = { diff --git a/lib/server.js b/lib/server.js index a6ae81dab..cec1ecd0b 100644 --- a/lib/server.js +++ b/lib/server.js @@ -55,22 +55,43 @@ function createSocketIoServer (webServer, executor, config) { } class Server extends KarmaEventEmitter { - constructor (cliOptions, done) { + constructor (cliOptionsOrConfig, done) { super() - logger.setupFromConfig(cliOptions) - + cliOptionsOrConfig = cliOptionsOrConfig || {} this.log = logger.create('karma-server') - + done = helper.isFunction(done) ? done : process.exit this.loadErrors = [] let config - try { - config = cfg.parseConfig(cliOptions.configFile, cliOptions, { throwErrors: true }) - } catch (parseConfigError) { - // TODO: change how `done` falls back to exit in next major version - // SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378 - (done || process.exit)(1) - return + if (cliOptionsOrConfig instanceof cfg.Config) { + config = cliOptionsOrConfig + } else { + logger.setupFromConfig({ + colors: cliOptionsOrConfig.colors, + logLevel: cliOptionsOrConfig.logLevel + }) + const deprecatedCliOptionsMessage = + 'Passing raw CLI options to `new Server(config, done)` is ' + + 'deprecated. Use ' + + '`parseConfig(configFilePath, cliOptions, {promiseConfig: true, throwErrors: true})` ' + + 'to prepare a processed `Config` instance and pass that as the ' + + '`config` argument instead.' + this.log.warn(deprecatedCliOptionsMessage) + try { + config = cfg.parseConfig( + cliOptionsOrConfig.configFile, + cliOptionsOrConfig, + { + promiseConfig: false, + throwErrors: true + } + ) + } catch (parseConfigError) { + // TODO: change how `done` falls back to exit in next major version + // SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378 + done(1) + return + } } this.log.debug('Final config', util.inspect(config, false, /** depth **/ null)) diff --git a/lib/stopper.js b/lib/stopper.js index 5e87be595..964eb5e37 100644 --- a/lib/stopper.js +++ b/lib/stopper.js @@ -3,12 +3,40 @@ const cfg = require('./config') const logger = require('./logger') const helper = require('./helper') -exports.stop = function (config, done) { - config = config || {} - logger.setupFromConfig(config) +exports.stop = function (cliOptionsOrConfig, done) { + cliOptionsOrConfig = cliOptionsOrConfig || {} const log = logger.create('stopper') done = helper.isFunction(done) ? done : process.exit - config = cfg.parseConfig(config.configFile, config) + + let config + if (cliOptionsOrConfig instanceof cfg.Config) { + config = cliOptionsOrConfig + } else { + logger.setupFromConfig({ + colors: cliOptionsOrConfig.colors, + logLevel: cliOptionsOrConfig.logLevel + }) + const deprecatedCliOptionsMessage = + 'Passing raw CLI options to `stopper(config, done)` is deprecated. Use ' + + '`parseConfig(configFilePath, cliOptions, {promiseConfig: true, throwErrors: true})` ' + + 'to prepare a processed `Config` instance and pass that as the ' + + '`config` argument instead.' + log.warn(deprecatedCliOptionsMessage) + try { + config = cfg.parseConfig( + cliOptionsOrConfig.configFile, + cliOptionsOrConfig, + { + promiseConfig: false, + throwErrors: true + } + ) + } catch (parseConfigError) { + // TODO: change how `done` falls back to exit in next major version + // SEE: https://github.com/karma-runner/karma/pull/3635#discussion_r565399378 + done(1) + } + } const request = http.request({ hostname: config.hostname, diff --git a/test/unit/cli.spec.js b/test/unit/cli.spec.js index 222e92c04..e59711288 100644 --- a/test/unit/cli.spec.js +++ b/test/unit/cli.spec.js @@ -2,6 +2,7 @@ const path = require('path') const mocks = require('mocks') +const proxyquire = require('proxyquire') const cli = require('../../lib/cli') const constant = require('../../lib/constants') @@ -206,4 +207,252 @@ describe('cli', () => { expect(args).to.deep.equal(['aa', '--bb', 'value']) }) }) + + describe('run', () => { + const COMMAND_COMPLETION = 'completion' + const COMMAND_INIT = 'init' + const COMMAND_RUN = 'run' + const COMMAND_START = 'start' + const COMMAND_STOP = 'stop' + const consoleErrorOriginal = console.error + const processExitOriginal = process.exit + let cliModule + let cliProcessFake = null + let completionFake = null + let initFake = null + let parseConfigFake = null + let runEmitterFake = null + let runFake = null + let ServerFake = null + let serverStartFake = null + let stopFake = null + let testCommand = null + let forceConfigFailure = false + + // `cliProcessFake` is used in multiple scopes, but not needed by the top + // scope. By using a factory, we can maintain one copy of the code in a + // single location while still having access to scopped variables that we + // need. + function createCliProcessFake () { + return sinon.fake(function cliProcessFake () { + const cliOptions = {} + if ( + testCommand === COMMAND_COMPLETION || + testCommand === COMMAND_INIT || + testCommand === COMMAND_RUN || + testCommand === COMMAND_START || + testCommand === COMMAND_STOP + ) { + cliOptions.cmd = testCommand + } else { + const errorMessage = + 'cli.spec.js: A valid command must be provided when testing the' + + 'exported `run()` method.' + throw new Error(errorMessage) + } + if (forceConfigFailure === true) { + cliOptions.forceConfigFailure = true + } + return cliOptions + }) + } + + before(() => { + proxyquire.noPreserveCache() + }) + + beforeEach(() => { + // Keep the test output clean + console.error = sinon.spy() + + // Keep the process from actually exiting + process.exit = sinon.spy() + + completionFake = sinon.fake() + initFake = sinon.fake() + parseConfigFake = sinon.fake(function parseConfigFake () { + const cliOptions = arguments[1] + + // Allow individual tests to test against success and failure without + // needing to manage multiple sinon fakes. + const forceConfigFailure = cliOptions && cliOptions.forceConfigFailure === true + if (forceConfigFailure) { + // No need to mock out the synchronous API, the CLI is not intended to + // use it + return Promise.reject(new Error('Intentional Failure For Testing')) + } + + // Most of our tests will ignore the actual config as the CLI passes it + // on to other methods that are tested elsewhere + const karmaConfig = { + ...cliOptions, + isFakeParsedConfig: true + } + return Promise.resolve(karmaConfig) + }) + runEmitterFake = {} + runEmitterFake.on = sinon.fake.returns(runEmitterFake) + runFake = sinon.fake.returns(runEmitterFake) + serverStartFake = sinon.fake.resolves() + ServerFake = sinon.fake.returns({ start: serverStartFake }) + stopFake = sinon.fake() + cliModule = proxyquire( + '../../lib/cli', + { + './completion': { + completion: completionFake + }, + './config': { + parseConfig: parseConfigFake + }, + './init': { + init: initFake + }, + './runner': { + run: runFake + }, + './server': ServerFake, + './stopper': { + stop: stopFake + } + } + ) + }) + + afterEach(() => { + // Restore globals, simultaneously removing references to the spies. + console.error = consoleErrorOriginal + process.exit = processExitOriginal + + // Reset the test command + testCommand = null + + // Most tests won't be testing what happens during a configuration failure + // Here we clean up after the ones that do. + forceConfigFailure = false + + // Restores all replaced properties set by sinon methods (`replace`, + // `spy`, and `stub`) + sinon.restore() + + // Remove references to Fakes that were not handled above. Avoids `before` + // and `beforeEach` aside effects and references not getting cleaned up + // after the last test. + cliModule = null + cliProcessFake = null + completionFake = null + initFake = null + parseConfigFake = null + runEmitterFake = null + runFake = null + ServerFake = null + serverStartFake = null + stopFake = null + }) + + after(() => { + proxyquire.preserveCache() + }) + + describe('commands', () => { + let cliProcessOriginal + beforeEach(() => { + cliProcessFake = createCliProcessFake() + cliProcessOriginal = cliModule.process + cliModule.process = cliProcessFake + }) + afterEach(() => { + if (cliModule) { + cliModule.process = cliProcessOriginal + } + }) + describe(COMMAND_COMPLETION, () => { + beforeEach(() => { + testCommand = COMMAND_COMPLETION + }) + it('should configure and call the completion method of the completion module', async () => { + await cliModule.run() + expect(completionFake.calledOnce).to.be.true + expect(completionFake.firstCall.args[0]).to.eql({ + cmd: COMMAND_COMPLETION + }) + }) + }) + describe(COMMAND_INIT, () => { + beforeEach(() => { + testCommand = COMMAND_INIT + }) + it('should configure and call the init method of the init module', async () => { + await cliModule.run() + expect(initFake.calledOnce).to.be.true + expect(initFake.firstCall.args[0]).to.eql({ + cmd: COMMAND_INIT + }) + }) + }) + describe(COMMAND_RUN, () => { + beforeEach(() => { + testCommand = COMMAND_RUN + }) + it('should configure and call the run method of the runner module', async () => { + await cliModule.run() + expect(runFake.calledOnce).to.be.true + expect(runFake.firstCall.args[0]).to.eql({ + cmd: COMMAND_RUN, + isFakeParsedConfig: true + }) + expect(runEmitterFake.on.calledOnce).to.be.true + expect(runEmitterFake.on.firstCall.args[0]).to.be.equal('progress') + }) + }) + describe(COMMAND_START, () => { + beforeEach(() => { + testCommand = COMMAND_START + }) + it('should configure and start the server', async () => { + await cliModule.run() + expect(ServerFake.calledOnce).to.be.true + expect(ServerFake.firstCall.args[0]).to.eql({ + cmd: COMMAND_START, + isFakeParsedConfig: true + }) + expect(serverStartFake.calledOnce).to.be.true + }) + }) + describe(COMMAND_STOP, () => { + beforeEach(() => { + testCommand = COMMAND_STOP + }) + it('should configure and call the stop method of the stopper module', async () => { + await cliModule.run() + expect(stopFake.calledOnce).to.be.true + expect(stopFake.firstCall.args[0]).to.eql({ + cmd: COMMAND_STOP, + isFakeParsedConfig: true + }) + }) + }) + }) + describe('configuration failure', () => { + let cliProcessOriginal + beforeEach(() => { + forceConfigFailure = true + testCommand = COMMAND_START + + cliProcessFake = createCliProcessFake() + cliProcessOriginal = cliModule.process + cliModule.process = cliProcessFake + }) + afterEach(() => { + if (cliModule) { + cliModule.process = cliProcessOriginal + } + }) + it('should exit the process with a non-zero exit code when configuration parsing fails', async () => { + await cliModule.run() + expect(process.exit.calledOnce).to.be.true + expect(process.exit.firstCall.args[0]).not.to.be.equal(0) + }) + }) + }) }) diff --git a/test/unit/config.spec.js b/test/unit/config.spec.js index d115a2b6e..ddab67910 100644 --- a/test/unit/config.spec.js +++ b/test/unit/config.spec.js @@ -30,6 +30,9 @@ describe('config', () => { const wrapCfg = function (cfg) { return (config) => config.set(cfg) } + const wrapAsyncCfg = function (cfg) { + return async (config) => config.set(cfg) + } beforeEach(() => { mocks = {} @@ -52,7 +55,12 @@ describe('config', () => { '/conf/absolute.js': wrapCfg({ files: ['http://some.com', 'https://more.org/file.js'] }), '/conf/both.js': wrapCfg({ files: ['one.js', 'two.js'], exclude: ['third.js'] }), '/conf/coffee.coffee': wrapCfg({ files: ['one.js', 'two.js'] }), - '/conf/default-export.js': { default: wrapCfg({ files: ['one.js', 'two.js'] }) } + '/conf/default-export.js': { default: wrapCfg({ files: ['one.js', 'two.js'] }) }, + '/conf/default-config': function noOperations () {}, + '/conf/returns-promise-that-resolves.js': wrapAsyncCfg({ foo: 'bar' }), + '/conf/returns-promise-that-rejects.js': () => { + return Promise.reject(new Error('Unexpected Error')) + } } // load file under test @@ -60,6 +68,7 @@ describe('config', () => { global: {}, process: mocks.process, Error: Error, // Without this, chai's `.throw()` assertion won't correctly check against constructors. + Promise: Promise, require (path) { if (mockConfigs[path]) { return mockConfigs[path] @@ -75,10 +84,22 @@ describe('config', () => { }) describe('parseConfig', () => { - let logSpy + let logErrorStub + let logWarnStub + let processExitStub beforeEach(() => { - logSpy = sinon.spy(logger.create('config'), 'error') + const log = logger.create('config') + // Silence and monitor logged errors and warnings, regardless of the + // `logLevel` option. + logErrorStub = sinon.stub(log, 'error') + logWarnStub = sinon.stub(log, 'warn') + processExitStub = sinon.stub(process, 'exit') + }) + afterEach(() => { + logErrorStub.restore() + logWarnStub.restore() + processExitStub.restore() }) it('should resolve relative basePath to config directory', () => { @@ -116,24 +137,24 @@ describe('config', () => { expect(config.exclude).to.deep.equal(actual) }) - it('should log error and exit if file does not exist', () => { + it('should log an error and exit if file does not exist', () => { e.parseConfig('/conf/not-exist.js', {}) - expect(logSpy).to.have.been.called - const event = logSpy.lastCall.args + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args expect(event.toString().split('\n').slice(0, 2)).to.be.deep.equal( ['Error in config file!', ' Error: Cannot find module \'/conf/not-exist.js\'']) expect(mocks.process.exit).to.have.been.calledWith(1) }) - it('should log error and throw if file does not exist AND throwErrors is true', () => { + it('should log an error and throw if file does not exist AND throwErrors is true', () => { function parseConfig () { e.parseConfig('/conf/not-exist.js', {}, { throwErrors: true }) } expect(parseConfig).to.throw(Error, 'Error in config file!\n Error: Cannot find module \'/conf/not-exist.js\'') - expect(logSpy).to.have.been.called - const event = logSpy.lastCall.args + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args expect(event.toString().split('\n').slice(0, 2)).to.be.deep.equal( ['Error in config file!', ' Error: Cannot find module \'/conf/not-exist.js\'']) expect(mocks.process.exit).not.to.have.been.called @@ -142,8 +163,8 @@ describe('config', () => { it('should log an error and exit if invalid file', () => { e.parseConfig('/conf/invalid.js', {}) - expect(logSpy).to.have.been.called - const event = logSpy.lastCall.args + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args expect(event[0]).to.eql('Error in config file!\n') expect(event[1].message).to.eql('Unexpected token =') expect(mocks.process.exit).to.have.been.calledWith(1) @@ -155,8 +176,8 @@ describe('config', () => { } expect(parseConfig).to.throw(Error, 'Error in config file!\n SyntaxError: Unexpected token =') - expect(logSpy).to.have.been.called - const event = logSpy.lastCall.args + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args expect(event[0]).to.eql('Error in config file!\n') expect(event[1].message).to.eql('Unexpected token =') expect(mocks.process.exit).not.to.have.been.called @@ -168,13 +189,97 @@ describe('config', () => { } expect(parseConfig).to.throw(Error, 'Config file must export a function!\n') - expect(logSpy).to.have.been.called - const event = logSpy.lastCall.args + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args expect(event.toString().split('\n').slice(0, 1)).to.be.deep.equal( ['Config file must export a function!']) expect(mocks.process.exit).not.to.have.been.called }) + it('should log an error and fail when the config file\'s function returns a promise, but `parseOptions.promiseConfig` is not true', () => { + function parseConfig () { + e.parseConfig( + '/conf/returns-promise-that-resolves.js', {}, { throwErrors: true } + ) + } + const expectedErrorMessage = + 'The `parseOptions.promiseConfig` option must be set to `true` to ' + + 'enable promise return values from configuration files. ' + + 'Example: `parseConfig(path, cliOptions, { promiseConfig: true })`' + + expect(parseConfig).to.throw(Error, expectedErrorMessage) + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args + expect(event[0]).to.be.eql(expectedErrorMessage) + expect(mocks.process.exit).not.to.have.been.called + }) + + describe('when `parseOptions.promiseConfig` is true', () => { + it('should return a promise when promiseConfig is true', () => { + // Return value should always be a promise, regardless of whether or not + // the config file itself is synchronous or asynchronous and when no + // config file path is provided at all. + const noConfigFilePromise = e.parseConfig( + null, null, { promiseConfig: true } + ) + const syncConfigPromise = e.parseConfig( + '/conf/default-config', null, { promiseConfig: true } + ) + const asyncConfigPromise = e.parseConfig( + '/conf/returns-promise-that-resolves.js', + null, + { promiseConfig: true } + ) + + expect(noConfigFilePromise).to.be.an.instanceof( + Promise, + 'Expected parseConfig to return a promise when no config file path is provided.' + ) + expect(syncConfigPromise).to.be.an.instanceof( + Promise, + 'Expected parseConfig to return a promise when the config file DOES NOT return a promise.' + ) + expect(asyncConfigPromise).to.be.an.instanceof( + Promise, + 'Expected parseConfig to return a promise when the config file returns a promise.' + ) + }) + + it('should log an error and exit if invalid file', () => { + e.parseConfig('/conf/invalid.js', {}, { promiseConfig: true }) + + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args + expect(event[0]).to.eql('Error in config file!\n') + expect(event[1].message).to.eql('Unexpected token =') + expect(mocks.process.exit).to.have.been.calledWith(1) + }) + + it('should log an error and reject the promise if the config file rejects the promise returned by its function AND throwErrors is true', async () => { + const configThatRejects = e.parseConfig('/conf/returns-promise-that-rejects.js', {}, { promiseConfig: true, throwErrors: true }).catch((reason) => { + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args + expect(event[0]).to.eql('Error in config file!\n') + expect(event[1].message).to.eql('Unexpected Error') + expect(reason.message).to.eql('Error in config file!\n Error: Unexpected Error') + expect(reason).to.be.an.instanceof(Error) + }) + return configThatRejects + }) + + it('should log an error and reject the promise if invalid file AND throwErrors is true', async () => { + const configThatThrows = e.parseConfig('/conf/invalid.js', {}, { promiseConfig: true, throwErrors: true }).catch((reason) => { + expect(logErrorStub).to.have.been.called + const event = logErrorStub.lastCall.args + expect(event[0]).to.eql('Error in config file!\n') + expect(event[1].message).to.eql('Unexpected token =') + expect(reason.message).to.eql('Error in config file!\n SyntaxError: Unexpected token =') + expect(reason).to.be.an.instanceof(Error) + }) + return configThatThrows + }) + }) + it('should override config with given cli options', () => { const config = e.parseConfig('/home/config4.js', { port: 456, autoWatch: false }) @@ -288,7 +393,7 @@ describe('config', () => { it('should not read config file, when null', () => { const config = e.parseConfig(null, { basePath: '/some' }) - expect(logSpy).not.to.have.been.called + expect(logErrorStub).not.to.have.been.called expect(config.basePath).to.equal(resolveWinPath('/some')) // overridden by CLI expect(config.urlRoot).to.equal('/') }) // default value @@ -296,7 +401,7 @@ describe('config', () => { it('should not read config file, when null but still resolve cli basePath', () => { const config = e.parseConfig(null, { basePath: './some' }) - expect(logSpy).not.to.have.been.called + expect(logErrorStub).not.to.have.been.called expect(config.basePath).to.equal(resolveWinPath('./some')) expect(config.urlRoot).to.equal('/') }) // default value diff --git a/test/unit/server.spec.js b/test/unit/server.spec.js index 6523a709d..fceaebe4c 100644 --- a/test/unit/server.spec.js +++ b/test/unit/server.spec.js @@ -2,6 +2,7 @@ const Server = require('../../lib/server') const NetUtils = require('../../lib/utils/net-utils') const BrowserCollection = require('../../lib/browser_collection') const Browser = require('../../lib/browser') +const cfg = require('../../lib/config') const logger = require('../../lib/logger') describe('server', () => { @@ -16,7 +17,9 @@ describe('server', () => { let mockBoundServer let mockExecutor let doneStub + let log let logErrorSpy + let logWarnStub let server = mockConfig = browserCollection = webServerOnError = null let fileListOnResolve = fileListOnReject = mockLauncher = null let mockFileList = mockWebServer = mockSocketServer = mockExecutor = doneStub = null @@ -28,7 +31,9 @@ describe('server', () => { this.timeout(4000) browserCollection = new BrowserCollection() doneStub = sinon.stub() - logErrorSpy = sinon.spy(logger.create('karma-server'), 'error') + log = logger.create('karma-server') + logErrorSpy = sinon.spy(log, 'error') + logWarnStub = sinon.stub(log, 'warn') fileListOnResolve = fileListOnReject = null @@ -46,7 +51,6 @@ describe('server', () => { browserDisconnectTolerance: 0, browserNoActivityTimeout: 0 } - server = new Server(mockConfig, doneStub) sinon.stub(server._injector, 'invoke').returns([]) @@ -126,6 +130,37 @@ describe('server', () => { webServerOnError = null }) + afterEach(() => { + logWarnStub.restore() + }) + + describe('constructor', () => { + it('should log a warning when the first argument is not an instance of Config', async () => { + // Reset the spy interface on the stub. It may have already been called by + // code in the `before` or `beforeEach` hooks. + logWarnStub.resetHistory() + + const rawConfig = { + karmaConfigForTest: true + } + return cfg.parseConfig( + null, + rawConfig, + { promiseConfig: true, throwErrors: true } + ).then((parsedConfig) => { + const messageSubstring = + 'Passing raw CLI options to `new Server(config, done)` is ' + + 'deprecated.' + + const serverWithParsed = new Server(parsedConfig, doneStub) // eslint-disable-line no-unused-vars + expect(logWarnStub).to.not.have.been.calledWith(sinon.match(messageSubstring)) + + const serverWithRaw = new Server(rawConfig, doneStub) // eslint-disable-line no-unused-vars + expect(logWarnStub).to.have.been.calledOnceWith(sinon.match(messageSubstring)) + }) + }) + }) + describe('start', () => { let config beforeEach(() => { From 3eb7ee7c8be0fdaf56aeef7a15910d89656d80a0 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 23 Mar 2021 20:33:35 +0000 Subject: [PATCH 321/374] chore(release): 6.3.0 [skip ci] # [6.3.0](https://github.com/karma-runner/karma/compare/v6.2.0...v6.3.0) (2021-03-23) ### Features * support asynchronous `config.set()` call in karma.conf.js ([#3660](https://github.com/karma-runner/karma/issues/3660)) ([4c9097a](https://github.com/karma-runner/karma/commit/4c9097a59c666671aaa55177e03e8738e047e886)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fff01afc..254adedb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [6.3.0](https://github.com/karma-runner/karma/compare/v6.2.0...v6.3.0) (2021-03-23) + + +### Features + +* support asynchronous `config.set()` call in karma.conf.js ([#3660](https://github.com/karma-runner/karma/issues/3660)) ([4c9097a](https://github.com/karma-runner/karma/commit/4c9097a59c666671aaa55177e03e8738e047e886)) + # [6.2.0](https://github.com/karma-runner/karma/compare/v6.1.2...v6.2.0) (2021-03-10) diff --git a/package-lock.json b/package-lock.json index ab7b36418..9b1e0bebb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.2.0", + "version": "6.3.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5c2110653..335529c90 100644 --- a/package.json +++ b/package.json @@ -294,6 +294,7 @@ "Nick Carter ", "Nick McCurdy ", "Nick Payne ", + "Nick Petruzzelli ", "Nick Petruzzelli ", "Nick Williams ", "Nicolas Artman ", @@ -489,7 +490,7 @@ "engines": { "node": ">= 10" }, - "version": "6.2.0", + "version": "6.3.0", "license": "MIT", "husky": { "hooks": { From c0962e34fb2c0a7a43bead8d600ad4a6dbb29c3d Mon Sep 17 00:00:00 2001 From: johnjbarton Date: Wed, 24 Mar 2021 14:07:14 -0700 Subject: [PATCH 322/374] fix(client): clearContext after complete sent (#3657) When useiframe false and clearContext true and IE11, the clearContext blocks the complete event. --- client/karma.js | 7 +++---- static/karma.js | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/client/karma.js b/client/karma.js index 5586bdc9e..0cc7556e0 100644 --- a/client/karma.js +++ b/client/karma.js @@ -236,13 +236,12 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) // to ensure the error from an incorrect navigate is processed. var config = this.config setTimeout(function () { + socket.emit('complete', result || {}) if (config.clearContext) { navigateContextTo('about:blank') + } else { + self.updater.updateTestStatus('complete') } - - socket.emit('complete', result || {}) - self.updater.updateTestStatus('complete') - if (returnUrl) { location.href = returnUrl } diff --git a/static/karma.js b/static/karma.js index 23b7c1ae2..b630fe256 100644 --- a/static/karma.js +++ b/static/karma.js @@ -246,13 +246,12 @@ function Karma (updater, socket, iframe, opener, navigator, location, document) // to ensure the error from an incorrect navigate is processed. var config = this.config setTimeout(function () { + socket.emit('complete', result || {}) if (config.clearContext) { navigateContextTo('about:blank') + } else { + self.updater.updateTestStatus('complete') } - - socket.emit('complete', result || {}) - self.updater.updateTestStatus('complete') - if (returnUrl) { location.href = returnUrl } From 026fff870913fb6cd2858dd962935dc74c92b725 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 24 Mar 2021 21:15:01 +0000 Subject: [PATCH 323/374] chore(release): 6.3.1 [skip ci] ## [6.3.1](https://github.com/karma-runner/karma/compare/v6.3.0...v6.3.1) (2021-03-24) ### Bug Fixes * **client:** clearContext after complete sent ([#3657](https://github.com/karma-runner/karma/issues/3657)) ([c0962e3](https://github.com/karma-runner/karma/commit/c0962e34fb2c0a7a43bead8d600ad4a6dbb29c3d)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 254adedb7..c46be943d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.3.1](https://github.com/karma-runner/karma/compare/v6.3.0...v6.3.1) (2021-03-24) + + +### Bug Fixes + +* **client:** clearContext after complete sent ([#3657](https://github.com/karma-runner/karma/issues/3657)) ([c0962e3](https://github.com/karma-runner/karma/commit/c0962e34fb2c0a7a43bead8d600ad4a6dbb29c3d)) + # [6.3.0](https://github.com/karma-runner/karma/compare/v6.2.0...v6.3.0) (2021-03-23) diff --git a/package-lock.json b/package-lock.json index 9b1e0bebb..f4762c2c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.3.0", + "version": "6.3.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 335529c90..40f32872f 100644 --- a/package.json +++ b/package.json @@ -490,7 +490,7 @@ "engines": { "node": ">= 10" }, - "version": "6.3.0", + "version": "6.3.1", "license": "MIT", "husky": { "hooks": { From 0055bc5cbf75597fa1601661bc4bec8cc701a49a Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Tue, 30 Mar 2021 01:19:38 +0200 Subject: [PATCH 324/374] fix: fix running tests in IE9 (#3668) So the symptom is that after Karma page is loaded in IE9 the tests don't run and Karma is stuck at the "starting" step. Reloading the page once or twice makes IE9 connect to the server and tests pass successfully. After an "exciting" debugging session I figured out that the problem is that on the first load (and sometimes after the page reload) [`io` variable](https://github.com/karma-runner/karma/blob/026fff870913fb6cd2858dd962935dc74c92b725/client/main.js#L14), which should be set by the `socket.io.js` script is undefined. It looks like IE9 silently stops executing `socket.io.js` script somewhere midway and switches to the next script causing the `io` variable to be undefined. I assume it hits some limit or threshold or whatnot. Couldn't find much information on the Internet, besides people experiencing similar issues when loading e.g. unminified jQuery and their own code firing before the `$` variable is available. No good solutions found. Checking the `socket.io.js` contents, I have noticed that v2 served the minified client script on that path, while v3 now serves the unminified code. Presumably the huge script size is what causing IE9 to choke. Switching back to the minified socket.io client bundle allows tests to pass in IE9. With the fix, tests passed 5 times in a row, while without it they fail every time, so I assume it does resolve the problem. Fixes #3665 --- static/client.html | 2 +- static/client_with_context.html | 2 +- test/client/karma.conf.js | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/static/client.html b/static/client.html index 9bc16cbce..4e069e1ef 100644 --- a/static/client.html +++ b/static/client.html @@ -109,7 +109,7 @@

    Karma - starting

    - + diff --git a/static/client_with_context.html b/static/client_with_context.html index e562bdee1..9f5f4b21b 100644 --- a/static/client_with_context.html +++ b/static/client_with_context.html @@ -104,7 +104,7 @@ - + diff --git a/docs/dev/03-maintaining.md b/docs/dev/03-maintaining.md index 6e541ffb1..5144ff571 100644 --- a/docs/dev/03-maintaining.md +++ b/docs/dev/03-maintaining.md @@ -21,7 +21,7 @@ An issue or pull request is untriaged (needs to be triaged) when it is not assig ## Merging a pull request Please, make sure: -- Travis build is green. +- CI build is green. - At least one owner (other than you) approved the PR - by commenting “LGTM” or something like that. - if it’s just a simple docs change or a typo fix, feel free to skip this step. diff --git a/package-lock.json b/package-lock.json index 38a279855..ef7fa5c4a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1003,58 +1003,6 @@ } } }, - "@commitlint/travis-cli": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@commitlint/travis-cli/-/travis-cli-8.3.5.tgz", - "integrity": "sha512-E456A36Ya9Zrr0+ONfkPoHNdWnX4zfR6seHjuzTy0393iSHNc9cZ250mGw0SKQiYQu8x1QHrQyWwyRXLb2iASw==", - "dev": true, - "requires": { - "@commitlint/cli": "^8.3.5", - "babel-runtime": "6.26.0", - "execa": "0.11.0" - }, - "dependencies": { - "execa": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.11.0.tgz", - "integrity": "sha512-k5AR22vCt1DcfeiRixW46U5tMLtBg44ssdJM9PiXw3D8Bn5qyxFCSnKY/eR22y+ctFDGPqafpaXg2G4Emyua4A==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - } - } - }, "@marionebl/sander": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/@marionebl/sander/-/sander-0.6.1.tgz", diff --git a/package.json b/package.json index e6511014e..758dfe39c 100644 --- a/package.json +++ b/package.json @@ -444,7 +444,6 @@ "devDependencies": { "@commitlint/cli": "^8.3.4", "@commitlint/config-conventional": "^8.3.4", - "@commitlint/travis-cli": "^8.3.5", "@semantic-release/changelog": "^3.0.6", "@semantic-release/git": "^7.0.18", "browserify": "^16.2.3", @@ -511,6 +510,7 @@ "build:check": "node scripts/client.js check", "build:watch": "node scripts/client.js watch", "test:integration": "./scripts/integration-tests.sh", - "semantic-release": "semantic-release" + "semantic-release": "semantic-release", + "commitlint": "commitlint" } } diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index 47dc56ed7..3dc337178 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -1,4 +1,8 @@ -const TRAVIS_WITH_BS = !!process.env.BROWSER_STACK_ACCESS_KEY +// When running pre-release tests we want tests to fail if BrowserStack is not +// configured instead of falling back to the headless browser. That's what +// KARMA_TEST_NO_FALLBACK variable controls. +const useBrowserStack = (process.env.BROWSERSTACK_USERNAME && process.env.BROWSERSTACK_ACCESS_KEY) || + process.env.KARMA_TEST_NO_FALLBACK const launchers = { bs_chrome: { @@ -35,14 +39,6 @@ const launchers = { } } -let browsers = ['Chrome'] - -if (process.env.TRAVIS) { - if (TRAVIS_WITH_BS) { - browsers = Object.keys(launchers) - } -} - module.exports = function (config) { config.set({ // base path, that will be used to resolve files and exclude @@ -99,7 +95,7 @@ module.exports = function (config) { // - PhantomJS // - IE (only Windows) // CLI --browsers Chrome,Firefox,Safari - browsers: browsers, + browsers: useBrowserStack ? Object.keys(launchers) : ['ChromeHeadless'], customLaunchers: launchers, diff --git a/test/e2e/basic.feature b/test/e2e/basic.feature index 413648f62..d86dd438c 100644 --- a/test/e2e/basic.feature +++ b/test/e2e/basic.feature @@ -24,7 +24,7 @@ Feature: Basic Testrunner Given a configuration with: """ files = ['basic/plus.js', 'basic/test.js'] - browsers = ['Firefox'] + browsers = ['FirefoxHeadless'] plugins = [ 'karma-jasmine', 'karma-firefox-launcher' diff --git a/test/e2e/module-types.feature b/test/e2e/module-types.feature index 0a2011b5e..15bf8c6e2 100644 --- a/test/e2e/module-types.feature +++ b/test/e2e/module-types.feature @@ -14,7 +14,7 @@ Feature: ES Modules // manually enable modules). customLaunchers = { FirefoxWithModules: { - base: 'Firefox', + base: 'FirefoxHeadless', prefs: { 'dom.moduleScripts.enabled': true } diff --git a/test/e2e/runInParent.feature b/test/e2e/runInParent.feature index 2bd59b321..ac5470517 100644 --- a/test/e2e/runInParent.feature +++ b/test/e2e/runInParent.feature @@ -28,7 +28,7 @@ Feature: runInParent option Given a configuration with: """ files = ['basic/plus.js', 'basic/test.js'] - browsers = ['Firefox'] + browsers = ['FirefoxHeadless'] plugins = [ 'karma-jasmine', 'karma-firefox-launcher' diff --git a/test/e2e/tag.feature b/test/e2e/tag.feature index d51ab5f2b..04f686356 100644 --- a/test/e2e/tag.feature +++ b/test/e2e/tag.feature @@ -7,7 +7,7 @@ Feature: JavaScript Tag Given a configuration with: """ files = ['tag/tag.js', 'tag/test-with-version.js']; - browsers = ['Firefox'] + browsers = ['FirefoxHeadless'] plugins = [ 'karma-jasmine', 'karma-firefox-launcher' @@ -41,7 +41,7 @@ Feature: JavaScript Tag Given a configuration with: """ files = ['tag/tag.js', 'tag/test-without-version.js']; - browsers = ['Firefox'] + browsers = ['FirefoxHeadless'] plugins = [ 'karma-jasmine', 'karma-firefox-launcher' From 67e46904e7f7469b073f402c7fe6067742aa93c0 Mon Sep 17 00:00:00 2001 From: Jonathan Ginsburg Date: Fri, 15 Oct 2021 20:00:03 -0500 Subject: [PATCH 336/374] chore(cd): use GITHUB_TOKEN instead of GH_TOKEN This is the [default environment value name provided by GitHub Actions][1]. Also: * Format the YAML workflow files. [1]: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret --- .github/workflows/release.yml | 4 ++-- .github/workflows/test.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce351d4be..98c478e01 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,12 +10,12 @@ jobs: name: Test, Tag Commit and Release to NPM runs-on: ubuntu-latest env: - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME}} + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - GH_TOKEN: ${{ secrets.GH_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} KARMA_TEST_NO_FALLBACK: 1 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 476ac60e8..47e0882ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,7 +13,7 @@ jobs: name: Lint and Unit (Client and Server), E2E and Integration Test runs-on: ubuntu-latest env: - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME}} + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} From 4b3b0721b38dfacfca9886c31686ffd97e75654e Mon Sep 17 00:00:00 2001 From: Jonathan Ginsburg Date: Fri, 15 Oct 2021 21:05:06 -0500 Subject: [PATCH 337/374] chore(ci/client/browserstack): modify concurrency and timeout settings In our client tests, for BrowserStack, reduce the `browserDisconnectTimeout` and the `browserNoActivityTimeout` to a minute, instead of 5. Also, reduce the concurrency of browsers to 2 instead of 3. This is because BS is being flaky when handling many browsers concurrently and, when a browser has been disconnected it will generally not come back, so we do not need to wait a whole 5 minutes; it is better to just use another try from the `browserDisconnectTolerance` configuration pool. The overall result is a more efficient CI run. --- test/client/karma.conf.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index 3dc337178..289fb22d1 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -103,9 +103,9 @@ module.exports = function (config) { // https://github.com/karma-runner/karma-browserstack-launcher/issues/61 captureTimeout: 3e5, browserDisconnectTolerance: 3, - browserDisconnectTimeout: 3e5, + browserDisconnectTimeout: 6e4, browserSocketTimeout: 1.2e5, - browserNoActivityTimeout: 3e5, + browserNoActivityTimeout: 6e4, // Auto run tests on start (when browsers are captured) and exit // CLI --single-run --no-single-run @@ -124,7 +124,7 @@ module.exports = function (config) { 'karma-browserstack-launcher' ], - concurrency: 3, + concurrency: 2, forceJSONP: true, From ab9ebf8585610b80524f90570ad3c5898487b62f Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Sat, 16 Oct 2021 14:48:24 +0200 Subject: [PATCH 338/374] chore: add DOCS_GITHUB_TOKEN secret for updating karma documentation We have a script, which is run as part of release process to automatically update the documentation website: https://github.com/karma-runner/karma-runner.github.com. The DOCS_GITHUB_TOKEN secret contains a GitHub token with write access to the website repository. --- .github/workflows/release.yml | 1 + tools/update-docs.js | 9 +++++---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98c478e01..424d8ca4e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,7 @@ jobs: SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DOCS_GITHUB_TOKEN: ${{ secrets.DOCS_GITHUB_TOKEN }} KARMA_TEST_NO_FALLBACK: 1 steps: - uses: actions/checkout@v2 diff --git a/tools/update-docs.js b/tools/update-docs.js index ca6f6ef7a..a71bb6d09 100644 --- a/tools/update-docs.js +++ b/tools/update-docs.js @@ -8,10 +8,11 @@ const success = async (pluginConfig, { nextRelease, logger }) => { const { name: docsPath } = dirSync() // This is a regular repository remote one would get if they click a Clone - // button on GitHub. The only added part is GH_TOKEN value in the `userinfo` - // part of the URL (https://en.wikipedia.org/wiki/URL), which allows GitHub - // to authenticate a user and authorise the push to the repository. - const repoOrigin = `https://${process.env.GH_TOKEN}@github.com/karma-runner/karma-runner.github.com.git` + // button on GitHub. The only added part is DOCS_GITHUB_TOKEN value in the + // `userinfo` part of the URL (https://en.wikipedia.org/wiki/URL), which + // allows GitHub to authenticate a user and authorise the push to the + // repository. + const repoOrigin = `https://${process.env.DOCS_GITHUB_TOKEN}@github.com/karma-runner/karma-runner.github.com.git` const options = { encoding: 'utf8', cwd: docsPath } From 105da90a9975c1050f96cda966bd30a3c677494e Mon Sep 17 00:00:00 2001 From: Michael Vartan Date: Mon, 18 Oct 2021 21:13:18 -0700 Subject: [PATCH 339/374] fix(client): prevent socket.io from hanging due to mocked clocks (#3695) --- client/main.js | 3 +- package-lock.json | 102 ++++++++++++++++++++++------------------------ package.json | 3 +- static/karma.js | 3 +- 4 files changed, 54 insertions(+), 57 deletions(-) diff --git a/client/main.js b/client/main.js index 6ca6e5d8b..7dfc5b738 100644 --- a/client/main.js +++ b/client/main.js @@ -16,7 +16,8 @@ var socket = io(location.host, { reconnectionDelayMax: Infinity, timeout: BROWSER_SOCKET_TIMEOUT, path: KARMA_PROXY_PATH + KARMA_URL_ROOT.substr(1) + 'socket.io', - 'sync disconnect on unload': true + 'sync disconnect on unload': true, + useNativeTimers: true }) // instantiate the updater of the view diff --git a/package-lock.json b/package-lock.json index ef7fa5c4a..fd6d6d9f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2281,19 +2281,19 @@ "dev": true }, "@types/component-emitter": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz", - "integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==" + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.11.tgz", + "integrity": "sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==" }, "@types/cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg==" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" }, "@types/cors": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz", - "integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg==" + "version": "2.8.12", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", + "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" }, "@types/events": { "version": "3.0.0", @@ -2333,8 +2333,7 @@ "@types/node": { "version": "13.11.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.0.tgz", - "integrity": "sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ==", - "dev": true + "integrity": "sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ==" }, "@types/normalize-package-data": { "version": "2.4.0", @@ -2801,9 +2800,9 @@ } }, "base64-arraybuffer": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", - "integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz", + "integrity": "sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==" }, "base64-js": { "version": "1.3.0", @@ -4245,23 +4244,26 @@ } }, "engine.io": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.1.0.tgz", - "integrity": "sha512-vW7EAtn0HDQ4MtT5QbmCHF17TaYLONv2/JwdYsq9USPRZVM4zG7WB3k0Nc321z8EuSOlhGokrYlYx4176QhD0A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.0.0.tgz", + "integrity": "sha512-Ui7yl3JajEIaACg8MOUwWvuuwU7jepZqX3BKs1ho7NQRuP4LhN4XIykXhp8bEy+x/DhA0LBZZXYSCkZDqrwMMg==", "requires": { + "@types/cookie": "^0.4.1", + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~4.0.0", - "ws": "~7.4.2" + "engine.io-parser": "~5.0.0", + "ws": "~8.2.3" }, "dependencies": { "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { "ms": "2.1.2" } @@ -4274,11 +4276,11 @@ } }, "engine.io-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz", - "integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.1.tgz", + "integrity": "sha512-j4p3WwJrG2k92VISM0op7wiq60vO92MlF3CRGxhKHy9ywG1/Dkc72g0dXeDQ+//hrcDn8gqQzoEkdO9FN0d9AA==", "requires": { - "base64-arraybuffer": "0.1.4" + "base64-arraybuffer": "~1.0.1" } }, "enquirer": { @@ -6468,7 +6470,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.1.0", + "socket.io": "^4.2.0", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.28", @@ -12428,30 +12430,22 @@ } }, "socket.io": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.1.0.tgz", - "integrity": "sha512-Aqg2dlRh6xSJvRYK31ksG65q4kmBOqU4g+1ukhPcoT6wNGYoIwSYPlCPuRwOO9pgLUajojGFztl6+V2opmKcww==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.3.1.tgz", + "integrity": "sha512-HC5w5Olv2XZ0XJ4gOLGzzHEuOCfj3G0SmoW3jLHYYh34EVsIr3EkW9h6kgfW+K3TFEcmYy8JcPWe//KUkBp5jA==", "requires": { - "@types/cookie": "^0.4.0", - "@types/cors": "^2.8.8", - "@types/node": "^14.14.10", "accepts": "~1.3.4", "base64id": "~2.0.0", - "debug": "~4.3.1", - "engine.io": "~4.1.0", - "socket.io-adapter": "~2.1.0", - "socket.io-parser": "~4.0.3" + "debug": "~4.3.2", + "engine.io": "~6.0.0", + "socket.io-adapter": "~2.3.2", + "socket.io-parser": "~4.0.4" }, "dependencies": { - "@types/node": { - "version": "14.14.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.22.tgz", - "integrity": "sha512-g+f/qj/cNcqKkc3tFqlXOYjrmZA+jNBiDzbP3kH+B+otKFqAdPgVTGP1IeKRdMml/aE69as5S4FqtxAbl+LaMw==" - }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { "ms": "2.1.2" } @@ -12464,9 +12458,9 @@ } }, "socket.io-adapter": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.1.0.tgz", - "integrity": "sha512-+vDov/aTsLjViYTwS9fPy5pEtTkrbEKsw2M+oVSoFGw6OD1IpvlV1VPhUzNbofCQ8oyMbdYJqDtGdmHQK6TdPg==" + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.3.2.tgz", + "integrity": "sha512-PBZpxUPYjmoogY0aoaTmo1643JelsaS1CiAwNjRVdrI0X9Seuc19Y2Wife8k88avW6haG8cznvwbubAZwH4Mtg==" }, "socket.io-parser": { "version": "4.0.4", @@ -12484,9 +12478,9 @@ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "requires": { "ms": "2.1.2" } @@ -13789,9 +13783,9 @@ } }, "ws": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", - "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==" + "version": "8.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", + "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==" }, "xmlbuilder": { "version": "12.0.0", diff --git a/package.json b/package.json index 758dfe39c..46312bea2 100644 --- a/package.json +++ b/package.json @@ -284,6 +284,7 @@ "Merott Movahedi ", "Merrick Christensen ", "Michael Krotscheck ", + "Michael Vartan ", "Michał Siwek ", "Milan Aleksic ", "Milana Stojadinov ", @@ -435,7 +436,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^3.1.0", + "socket.io": "^4.2.0", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.28", diff --git a/static/karma.js b/static/karma.js index 95be74c59..50be7e472 100644 --- a/static/karma.js +++ b/static/karma.js @@ -338,7 +338,8 @@ var socket = io(location.host, { reconnectionDelayMax: Infinity, timeout: BROWSER_SOCKET_TIMEOUT, path: KARMA_PROXY_PATH + KARMA_URL_ROOT.substr(1) + 'socket.io', - 'sync disconnect on unload': true + 'sync disconnect on unload': true, + useNativeTimers: true }) // instantiate the updater of the view From d69b77aa8256ed2bd4aa3bda3e6687cc9ea9d02b Mon Sep 17 00:00:00 2001 From: Jonathan Ginsburg Date: Tue, 19 Oct 2021 00:11:44 -0500 Subject: [PATCH 340/374] chore(ci/client/browserstack): reduce the `captureTimeout` This should've happened in https://github.com/karma-runner/karma/commit/4b3b0721b38dfacfca9886c31686ffd97e75654e. --- test/client/karma.conf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/client/karma.conf.js b/test/client/karma.conf.js index 289fb22d1..454d40d9e 100644 --- a/test/client/karma.conf.js +++ b/test/client/karma.conf.js @@ -101,7 +101,7 @@ module.exports = function (config) { // Recommeneded browserstack timeouts // https://github.com/karma-runner/karma-browserstack-launcher/issues/61 - captureTimeout: 3e5, + captureTimeout: 6e4, browserDisconnectTolerance: 3, browserDisconnectTimeout: 6e4, browserSocketTimeout: 1.2e5, From 56cda531e8dfd9df5e233348f910c256d668190f Mon Sep 17 00:00:00 2001 From: Jonathan Ginsburg Date: Tue, 19 Oct 2021 20:57:30 -0500 Subject: [PATCH 341/374] chore: use karmarunnerbot's token for semantic-release actions --- .github/workflows/release.yml | 5 +++-- tools/update-docs.js | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 424d8ca4e..e93ffed06 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,11 +15,12 @@ jobs: SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }} SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - DOCS_GITHUB_TOKEN: ${{ secrets.DOCS_GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.KARMARUNNERBOT_GITHUB_TOKEN }} KARMA_TEST_NO_FALLBACK: 1 steps: - uses: actions/checkout@v2 + with: + token: ${{ env.GITHUB_TOKEN }} - uses: actions/setup-node@v2 with: node-version: 14 diff --git a/tools/update-docs.js b/tools/update-docs.js index a71bb6d09..9f5b297fa 100644 --- a/tools/update-docs.js +++ b/tools/update-docs.js @@ -8,11 +8,11 @@ const success = async (pluginConfig, { nextRelease, logger }) => { const { name: docsPath } = dirSync() // This is a regular repository remote one would get if they click a Clone - // button on GitHub. The only added part is DOCS_GITHUB_TOKEN value in the + // button on GitHub. The only added part is GITHUB_TOKEN value in the // `userinfo` part of the URL (https://en.wikipedia.org/wiki/URL), which // allows GitHub to authenticate a user and authorise the push to the // repository. - const repoOrigin = `https://${process.env.DOCS_GITHUB_TOKEN}@github.com/karma-runner/karma-runner.github.com.git` + const repoOrigin = `https://${process.env.GITHUB_TOKEN}@github.com/karma-runner/karma-runner.github.com.git` const options = { encoding: 'utf8', cwd: docsPath } From 389d816ed1da0e94116a43038b1de06baf2c1e58 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 20 Oct 2021 17:05:22 +0000 Subject: [PATCH 342/374] chore(release): 6.3.5 [skip ci] ## [6.3.5](https://github.com/karma-runner/karma/compare/v6.3.4...v6.3.5) (2021-10-20) ### Bug Fixes * **client:** prevent socket.io from hanging due to mocked clocks ([#3695](https://github.com/karma-runner/karma/issues/3695)) ([105da90](https://github.com/karma-runner/karma/commit/105da90a9975c1050f96cda966bd30a3c677494e)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 6 +++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e5a9f703..dff6d69e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.3.5](https://github.com/karma-runner/karma/compare/v6.3.4...v6.3.5) (2021-10-20) + + +### Bug Fixes + +* **client:** prevent socket.io from hanging due to mocked clocks ([#3695](https://github.com/karma-runner/karma/issues/3695)) ([105da90](https://github.com/karma-runner/karma/commit/105da90a9975c1050f96cda966bd30a3c677494e)) + ## [6.3.4](https://github.com/karma-runner/karma/compare/v6.3.3...v6.3.4) (2021-06-14) diff --git a/package-lock.json b/package-lock.json index fd6d6d9f8..9698c4109 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.3.4", + "version": "6.3.5", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 46312bea2..4a793b790 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "Mark Trostler ", "Ciro Nunes ", "Christian Budde Christensen ", + "Jonathan Ginsburg ", "Pawel Kozlowski ", "Robo ", "Shyam Seshadri ", @@ -97,7 +98,6 @@ "Janderson Constantino ", "Jonas Pommerening ", "Jonathan Freeman ", - "Jonathan Ginsburg ", "Josh ", "KJ Tsanaktsidis ", "Keen Yee Liau ", @@ -284,7 +284,7 @@ "Merott Movahedi ", "Merrick Christensen ", "Michael Krotscheck ", - "Michael Vartan ", + "Michael Vartan ", "Michał Siwek ", "Milan Aleksic ", "Milana Stojadinov ", @@ -492,7 +492,7 @@ "engines": { "node": ">= 10" }, - "version": "6.3.4", + "version": "6.3.5", "license": "MIT", "husky": { "hooks": { From 6f2b2ec6ed0218980eabf2cbf44e0c8f16fee661 Mon Sep 17 00:00:00 2001 From: Evgeniy Chekan Date: Mon, 25 Oct 2021 18:28:38 +0300 Subject: [PATCH 343/374] fix: bump vulnerable ua-parser-js version Closes #3713 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9698c4109..eccbce1e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6473,7 +6473,7 @@ "socket.io": "^4.2.0", "source-map": "^0.6.1", "tmp": "^0.2.1", - "ua-parser-js": "^0.7.28", + "ua-parser-js": "^0.7.30", "yargs": "^16.1.1" } }, @@ -13216,9 +13216,9 @@ "dev": true }, "ua-parser-js": { - "version": "0.7.28", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.28.tgz", - "integrity": "sha512-6Gurc1n//gjp9eQNXjD9O3M/sMwVtN5S8Lv9bvOYBfKfDNiIIhqiyi01vMBO45u4zkDE420w/e0se7Vs+sIg+g==" + "version": "0.7.30", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.30.tgz", + "integrity": "sha512-uXEtSresNUlXQ1QL4/3dQORcGv7+J2ookOG2ybA/ga9+HYEXueT2o+8dUJQkpedsyTyCJ6jCCirRcKtdtx1kbg==" }, "uglify-js": { "version": "3.6.0", diff --git a/package.json b/package.json index 4a793b790..bda5d4f23 100644 --- a/package.json +++ b/package.json @@ -439,7 +439,7 @@ "socket.io": "^4.2.0", "source-map": "^0.6.1", "tmp": "^0.2.1", - "ua-parser-js": "^0.7.28", + "ua-parser-js": "^0.7.30", "yargs": "^16.1.1" }, "devDependencies": { From 4ad9058a011b4534a2e160918edd002602c4a911 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 25 Oct 2021 19:30:58 +0000 Subject: [PATCH 344/374] chore(release): 6.3.6 [skip ci] ## [6.3.6](https://github.com/karma-runner/karma/compare/v6.3.5...v6.3.6) (2021-10-25) ### Bug Fixes * bump vulnerable ua-parser-js version ([6f2b2ec](https://github.com/karma-runner/karma/commit/6f2b2ec6ed0218980eabf2cbf44e0c8f16fee661)), closes [#3713](https://github.com/karma-runner/karma/issues/3713) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 3 ++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dff6d69e4..6e5e7d130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.3.6](https://github.com/karma-runner/karma/compare/v6.3.5...v6.3.6) (2021-10-25) + + +### Bug Fixes + +* bump vulnerable ua-parser-js version ([6f2b2ec](https://github.com/karma-runner/karma/commit/6f2b2ec6ed0218980eabf2cbf44e0c8f16fee661)), closes [#3713](https://github.com/karma-runner/karma/issues/3713) + ## [6.3.5](https://github.com/karma-runner/karma/compare/v6.3.4...v6.3.5) (2021-10-20) diff --git a/package-lock.json b/package-lock.json index eccbce1e1..d3c7357d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.3.5", + "version": "6.3.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index bda5d4f23..dae4f3f83 100644 --- a/package.json +++ b/package.json @@ -210,6 +210,7 @@ "Eldar Jafarov ", "Eric Baer ", "Esteban Marin ", + "Evgeniy Chekan ", "Fabian Beuke ", "Filipe Silva ", "Franck Garcia ", @@ -492,7 +493,7 @@ "engines": { "node": ">= 10" }, - "version": "6.3.5", + "version": "6.3.6", "license": "MIT", "husky": { "hooks": { From 36d41cb3cc03f5d4e53c33134f38a5d916999571 Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Wed, 2 Jun 2021 22:43:46 +0200 Subject: [PATCH 345/374] chore: update tooling packages to the latest versions Configurations are updated to accommodate for breaking changes. --- package-lock.json | 8067 ++++++++++++++++----------------------------- package.json | 10 +- release.config.js | 2 +- 3 files changed, 2868 insertions(+), 5211 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3c7357d2..cb533ea13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,262 +60,255 @@ } }, "@commitlint/cli": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-8.3.5.tgz", - "integrity": "sha512-6+L0vbw55UEdht71pgWOE55SRgb+8OHcEwGDB234VlIBFGK9P2QOBU7MHiYJ5cjdjCQ0rReNrGjOHmJ99jwf0w==", - "dev": true, - "requires": { - "@commitlint/format": "^8.3.4", - "@commitlint/lint": "^8.3.5", - "@commitlint/load": "^8.3.5", - "@commitlint/read": "^8.3.4", - "babel-polyfill": "6.26.0", - "chalk": "2.4.2", - "get-stdin": "7.0.0", - "lodash": "4.17.15", - "meow": "5.0.0", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-12.1.4.tgz", + "integrity": "sha512-ZR1WjXLvqEffYyBPT0XdnSxtt3Ty1TMoujEtseW5o3vPnkA1UNashAMjQVg/oELqfaiAMnDw8SERPMN0e/0kLg==", + "dev": true, + "requires": { + "@commitlint/format": "^12.1.4", + "@commitlint/lint": "^12.1.4", + "@commitlint/load": "^12.1.4", + "@commitlint/read": "^12.1.4", + "@commitlint/types": "^12.1.4", + "lodash": "^4.17.19", "resolve-from": "5.0.0", - "resolve-global": "1.0.0" + "resolve-global": "1.0.0", + "yargs": "^16.2.0" }, "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } - }, - "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "meow": { + "resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" } }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "ansi-regex": "^5.0.1" } }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", - "dev": true } } }, "@commitlint/config-conventional": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-8.3.4.tgz", - "integrity": "sha512-w0Yc5+aVAjZgjYqx29igBOnVCj8O22gy3Vo6Fyp7PwoS7+AYS1x3sN7IBq6i7Ae15Mv5P+rEx1pkxXo5zOMe4g==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-12.1.4.tgz", + "integrity": "sha512-ZIdzmdy4o4WyqywMEpprRCrehjCSQrHkaRTVZV411GyLigFQHlEBSJITAihLAWe88Qy/8SyoIe5uKvAsV5vRqQ==", "dev": true, "requires": { - "conventional-changelog-conventionalcommits": "4.2.1" + "conventional-changelog-conventionalcommits": "^4.3.1" } }, "@commitlint/ensure": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-8.3.4.tgz", - "integrity": "sha512-8NW77VxviLhD16O3EUd02lApMFnrHexq10YS4F4NftNoErKbKaJ0YYedktk2boKrtNRf/gQHY/Qf65edPx4ipw==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-12.1.4.tgz", + "integrity": "sha512-MxHIBuAG9M4xl33qUfIeMSasbv3ktK0W+iygldBxZOL4QSYC2Gn66pZAQMnV9o3V+sVFHoAK2XUKqBAYrgbEqw==", "dev": true, "requires": { - "lodash": "4.17.15" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - } + "@commitlint/types": "^12.1.4", + "lodash": "^4.17.19" } }, "@commitlint/execute-rule": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-8.3.4.tgz", - "integrity": "sha512-f4HigYjeIBn9f7OuNv5zh2y5vWaAhNFrfeul8CRJDy82l3Y+09lxOTGxfF3uMXKrZq4LmuK6qvvRCZ8mUrVvzQ==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-12.1.4.tgz", + "integrity": "sha512-h2S1j8SXyNeABb27q2Ok2vD1WfxJiXvOttKuRA9Or7LN6OQoC/KtT3844CIhhWNteNMu/wE0gkTqGxDVAnJiHg==", "dev": true }, "@commitlint/format": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-8.3.4.tgz", - "integrity": "sha512-809wlQ/ND6CLZON+w2Rb3YM2TLNDfU2xyyqpZeqzf2reJNpySMSUAeaO/fNDJSOKIsOsR3bI01rGu6hv28k+Nw==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-12.1.4.tgz", + "integrity": "sha512-h28ucMaoRjVvvgS6Bdf85fa/+ZZ/iu1aeWGCpURnQV7/rrVjkhNSjZwGlCOUd5kDV1EnZ5XdI7L18SUpRjs26g==", "dev": true, "requires": { - "chalk": "^2.0.1" + "@commitlint/types": "^12.1.4", + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "@commitlint/is-ignored": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-8.3.5.tgz", - "integrity": "sha512-Zo+8a6gJLFDTqyNRx53wQi/XTiz8mncvmWf/4oRG+6WRcBfjSSHY7KPVj5Y6UaLy2EgZ0WQ2Tt6RdTDeQiQplA==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-12.1.4.tgz", + "integrity": "sha512-uTu2jQU2SKvtIRVLOzMQo3KxDtO+iJ1p0olmncwrqy4AfPLgwoyCP2CiULq5M7xpR3+dE3hBlZXbZTQbD7ycIw==", "dev": true, "requires": { - "semver": "6.3.0" + "@commitlint/types": "^12.1.4", + "semver": "7.3.5" }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, "@commitlint/lint": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-8.3.5.tgz", - "integrity": "sha512-02AkI0a6PU6rzqUvuDkSi6rDQ2hUgkq9GpmdJqfai5bDbxx2939mK4ZO+7apbIh4H6Pae7EpYi7ffxuJgm+3hQ==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-12.1.4.tgz", + "integrity": "sha512-1kZ8YDp4to47oIPFELUFGLiLumtPNKJigPFDuHt2+f3Q3IKdQ0uk53n3CPl4uoyso/Og/EZvb1mXjFR/Yce4cA==", "dev": true, "requires": { - "@commitlint/is-ignored": "^8.3.5", - "@commitlint/parse": "^8.3.4", - "@commitlint/rules": "^8.3.4", - "babel-runtime": "^6.23.0", - "lodash": "4.17.15" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - } + "@commitlint/is-ignored": "^12.1.4", + "@commitlint/parse": "^12.1.4", + "@commitlint/rules": "^12.1.4", + "@commitlint/types": "^12.1.4" } }, "@commitlint/load": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-8.3.5.tgz", - "integrity": "sha512-poF7R1CtQvIXRmVIe63FjSQmN9KDqjRtU5A6hxqXBga87yB2VUJzic85TV6PcQc+wStk52cjrMI+g0zFx+Zxrw==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-12.1.4.tgz", + "integrity": "sha512-Keszi0IOjRzKfxT+qES/n+KZyLrxy79RQz8wWgssCboYjKEp+wC+fLCgbiMCYjI5k31CIzIOq/16J7Ycr0C0EA==", "dev": true, "requires": { - "@commitlint/execute-rule": "^8.3.4", - "@commitlint/resolve-extends": "^8.3.5", - "babel-runtime": "^6.23.0", - "chalk": "2.4.2", - "cosmiconfig": "^5.2.0", - "lodash": "4.17.15", + "@commitlint/execute-rule": "^12.1.4", + "@commitlint/resolve-extends": "^12.1.4", + "@commitlint/types": "^12.1.4", + "chalk": "^4.0.0", + "cosmiconfig": "^7.0.0", + "lodash": "^4.17.19", "resolve-from": "^5.0.0" }, "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "resolve-from": { @@ -323,187 +316,159 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, "@commitlint/message": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-8.3.4.tgz", - "integrity": "sha512-nEj5tknoOKXqBsaQtCtgPcsAaf5VCg3+fWhss4Vmtq40633xLq0irkdDdMEsYIx8rGR0XPBTukqzln9kAWCkcA==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-12.1.4.tgz", + "integrity": "sha512-6QhalEKsKQ/Y16/cTk5NH4iByz26fqws2ub+AinHPtM7Io0jy4e3rym9iE+TkEqiqWZlUigZnTwbPvRJeSUBaA==", "dev": true }, "@commitlint/parse": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-8.3.4.tgz", - "integrity": "sha512-b3uQvpUQWC20EBfKSfMRnyx5Wc4Cn778bVeVOFErF/cXQK725L1bYFvPnEjQO/GT8yGVzq2wtLaoEqjm1NJ/Bw==", + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-12.1.4.tgz", + "integrity": "sha512-yqKSAsK2V4X/HaLb/yYdrzs6oD/G48Ilt0EJ2Mp6RJeWYxG14w/Out6JrneWnr/cpzemyN5hExOg6+TB19H/Lw==", "dev": true, "requires": { - "conventional-changelog-angular": "^1.3.3", - "conventional-commits-parser": "^3.0.0", - "lodash": "^4.17.11" + "@commitlint/types": "^12.1.4", + "conventional-changelog-angular": "^5.0.11", + "conventional-commits-parser": "^3.0.0" + } + }, + "@commitlint/read": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-12.1.4.tgz", + "integrity": "sha512-TnPQSJgD8Aod5Xeo9W4SaYKRZmIahukjcCWJ2s5zb3ZYSmj6C85YD9cR5vlRyrZjj78ItLUV/X4FMWWVIS38Jg==", + "dev": true, + "requires": { + "@commitlint/top-level": "^12.1.4", + "@commitlint/types": "^12.1.4", + "fs-extra": "^9.0.0", + "git-raw-commits": "^2.0.0" }, "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", - "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - } + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, - "conventional-commits-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", - "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.1", - "lodash": "^4.17.15", - "meow": "^7.0.0", - "split2": "^2.0.0", - "through2": "^3.0.0", - "trim-off-newlines": "^1.0.0" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, - "locate-path": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@commitlint/resolve-extends": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-12.1.4.tgz", + "integrity": "sha512-R9CoUtsXLd6KSCfsZly04grsH6JVnWFmVtWgWs1KdDpdV+G3TSs37tColMFqglpkx3dsWu8dsPD56+D9YnJfqg==", + "dev": true, + "requires": { + "import-fresh": "^3.0.0", + "lodash": "^4.17.19", + "resolve-from": "^5.0.0", + "resolve-global": "^1.0.0" + }, + "dependencies": { + "resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "map-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true - }, - "meow": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", - "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", - "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "arrify": "^2.0.1", - "camelcase": "^6.0.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" - }, - "dependencies": { - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - } - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } - } - } + } + } + }, + "@commitlint/rules": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-12.1.4.tgz", + "integrity": "sha512-W8m6ZSjg7RuIsIfzQiFHa48X5mcPXeKT9yjBxVmjHvYfS2FDBf1VxCQ7vO0JTVIdV4ohjZ0eKg/wxxUuZHJAZg==", + "dev": true, + "requires": { + "@commitlint/ensure": "^12.1.4", + "@commitlint/message": "^12.1.4", + "@commitlint/to-lines": "^12.1.4", + "@commitlint/types": "^12.1.4" + } + }, + "@commitlint/to-lines": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-12.1.4.tgz", + "integrity": "sha512-TParumvbi8bdx3EdLXz2MaX+e15ZgoCqNUgqHsRLwyqLUTRbqCVkzrfadG1UcMQk8/d5aMbb327ZKG3Q4BRorw==", + "dev": true + }, + "@commitlint/top-level": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-12.1.4.tgz", + "integrity": "sha512-d4lTJrOT/dXlpY+NIt4CUl77ciEzYeNVc0VFgUQ6VA+b1rqYD2/VWFjBlWVOrklxtSDeKyuEhs36RGrppEFAvg==", + "dev": true, + "requires": { + "find-up": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-try": "^2.0.0" + "p-locate": "^5.0.0" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "yocto-queue": "^0.1.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" + "p-limit": "^3.0.2" } }, "path-exists": { @@ -511,870 +476,592 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + } + } + }, + "@commitlint/types": { + "version": "12.1.4", + "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-12.1.4.tgz", + "integrity": "sha512-KRIjdnWNUx6ywz+SJvjmNCbQKcKP6KArhjZhY2l+CWKxak0d77SOjggkMwFTiSgLODOwmuLTbarR2ZfWPiPMlw==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "color-convert": "^2.0.1" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "dependencies": { - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - } + "color-name": "~1.1.4" } }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" + "has-flag": "^4.0.0" } - }, - "trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", - "dev": true - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true } } }, - "@commitlint/read": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-8.3.4.tgz", - "integrity": "sha512-FKv1kHPrvcAG5j+OSbd41IWexsbLhfIXpxVC/YwQZO+FR0EHmygxQNYs66r+GnhD1EfYJYM4WQIqd5bJRx6OIw==", + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@commitlint/top-level": "^8.3.4", - "@marionebl/sander": "^0.6.0", - "babel-runtime": "^6.23.0", - "git-raw-commits": "^2.0.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@octokit/auth-token": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", + "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3" + } + }, + "@octokit/core": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz", + "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==", + "dev": true, + "requires": { + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.6.0", + "@octokit/request-error": "^2.0.5", + "@octokit/types": "^6.0.3", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/endpoint": { + "version": "6.0.12", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", + "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "is-plain-object": "^5.0.0", + "universal-user-agent": "^6.0.0" }, "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true - }, - "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + } + } + }, + "@octokit/graphql": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", + "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", + "dev": true, + "requires": { + "@octokit/request": "^5.6.0", + "@octokit/types": "^6.0.3", + "universal-user-agent": "^6.0.0" + } + }, + "@octokit/openapi-types": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz", + "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==", + "dev": true + }, + "@octokit/plugin-paginate-rest": { + "version": "2.17.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz", + "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==", + "dev": true, + "requires": { + "@octokit/types": "^6.34.0" + } + }, + "@octokit/plugin-request-log": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", + "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", + "dev": true + }, + "@octokit/plugin-rest-endpoint-methods": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz", + "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==", + "dev": true, + "requires": { + "@octokit/types": "^6.34.0", + "deprecation": "^2.3.1" + } + }, + "@octokit/request": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz", + "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==", + "dev": true, + "requires": { + "@octokit/endpoint": "^6.0.1", + "@octokit/request-error": "^2.1.0", + "@octokit/types": "^6.16.1", + "is-plain-object": "^5.0.0", + "node-fetch": "^2.6.1", + "universal-user-agent": "^6.0.0" + }, + "dependencies": { + "is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + } + } + }, + "@octokit/request-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", + "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", + "dev": true, + "requires": { + "@octokit/types": "^6.0.3", + "deprecation": "^2.0.0", + "once": "^1.4.0" + } + }, + "@octokit/rest": { + "version": "18.12.0", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", + "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", + "dev": true, + "requires": { + "@octokit/core": "^3.5.1", + "@octokit/plugin-paginate-rest": "^2.16.8", + "@octokit/plugin-request-log": "^1.0.4", + "@octokit/plugin-rest-endpoint-methods": "^5.12.0" + } + }, + "@octokit/types": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz", + "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==", + "dev": true, + "requires": { + "@octokit/openapi-types": "^11.2.0" + } + }, + "@semantic-release/changelog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-5.0.1.tgz", + "integrity": "sha512-unvqHo5jk4dvAf2nZ3aw4imrlwQ2I50eVVvq9D47Qc3R+keNqepx1vDYwkjF8guFXnOYaYcR28yrZWno1hFbiw==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^3.0.0", + "fs-extra": "^9.0.0", + "lodash": "^4.17.4" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - } + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, - "git-raw-commits": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.7.tgz", - "integrity": "sha512-SkwrTqrDxw8y0G1uGJ9Zw13F7qu3LF8V4BifyDeiJCxSnjRGZD9SaoMiMqUvvXMXh6S3sOQ1DsBN7L2fMUZW/g==", + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "dargs": "^7.0.0", - "lodash.template": "^4.0.2", - "meow": "^7.0.0", - "split2": "^2.0.0", - "through2": "^3.0.0" - }, - "dependencies": { - "dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true - } + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@semantic-release/commit-analyzer": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-8.0.1.tgz", + "integrity": "sha512-5bJma/oB7B4MtwUkZC2Bf7O1MHfi4gWe4mA+MIQ3lsEV0b422Bvl1z5HRpplDnMLHH3EXMoRdEng6Ds5wUqA3A==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.0", + "conventional-commits-filter": "^2.0.0", + "conventional-commits-parser": "^3.0.7", + "debug": "^4.0.0", + "import-from": "^3.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.2" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "ms": "2.1.2" } }, - "map-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", - "dev": true - }, - "meow": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", - "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { - "@types/minimist": "^1.2.0", - "arrify": "^2.0.1", - "camelcase": "^6.0.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" - }, - "dependencies": { - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - } - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } - } - } + "braces": "^3.0.1", + "picomatch": "^2.2.3" } }, - "p-limit": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "picomatch": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + } + } + }, + "@semantic-release/error": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", + "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", + "dev": true + }, + "@semantic-release/git": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-9.0.1.tgz", + "integrity": "sha512-75P03s9v0xfrH9ffhDVWRIX0fgWBvJMmXhUU0rMTKYz47oMXU5O95M/ocgIKnVJlWZYoC+LpIe4Ye6ev8CrlUQ==", + "dev": true, + "requires": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^3.0.0", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "execa": "^5.0.0", + "lodash": "^4.17.4", + "micromatch": "^4.0.0", + "p-reduce": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "p-try": "^2.0.0" + "ms": "2.1.2" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "braces": "^3.0.1", + "picomatch": "^2.2.3" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + } + } + }, + "@semantic-release/github": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-7.2.3.tgz", + "integrity": "sha512-lWjIVDLal+EQBzy697ayUNN8MoBpp+jYIyW2luOdqn5XBH4d9bQGfTnjuLyzARZBHejqh932HVjiH/j4+R7VHw==", + "dev": true, + "requires": { + "@octokit/rest": "^18.0.0", + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "bottleneck": "^2.18.1", + "debug": "^4.0.0", + "dir-glob": "^3.0.0", + "fs-extra": "^10.0.0", + "globby": "^11.0.0", + "http-proxy-agent": "^4.0.0", + "https-proxy-agent": "^5.0.0", + "issue-parser": "^6.0.0", + "lodash": "^4.17.4", + "mime": "^2.4.3", + "p-filter": "^2.0.0", + "p-retry": "^4.0.0", + "url-join": "^4.0.0" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "debug": "4" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } + "ms": "2.1.2" } }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", "dev": true, "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "dependencies": { - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - } + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, "requires": { - "min-indent": "^1.0.0" + "agent-base": "6", + "debug": "4" } }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, - "trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", - "dev": true - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true - } - } - }, - "@commitlint/resolve-extends": { - "version": "8.3.5", - "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-8.3.5.tgz", - "integrity": "sha512-nHhFAK29qiXNe6oH6uG5wqBnCR+BQnxlBW/q5fjtxIaQALgfoNLHwLS9exzbIRFqwJckpR6yMCfgMbmbAOtklQ==", - "dev": true, - "requires": { - "import-fresh": "^3.0.0", - "lodash": "4.17.15", - "resolve-from": "^5.0.0", - "resolve-global": "^1.0.0" - }, - "dependencies": { - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true } } }, - "@commitlint/rules": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-8.3.4.tgz", - "integrity": "sha512-xuC9dlqD5xgAoDFgnbs578cJySvwOSkMLQyZADb1xD5n7BNcUJfP8WjT9W1Aw8K3Wf8+Ym/ysr9FZHXInLeaRg==", - "dev": true, - "requires": { - "@commitlint/ensure": "^8.3.4", - "@commitlint/message": "^8.3.4", - "@commitlint/to-lines": "^8.3.4", - "babel-runtime": "^6.23.0" - } - }, - "@commitlint/to-lines": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-8.3.4.tgz", - "integrity": "sha512-5AvcdwRsMIVq0lrzXTwpbbG5fKRTWcHkhn/hCXJJ9pm1JidsnidS1y0RGkb3O50TEHGewhXwNoavxW9VToscUA==", - "dev": true - }, - "@commitlint/top-level": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-8.3.4.tgz", - "integrity": "sha512-nOaeLBbAqSZNpKgEtO6NAxmui1G8ZvLG+0wb4rvv6mWhPDzK1GNZkCd8FUZPahCoJ1iHDoatw7F8BbJLg4nDjg==", + "@semantic-release/npm": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-7.1.3.tgz", + "integrity": "sha512-x52kQ/jR09WjuWdaTEHgQCvZYMOTx68WnS+TZ4fya5ZAJw4oRtJETtrvUw10FdfM28d/keInQdc66R1Gw5+OEQ==", "dev": true, "requires": { - "find-up": "^4.0.0" + "@semantic-release/error": "^2.2.0", + "aggregate-error": "^3.0.0", + "execa": "^5.0.0", + "fs-extra": "^10.0.0", + "lodash": "^4.17.15", + "nerf-dart": "^1.0.0", + "normalize-url": "^6.0.0", + "npm": "^7.0.0", + "rc": "^1.2.8", + "read-pkg": "^5.0.0", + "registry-auth-token": "^4.0.0", + "semver": "^7.1.2", + "tempy": "^1.0.0" }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "fs-extra": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { - "p-try": "^2.0.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - } - } - }, - "@marionebl/sander": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@marionebl/sander/-/sander-0.6.1.tgz", - "integrity": "sha1-GViWWHTyS8Ub5Ih1/rUNZC/EH3s=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.3", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.2" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } - }, - "@octokit/auth-token": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.0.tgz", - "integrity": "sha512-eoOVMjILna7FVQf96iWc3+ZtE/ZT6y8ob8ZzcqKY1ibSQCnu4O/B7pJvzMx5cyZ/RjAff6DAdEb0O0Cjcxidkg==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.0" - } - }, - "@octokit/endpoint": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.0.tgz", - "integrity": "sha512-3nx+MEYoZeD0uJ+7F/gvELLvQJzLXhep2Az0bBSXagbApDvDW0LWwpnAIY/hb0Jwe17A0fJdz0O12dPh05cj7A==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.0", - "is-plain-object": "^3.0.0", - "universal-user-agent": "^5.0.0" - }, - "dependencies": { - "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "isobject": "^4.0.0" + "lru-cache": "^6.0.0" } }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true }, - "universal-user-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz", - "integrity": "sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==", - "dev": true, - "requires": { - "os-name": "^3.1.0" - } - } - } - }, - "@octokit/plugin-paginate-rest": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-1.1.2.tgz", - "integrity": "sha512-jbsSoi5Q1pj63sC16XIUboklNw+8tL9VOnJsWycWYR78TKss5PVpIPb1TUUcMQ+bBh7cY579cVAWmf5qG+dw+Q==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.1" - } - }, - "@octokit/plugin-request-log": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.0.tgz", - "integrity": "sha512-ywoxP68aOT3zHCLgWZgwUJatiENeHE7xJzYjfz8WI0goynp96wETBF+d95b8g/uL4QmS6owPVlaxiz3wyMAzcw==", - "dev": true - }, - "@octokit/plugin-rest-endpoint-methods": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-2.4.0.tgz", - "integrity": "sha512-EZi/AWhtkdfAYi01obpX0DF7U6b1VRr30QNQ5xSFPITMdLSfhcBqjamE3F+sKcxPbD7eZuMHu3Qkk2V+JGxBDQ==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.1", - "deprecation": "^2.3.1" - } - }, - "@octokit/request": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.3.4.tgz", - "integrity": "sha512-qyj8G8BxQyXjt9Xu6NvfvOr1E0l35lsXtwm3SopsYg/JWXjlsnwqLc8rsD2OLguEL/JjLfBvrXr4az7z8Lch2A==", - "dev": true, - "requires": { - "@octokit/endpoint": "^6.0.0", - "@octokit/request-error": "^2.0.0", - "@octokit/types": "^2.0.0", - "deprecation": "^2.0.0", - "is-plain-object": "^3.0.0", - "node-fetch": "^2.3.0", - "once": "^1.4.0", - "universal-user-agent": "^5.0.0" - }, - "dependencies": { - "@octokit/request-error": { + "universalify": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.0.tgz", - "integrity": "sha512-rtYicB4Absc60rUv74Rjpzek84UbVHGHJRu4fNVlZ1mCcyUPPuzFfG9Rn6sjHrd95DEsmjSt1Axlc699ZlbDkw==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "is-plain-object": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz", - "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==", - "dev": true, - "requires": { - "isobject": "^4.0.0" - } - }, - "isobject": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz", - "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true - }, - "universal-user-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz", - "integrity": "sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==", - "dev": true, - "requires": { - "os-name": "^3.1.0" - } - } - } - }, - "@octokit/request-error": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-1.2.1.tgz", - "integrity": "sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==", - "dev": true, - "requires": { - "@octokit/types": "^2.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "@octokit/rest": { - "version": "16.43.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.43.1.tgz", - "integrity": "sha512-gfFKwRT/wFxq5qlNjnW2dh+qh74XgTQ2B179UX5K1HYCluioWj8Ndbgqw2PVqa1NnVJkGHp2ovMpVn/DImlmkw==", - "dev": true, - "requires": { - "@octokit/auth-token": "^2.4.0", - "@octokit/plugin-paginate-rest": "^1.1.1", - "@octokit/plugin-request-log": "^1.0.0", - "@octokit/plugin-rest-endpoint-methods": "2.4.0", - "@octokit/request": "^5.2.0", - "@octokit/request-error": "^1.0.2", - "atob-lite": "^2.0.0", - "before-after-hook": "^2.0.0", - "btoa-lite": "^1.0.0", - "deprecation": "^2.0.0", - "lodash.get": "^4.4.2", - "lodash.set": "^4.3.2", - "lodash.uniq": "^4.5.0", - "octokit-pagination-methods": "^1.1.0", - "once": "^1.4.0", - "universal-user-agent": "^4.0.0" - } - }, - "@octokit/types": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-2.5.1.tgz", - "integrity": "sha512-q4Wr7RexkPRrkQpXzUYF5Fj/14Mr65RyOHj6B9d/sQACpqGcStkHZj4qMEtlMY5SnD/69jlL9ItGPbDM0dR/dA==", - "dev": true, - "requires": { - "@types/node": ">= 8" - } - }, - "@semantic-release/changelog": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-3.0.6.tgz", - "integrity": "sha512-9TqPL/VarLLj6WkUqbIqFiY3nwPmLuKFHy9fe/LamAW5s4MEW/ig9zW9vzYGOUVtWdErGJ1J62E3Edkamh3xaQ==", - "dev": true, - "requires": { - "@semantic-release/error": "^2.1.0", - "aggregate-error": "^3.0.0", - "fs-extra": "^8.0.0", - "lodash": "^4.17.4" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } } } }, - "@semantic-release/commit-analyzer": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-6.3.3.tgz", - "integrity": "sha512-Pyv1ZL2u5AIOY4YbxFCAB5J1PEh5yON8ylbfiPiriDGGW6Uu1U3Y8lysMtWu+FUD5x7tSnyIzhqx0+fxPxqbgw==", + "@semantic-release/release-notes-generator": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-9.0.3.tgz", + "integrity": "sha512-hMZyddr0u99OvM2SxVOIelHzly+PP3sYtJ8XOLHdMp8mrluN5/lpeTnIO27oeCYdupY/ndoGfvrqDjHqkSyhVg==", "dev": true, "requires": { "conventional-changelog-angular": "^5.0.0", + "conventional-changelog-writer": "^4.0.0", "conventional-commits-filter": "^2.0.0", - "conventional-commits-parser": "^3.0.7", + "conventional-commits-parser": "^3.0.0", "debug": "^4.0.0", + "get-stream": "^6.0.0", "import-from": "^3.0.0", - "lodash": "^4.17.4" + "into-stream": "^6.0.0", + "lodash": "^4.17.4", + "read-pkg-up": "^7.0.0" }, "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", - "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - } - } - }, - "conventional-changelog-angular": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.11.tgz", - "integrity": "sha512-nSLypht/1yEflhuTogC03i7DX7sOrXGsRn14g131Potqi6cbGbGEE9PSDEHKldabB6N76HiSyw9Ph+kLmC04Qw==", - "dev": true, - "requires": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - }, - "dependencies": { - "compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - } - } - }, - "conventional-commits-filter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz", - "integrity": "sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==", - "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" - } - }, - "conventional-commits-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", - "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", - "dev": true, - "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.1", - "lodash": "^4.17.15", - "meow": "^7.0.0", - "split2": "^2.0.0", - "through2": "^3.0.0", - "trim-off-newlines": "^1.0.0" - } - }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "is-obj": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -1384,72 +1071,6 @@ "p-locate": "^4.1.0" } }, - "map-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", - "dev": true - }, - "meow": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", - "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", - "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "arrify": "^2.0.1", - "camelcase": "^6.0.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" - }, - "dependencies": { - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - } - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } - } - } - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1481,14 +1102,14 @@ "dev": true }, "parse-json": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.1.tgz", - "integrity": "sha512-ztoZ4/DYeXQq4E21v169sC8qWINGpcosGv9XhTDvg9/hWvx/zrFkc9BiWxR58OJLHGk28j5BL0SDLeV2WmFZlQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -1527,745 +1148,44 @@ "find-up": "^4.1.0", "read-pkg": "^5.2.0", "type-fest": "^0.8.1" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "dependencies": { - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - } - } - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" } }, - "trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", - "dev": true - }, "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true } } }, - "@semantic-release/error": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-2.2.0.tgz", - "integrity": "sha512-9Tj/qn+y2j+sjCI3Jd+qseGtHjOAeg7dU2/lVcqIQ9TV3QDaDXDYXcoOHU+7o2Hwh8L8ymL4gfuO7KxDs3q2zg==", - "dev": true - }, - "@semantic-release/git": { - "version": "7.0.18", - "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-7.0.18.tgz", - "integrity": "sha512-VwnsGUXpNdvPcsq05BQyLBZxGUlEiJCMKNi8ttLvZZAhjI1mAp9dwypOeyxSJ5eFQ+iGMBLdoKF1LL0pmA/d0A==", + "@sinonjs/commons": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", + "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", "dev": true, "requires": { - "@semantic-release/error": "^2.1.0", - "aggregate-error": "^3.0.0", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "execa": "^3.2.0", - "fs-extra": "^8.0.0", - "globby": "^10.0.0", - "lodash": "^4.17.4", - "micromatch": "^4.0.0", - "p-reduce": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "type-detect": "4.0.8" } }, - "@semantic-release/github": { - "version": "5.5.8", - "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-5.5.8.tgz", - "integrity": "sha512-YxbBXbCThs/Xk3E4QU01AMIUM8eb0UTvjHJtclTDR3/DEW7kUpmXQqBMnSh3qCTuk4scRFIoaF0fGU/0xByZug==", + "@sinonjs/formatio": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", + "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", "dev": true, "requires": { - "@octokit/rest": "^16.27.0", - "@semantic-release/error": "^2.2.0", - "aggregate-error": "^3.0.0", - "bottleneck": "^2.18.1", - "debug": "^4.0.0", - "dir-glob": "^3.0.0", - "fs-extra": "^8.0.0", - "globby": "^10.0.0", - "http-proxy-agent": "^3.0.0", - "https-proxy-agent": "^4.0.0", - "issue-parser": "^5.0.0", - "lodash": "^4.17.4", - "mime": "^2.4.3", - "p-filter": "^2.0.0", - "p-retry": "^4.0.0", - "url-join": "^4.0.0" - }, - "dependencies": { - "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", - "dev": true, - "requires": { - "agent-base": "5", - "debug": "4" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" } }, - "@semantic-release/npm": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-5.3.5.tgz", - "integrity": "sha512-AOREQ6rUT8OAiqXvWCp0kMNjcdnLLq1JdP0voZL4l5zf6Tgs/65YA7ctP+9shthW01Ps85Nu0pILW3p9GkaYuw==", + "@sinonjs/samsam": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", + "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", "dev": true, "requires": { - "@semantic-release/error": "^2.2.0", - "aggregate-error": "^3.0.0", - "execa": "^3.2.0", - "fs-extra": "^8.0.0", - "lodash": "^4.17.15", - "nerf-dart": "^1.0.0", - "normalize-url": "^4.0.0", - "npm": "^6.10.3", - "rc": "^1.2.8", - "read-pkg": "^5.0.0", - "registry-auth-token": "^4.0.0", - "tempy": "^0.3.0" - }, - "dependencies": { - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - } - } - } - }, - "@semantic-release/release-notes-generator": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-7.3.5.tgz", - "integrity": "sha512-LGjgPBGjjmjap/76O0Md3wc04Y7IlLnzZceLsAkcYRwGQdRPTTFUJKqDQTuieWTs7zfHzQoZqsqPfFxEN+g2+Q==", - "dev": true, - "requires": { - "conventional-changelog-angular": "^5.0.0", - "conventional-changelog-writer": "^4.0.0", - "conventional-commits-filter": "^2.0.0", - "conventional-commits-parser": "^3.0.0", - "debug": "^4.0.0", - "get-stream": "^5.0.0", - "import-from": "^3.0.0", - "into-stream": "^5.0.0", - "lodash": "^4.17.4", - "read-pkg-up": "^7.0.0" - }, - "dependencies": { - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", - "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - } - } - }, - "conventional-changelog-angular": { - "version": "5.0.11", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.11.tgz", - "integrity": "sha512-nSLypht/1yEflhuTogC03i7DX7sOrXGsRn14g131Potqi6cbGbGEE9PSDEHKldabB6N76HiSyw9Ph+kLmC04Qw==", - "dev": true, - "requires": { - "compare-func": "^2.0.0", - "q": "^1.5.1" - }, - "dependencies": { - "compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - } - } - }, - "conventional-changelog-writer": { - "version": "4.0.17", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.17.tgz", - "integrity": "sha512-IKQuK3bib/n032KWaSb8YlBFds+aLmzENtnKtxJy3+HqDq5kohu3g/UdNbIHeJWygfnEbZjnCKFxAW0y7ArZAw==", - "dev": true, - "requires": { - "compare-func": "^2.0.0", - "conventional-commits-filter": "^2.0.6", - "dateformat": "^3.0.0", - "handlebars": "^4.7.6", - "json-stringify-safe": "^5.0.1", - "lodash": "^4.17.15", - "meow": "^7.0.0", - "semver": "^6.0.0", - "split": "^1.0.0", - "through2": "^3.0.0" - }, - "dependencies": { - "compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "requires": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "conventional-commits-filter": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.6.tgz", - "integrity": "sha512-4g+sw8+KA50/Qwzfr0hL5k5NWxqtrOVw4DDk3/h6L85a9Gz0/Eqp3oP+CWCNfesBvZZZEFHF7OTEbRe+yYSyKw==", - "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" - } - }, - "handlebars": { - "version": "4.7.6", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", - "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", - "dev": true, - "requires": { - "minimist": "^1.2.5", - "neo-async": "^2.6.0", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4", - "wordwrap": "^1.0.0" - } - } - } - }, - "conventional-commits-filter": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz", - "integrity": "sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==", - "dev": true, - "requires": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.0" - } - }, - "conventional-commits-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.1.0.tgz", - "integrity": "sha512-RSo5S0WIwXZiRxUGTPuYFbqvrR4vpJ1BDdTlthFgvHt5kEdnd1+pdvwWphWn57/oIl4V72NMmOocFqqJ8mFFhA==", - "dev": true, - "requires": { - "JSONStream": "^1.0.4", - "is-text-path": "^1.0.1", - "lodash": "^4.17.15", - "meow": "^7.0.0", - "split2": "^2.0.0", - "through2": "^3.0.0", - "trim-off-newlines": "^1.0.0" - } - }, - "dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "map-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", - "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", - "dev": true - }, - "meow": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", - "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", - "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "arrify": "^2.0.1", - "camelcase": "^6.0.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "^4.0.2", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" - }, - "dependencies": { - "minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - } - } - }, - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - } - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", - "lines-and-columns": "^1.1.6" - } - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - } - } - }, - "redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "dependencies": { - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - } - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "requires": { - "min-indent": "^1.0.0" - } - }, - "through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "trim-newlines": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", - "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", - "dev": true - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "@sinonjs/commons": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", - "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/formatio": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.2.tgz", - "integrity": "sha512-B8SEsgd8gArBLMD6zpRw3juQ2FVSsmdd7qlevyDqzS9WTCtvF55/gAL+h6gue8ZvPYcdiPdvueM/qm//9XzyTQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^3.1.0" - } - }, - "@sinonjs/samsam": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.3.tgz", - "integrity": "sha512-bKCMKZvWIjYD0BLGnNrxVuw4dkWCYsLqFOUWw8VgKF/+5Y+mE7LfHWPIYoDXowH+3a9LsWDMo0uAP8YDosPvHQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.3.0", - "array-from": "^2.1.1", - "lodash": "^4.17.15" + "@sinonjs/commons": "^1.3.0", + "array-from": "^2.1.1", + "lodash": "^4.17.15" } }, "@sinonjs/text-encoding": { @@ -2274,6 +1194,12 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", @@ -2295,39 +1221,16 @@ "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "dev": true }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, "@types/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", "dev": true }, "@types/node": { @@ -2336,9 +1239,9 @@ "integrity": "sha512-uM4mnmsIIPK/yeO+42F2RQhGUIs39K2RFmugcJANppXe6J1nvH87PvzPZYpza7Xhhs8Yn9yIAVdLZ84z61+0xQ==" }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "@types/parse-json": { @@ -2348,9 +1251,9 @@ "dev": true }, "@types/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", + "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", "dev": true }, "JSONStream": { @@ -2418,21 +1321,13 @@ } }, "aggregate-error": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", - "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "dev": true, "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" - }, - "dependencies": { - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - } } }, "ajv": { @@ -2454,10 +1349,21 @@ "dev": true }, "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } + } }, "ansi-regex": { "version": "3.0.0", @@ -2540,12 +1446,6 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, "array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", @@ -2569,8 +1469,14 @@ "is-string": "^1.0.5" } }, - "array-unique": { - "version": "0.3.2", + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true @@ -2690,55 +1596,18 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, - "atob-lite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/atob-lite/-/atob-lite-2.0.0.tgz", - "integrity": "sha1-D+9a1G8b16hQLGVyfwNn1e5D1pY=", - "dev": true - }, - "babel-polyfill": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", - "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - } - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "core-js": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", - "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", - "dev": true - } - } - }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -2822,9 +1691,9 @@ "dev": true }, "before-after-hook": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.1.0.tgz", - "integrity": "sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz", + "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==", "dev": true }, "binary-extensions": { @@ -3167,12 +2036,6 @@ } } }, - "btoa-lite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", - "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=", - "dev": true - }, "buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", @@ -3235,38 +2098,29 @@ "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", "dev": true }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, "cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", @@ -3394,23 +2248,6 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, - "cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", - "dev": true, - "requires": { - "colors": "1.0.3" - }, - "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", - "dev": true - } - } - }, "cli-table3": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", @@ -3532,21 +2369,14 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true, - "optional": true - }, "compare-func": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", - "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", "dev": true, "requires": { "array-ify": "^1.0.0", - "dot-prop": "^3.0.0" + "dot-prop": "^5.1.0" } }, "compare-versions": { @@ -3616,26 +2446,118 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "conventional-changelog-angular": { - "version": "1.6.6", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-1.6.6.tgz", - "integrity": "sha512-suQnFSqCxRwyBxY68pYTsFkG0taIdinHLNEAX5ivtw8bCRnIgnpvcHmlR/yjUyZIrNPYAoXlY1WiEKWgSE4BNg==", + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", "dev": true, "requires": { - "compare-func": "^1.3.1", + "compare-func": "^2.0.0", "q": "^1.5.1" } }, "conventional-changelog-conventionalcommits": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.2.1.tgz", - "integrity": "sha512-vC02KucnkNNap+foDKFm7BVUSDAXktXrUJqGszUuYnt6T0J2azsbYz/w9TDc3VsrW2v6JOtiQWVcgZnporHr4Q==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.1.tgz", + "integrity": "sha512-lzWJpPZhbM1R0PIzkwzGBCnAkH5RKJzJfFQZcl/D+2lsJxAwGnDKBqn/F4C1RD31GJNn8NuKWQzAZDAVXPp2Mw==", "dev": true, "requires": { - "compare-func": "^1.3.1", - "lodash": "^4.2.1", + "compare-func": "^2.0.0", + "lodash": "^4.17.15", "q": "^1.5.1" } }, + "conventional-changelog-writer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.1.0.tgz", + "integrity": "sha512-WwKcUp7WyXYGQmkLsX4QmU42AZ1lqlvRW9mqoyiQzdD+rJWbTepdWoKJuwXTS+yq79XKnQNa93/roViPQrAQgw==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.3.tgz", + "integrity": "sha512-YyRDR7On9H07ICFpRm/igcdjIqebXbvf4Cff+Pf0BrBys1i1EOzx9iFXNlAbdrLAR8jf7bkUYkDAr8pEy0q4Pw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -3670,12 +2592,6 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true }, - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - }, "core-js-pure": { "version": "3.6.5", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", @@ -3698,41 +2614,50 @@ } }, "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", "dev": true, "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" }, "dependencies": { "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" } }, "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "dev": true } } @@ -3775,16 +2700,25 @@ } }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "crypto-browserify": { @@ -3807,9 +2741,9 @@ } }, "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", + "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, "cucumber": { @@ -3906,15 +2840,6 @@ "integrity": "sha512-+x5j1IfZrBtbvYHuoUX0rl4nUGxaey6Do9sM0CABmZfDCcWXuuRm1fQeCaklIYQgOFHQ6xOHvDSdkMHHpni6tQ==", "dev": true }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, "custom-event": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", @@ -3930,6 +2855,12 @@ "type": "^1.0.1" } }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, "dash-ast": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", @@ -3947,6 +2878,12 @@ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", "dev": true }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3969,6 +2906,14 @@ "requires": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } } }, "decode-uri-component": { @@ -4054,6 +2999,33 @@ "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", "dev": true }, + "del": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-6.0.0.tgz", + "integrity": "sha512-1shh9DQ23L16oXSZKB2JxpL7iMy2E0S9d517ptA1P8iw0alkPtQcrKH7ru31rYtKwF499HkTu+DRzq3TCKDFRQ==", + "dev": true, + "requires": { + "globby": "^11.0.1", + "graceful-fs": "^4.2.4", + "is-glob": "^4.0.1", + "is-path-cwd": "^2.2.0", + "is-path-inside": "^3.0.2", + "p-map": "^4.0.0", + "rimraf": "^3.0.2", + "slash": "^3.0.0" + }, + "dependencies": { + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + } + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -4170,12 +3142,12 @@ "dev": true }, "dot-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", - "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", "dev": true, "requires": { - "is-obj": "^1.0.0" + "is-obj": "^2.0.0" } }, "duplexer": { @@ -4234,15 +3206,6 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, "engine.io": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.0.0.tgz", @@ -4298,12 +3261,13 @@ "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=" }, "env-ci": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-4.5.2.tgz", - "integrity": "sha512-lS+edpNp2+QXEPkx6raEMIjKxKKWnJ4+VWzovYJ2NLYiJAYenSAXotFfVdgaFxdbVnvAbUI8epQDa1u12ERxfQ==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-5.4.0.tgz", + "integrity": "sha512-6Bq7gq+2QCZjCwe2vUXTcecIsjfh71kyNds5nBrpyuyPjgYgGEHlgjkrKSH6LFwJ5PSEwH3r7KXioGreJKcuHA==", "dev": true, "requires": { - "execa": "^3.2.0", + "execa": "^5.0.0", + "fromentries": "^1.3.2", "java-properties": "^1.0.0" } }, @@ -4860,118 +3824,53 @@ } }, "execa": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", - "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "dependencies": { - "cross-spawn": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", - "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "is-descriptor": "^0.1.0" } }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "mimic-fn": "^2.1.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "^0.1.0" } } } @@ -5109,42 +4008,41 @@ "dev": true }, "fast-glob": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", - "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" }, "dependencies": { "glob-parent": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", - "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" } }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true } } @@ -5162,9 +4060,9 @@ "dev": true }, "fastq": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.7.0.tgz", - "integrity": "sha512-YOadQRnHd5q6PogvAR/x62BGituF2ufiEA6s8aavQANw5YKHERI4AREboX6KotzP8oX2klxYF2wcV/7bn1clfQ==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -5180,9 +4078,9 @@ } }, "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -5366,6 +4264,12 @@ "readable-stream": "^2.0.0" } }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, "fs-access": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", @@ -5426,13 +4330,10 @@ "dev": true }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true }, "get-value": { "version": "2.0.6", @@ -5471,6 +4372,41 @@ } } }, + "git-raw-commits": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.10.tgz", + "integrity": "sha512-sHhX5lsbG9SOO6yXdlwgEMQ/ljIn7qMpAbJZCGfXX2fq5T8M5SrDnpYk9/4HswTildcIqatsWa91vty6VhWSaQ==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + } + } + }, "glob": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", @@ -5519,31 +4455,23 @@ } }, "globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "requires": { - "@types/glob": "^7.1.1", "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", "slash": "^3.0.0" }, "dependencies": { - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true } } @@ -5559,6 +4487,19 @@ "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", "dev": true }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -5709,28 +4650,32 @@ } }, "http-proxy-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-3.0.0.tgz", - "integrity": "sha512-uGuJaBWQWDQCJI5ip0d/VTYZW0nRrlLWXA4A7P1jrsa+f77rW2yXz315oBt6zGCF6l8C2tlMxY7ffULCj+5FhA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, "requires": { - "agent-base": "5", + "@tootallnate/once": "1", + "agent-base": "6", "debug": "4" }, "dependencies": { "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "ms": { @@ -5781,9 +4726,9 @@ } }, "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, "husky": { @@ -5999,9 +4944,9 @@ "dev": true }, "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, "inflight": { @@ -6060,9 +5005,9 @@ } }, "into-stream": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-5.1.1.tgz", - "integrity": "sha512-krrAJ7McQxGGmvaYbB7Q1mcA+cRwg9Ij2RfWIeVesNBgVDZmzY/Fa4IpZUT3bmdRzMzdf/mzltCG2Dq99IZGBA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-6.0.0.tgz", + "integrity": "sha512-XHbaOAvP+uFKUFsOgoNPRjLkwB+I22JFPFe5OjTkQ0nwgj6+pSjb4NmB6VMxaPshLiOf+zcpOCBQuLwC1KHhZA==", "dev": true, "requires": { "from2": "^2.3.0", @@ -6115,6 +5060,15 @@ "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", "dev": true }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -6160,12 +5114,6 @@ } } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true - }, "is-docker": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.1.1.tgz", @@ -6224,9 +5172,9 @@ } }, "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "dev": true }, "is-object": { @@ -6235,6 +5183,18 @@ "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", "dev": true }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -6266,9 +5226,9 @@ "dev": true }, "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-string": { @@ -6334,9 +5294,9 @@ "dev": true }, "issue-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-5.0.0.tgz", - "integrity": "sha512-q/16W7EPHRL0FKVz9NU++TUsoygXGj6JOi88oulyAcQG+IEZ0T6teVdE+VLbe19OfL/tbV8Wi3Dfo0HedeHW0Q==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz", + "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==", "dev": true, "requires": { "lodash.capitalize": "^4.2.1", @@ -6386,6 +5346,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6654,12 +5620,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, "lodash.capitalize": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz", @@ -6672,12 +5632,6 @@ "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=", "dev": true }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", - "dev": true - }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -6702,43 +5656,6 @@ "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", "dev": true }, - "lodash.set": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", - "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=", - "dev": true - }, - "lodash.template": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", - "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0", - "lodash.templatesettings": "^4.0.0" - } - }, - "lodash.templatesettings": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", - "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", - "dev": true, - "requires": { - "lodash._reinterpolate": "^3.0.0" - } - }, - "lodash.toarray": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", - "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, "lodash.uniqby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz", @@ -6771,116 +5688,375 @@ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "2.1.2" + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "lolex": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", + "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", + "dev": true + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "marked": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/marked/-/marked-2.1.3.tgz", + "integrity": "sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==", + "dev": true + }, + "marked-terminal": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-4.2.0.tgz", + "integrity": "sha512-DQfNRV9svZf0Dm9Cf5x5xaVJ1+XjxQW6XjFJ5HFkVyK52SDpj5PCBzS5X5r2w9nHr3mlB0T5201UMLue9fmhUw==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.1", + "cardinal": "^2.1.1", + "chalk": "^4.1.0", + "cli-table3": "^0.6.0", + "node-emoji": "^1.10.0", + "supports-hyperlinks": "^2.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli-table3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", + "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "hosted-git-info": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, - "lolex": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz", - "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==", - "dev": true - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "macos-release": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", - "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-stream": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", - "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "marked": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz", - "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==", - "dev": true - }, - "marked-terminal": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-3.3.0.tgz", - "integrity": "sha512-+IUQJ5VlZoAFsM5MHNT7g3RHSkA3eETqhRCdXv4niUMAKHQ7lb1yvAcuGPmm4soxhmtX13u4Li6ZToXtvSEH+A==", - "dev": true, - "requires": { - "ansi-escapes": "^3.1.0", - "cardinal": "^2.1.1", - "chalk": "^2.4.1", - "cli-table": "^0.3.1", - "node-emoji": "^1.4.1", - "supports-hyperlinks": "^1.0.1" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -6894,9 +6070,9 @@ "dev": true }, "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "methods": { @@ -7018,6 +6194,12 @@ "mime-db": "1.44.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -7051,13 +6233,14 @@ "dev": true }, "minimist-options": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" } }, "mixin-deep": { @@ -7253,9 +6436,9 @@ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "nerf-dart": { @@ -7270,12 +6453,6 @@ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "nise": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.0.tgz", @@ -7299,19 +6476,22 @@ } }, "node-emoji": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", - "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", "dev": true, "requires": { - "lodash.toarray": "^4.4.0" + "lodash": "^4.17.21" } }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.5.tgz", + "integrity": "sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==", + "dev": true, + "requires": { + "whatwg-url": "^5.0.0" + } }, "normalize-package-data": { "version": "2.5.0", @@ -7331,1203 +6511,776 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", - "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "dev": true }, "npm": { - "version": "6.14.10", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.10.tgz", - "integrity": "sha512-FT23Qy/JMA+qxEYReMOr1MY7642fKn8Onn+72LASPi872Owvmw0svm+/DXTHOC3yO9CheEO+EslyXEpdBdRtIA==", - "dev": true, - "requires": { - "JSONStream": "^1.3.5", + "version": "7.24.2", + "resolved": "https://registry.npmjs.org/npm/-/npm-7.24.2.tgz", + "integrity": "sha512-120p116CE8VMMZ+hk8IAb1inCPk4Dj3VZw29/n2g6UI77urJKVYb7FZUDW8hY+EBnfsjI/2yrobBgFyzo7YpVQ==", + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^2.9.0", + "@npmcli/ci-detect": "^1.2.0", + "@npmcli/config": "^2.3.0", + "@npmcli/map-workspaces": "^1.0.4", + "@npmcli/package-json": "^1.0.1", + "@npmcli/run-script": "^1.8.6", "abbrev": "~1.1.1", "ansicolors": "~0.3.2", "ansistyles": "~0.1.3", - "aproba": "^2.0.0", "archy": "~1.0.0", - "bin-links": "^1.1.8", - "bluebird": "^3.5.5", - "byte-size": "^5.0.1", - "cacache": "^12.0.3", - "call-limit": "^1.1.1", - "chownr": "^1.1.4", - "ci-info": "^2.0.0", + "cacache": "^15.3.0", + "chalk": "^4.1.2", + "chownr": "^2.0.0", "cli-columns": "^3.1.2", - "cli-table3": "^0.5.1", - "cmd-shim": "^3.0.3", + "cli-table3": "^0.6.0", "columnify": "~1.5.4", - "config-chain": "^1.1.12", - "debuglog": "*", - "detect-indent": "~5.0.0", - "detect-newline": "^2.1.0", - "dezalgo": "~1.0.3", - "editor": "~1.0.0", - "figgy-pudding": "^3.5.1", - "find-npm-prefix": "^1.0.2", - "fs-vacuum": "~1.2.10", - "fs-write-stream-atomic": "~1.0.10", - "gentle-fs": "^2.3.1", - "glob": "^7.1.6", - "graceful-fs": "^4.2.4", - "has-unicode": "~2.0.1", - "hosted-git-info": "^2.8.8", - "iferr": "^1.0.2", - "imurmurhash": "*", - "infer-owner": "^1.0.4", - "inflight": "~1.0.6", - "inherits": "^2.0.4", - "ini": "^1.3.5", - "init-package-json": "^1.10.3", - "is-cidr": "^3.0.0", - "json-parse-better-errors": "^1.0.2", - "lazy-property": "~1.0.0", - "libcipm": "^4.0.8", - "libnpm": "^3.0.1", - "libnpmaccess": "^3.0.2", - "libnpmhook": "^5.0.3", - "libnpmorg": "^1.0.1", - "libnpmsearch": "^2.0.2", - "libnpmteam": "^1.0.2", - "libnpx": "^10.2.4", - "lock-verify": "^2.1.0", - "lockfile": "^1.0.4", - "lodash._baseindexof": "*", - "lodash._baseuniq": "~4.6.0", - "lodash._bindcallback": "*", - "lodash._cacheindexof": "*", - "lodash._createcache": "*", - "lodash._getnative": "*", - "lodash.clonedeep": "~4.5.0", - "lodash.restparam": "*", - "lodash.union": "~4.6.0", - "lodash.uniq": "~4.5.0", - "lodash.without": "~4.4.0", - "lru-cache": "^5.1.1", - "meant": "^1.0.2", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.5", - "move-concurrently": "^1.0.1", - "node-gyp": "^5.1.0", - "nopt": "^4.0.3", - "normalize-package-data": "^2.5.0", - "npm-audit-report": "^1.3.3", - "npm-cache-filename": "~1.0.2", - "npm-install-checks": "^3.0.2", - "npm-lifecycle": "^3.1.5", - "npm-package-arg": "^6.1.1", - "npm-packlist": "^1.4.8", - "npm-pick-manifest": "^3.0.2", - "npm-profile": "^4.0.4", - "npm-registry-fetch": "^4.0.7", + "fastest-levenshtein": "^1.0.12", + "glob": "^7.2.0", + "graceful-fs": "^4.2.8", + "hosted-git-info": "^4.0.2", + "ini": "^2.0.0", + "init-package-json": "^2.0.5", + "is-cidr": "^4.0.2", + "json-parse-even-better-errors": "^2.3.1", + "libnpmaccess": "^4.0.2", + "libnpmdiff": "^2.0.4", + "libnpmexec": "^2.0.1", + "libnpmfund": "^1.1.0", + "libnpmhook": "^6.0.2", + "libnpmorg": "^2.0.2", + "libnpmpack": "^2.0.1", + "libnpmpublish": "^4.0.1", + "libnpmsearch": "^3.1.1", + "libnpmteam": "^2.0.3", + "libnpmversion": "^1.2.1", + "make-fetch-happen": "^9.1.0", + "minipass": "^3.1.3", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "ms": "^2.1.2", + "node-gyp": "^7.1.2", + "nopt": "^5.0.0", + "npm-audit-report": "^2.1.5", + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.1.5", + "npm-pick-manifest": "^6.1.1", + "npm-profile": "^5.0.3", + "npm-registry-fetch": "^11.0.0", "npm-user-validate": "^1.0.1", - "npmlog": "~4.1.2", - "once": "~1.4.0", + "npmlog": "^5.0.1", "opener": "^1.5.2", - "osenv": "^0.1.5", - "pacote": "^9.5.12", - "path-is-inside": "~1.0.2", - "promise-inflight": "~1.0.1", + "pacote": "^11.3.5", + "parse-conflict-json": "^1.1.1", "qrcode-terminal": "^0.12.0", - "query-string": "^6.8.2", - "qw": "~1.0.1", "read": "~1.0.7", - "read-cmd-shim": "^1.0.5", - "read-installed": "~4.0.3", - "read-package-json": "^2.1.1", - "read-package-tree": "^5.3.1", - "readable-stream": "^3.6.0", + "read-package-json": "^4.1.1", + "read-package-json-fast": "^2.0.3", "readdir-scoped-modules": "^1.1.0", - "request": "^2.88.0", - "retry": "^0.12.0", - "rimraf": "^2.7.1", - "safe-buffer": "^5.1.2", - "semver": "^5.7.1", - "sha": "^3.0.0", - "slide": "~1.1.6", - "sorted-object": "~2.0.1", - "sorted-union-stream": "~2.1.3", - "ssri": "^6.0.1", - "stringify-package": "^1.0.1", - "tar": "^4.4.13", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "ssri": "^8.0.1", + "tar": "^6.1.11", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", - "uid-number": "0.0.6", - "umask": "~1.1.0", - "unique-filename": "^1.1.1", - "unpipe": "~1.0.0", - "update-notifier": "^2.5.0", - "uuid": "^3.3.3", - "validate-npm-package-license": "^3.0.4", + "treeverse": "^1.0.4", "validate-npm-package-name": "~3.0.0", - "which": "^1.3.1", - "worker-farm": "^1.7.0", - "write-file-atomic": "^2.4.3" + "which": "^2.0.2", + "write-file-atomic": "^3.0.3" }, "dependencies": { - "JSONStream": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - } - }, - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "bundled": true, - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "agentkeepalive": { - "version": "3.5.2", - "bundled": true, - "dev": true, - "requires": { - "humanize-ms": "^1.2.1" - } - }, - "ansi-align": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.0.0" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "bundled": true, - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "ansicolors": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "ansistyles": { - "version": "0.1.3", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "asap": { - "version": "2.0.6", - "bundled": true, - "dev": true - }, - "asn1": { - "version": "0.2.4", - "bundled": true, - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "bundled": true, - "dev": true - }, - "aws4": { - "version": "1.8.0", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bin-links": { - "version": "1.1.8", + "@gar/promisify": { + "version": "1.1.2", "bundled": true, - "dev": true, - "requires": { - "bluebird": "^3.5.3", - "cmd-shim": "^3.0.0", - "gentle-fs": "^2.3.0", - "graceful-fs": "^4.1.15", - "npm-normalize-package-bin": "^1.0.0", - "write-file-atomic": "^2.3.0" - } + "dev": true }, - "bluebird": { - "version": "3.5.5", + "@isaacs/string-locale-compare": { + "version": "1.1.0", "bundled": true, "dev": true }, - "boxen": { + "@npmcli/arborist": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "requires": { + "@isaacs/string-locale-compare": "^1.0.1", + "@npmcli/installed-package-contents": "^1.0.7", + "@npmcli/map-workspaces": "^1.0.2", + "@npmcli/metavuln-calculator": "^1.1.0", + "@npmcli/move-file": "^1.1.0", + "@npmcli/name-from-folder": "^1.0.1", + "@npmcli/node-gyp": "^1.0.1", + "@npmcli/package-json": "^1.0.1", + "@npmcli/run-script": "^1.8.2", + "bin-links": "^2.2.1", + "cacache": "^15.0.3", + "common-ancestor-path": "^1.0.1", + "json-parse-even-better-errors": "^2.3.1", + "json-stringify-nice": "^1.1.4", + "mkdirp": "^1.0.4", + "mkdirp-infer-owner": "^2.0.0", + "npm-install-checks": "^4.0.0", + "npm-package-arg": "^8.1.5", + "npm-pick-manifest": "^6.1.0", + "npm-registry-fetch": "^11.0.0", + "pacote": "^11.3.5", + "parse-conflict-json": "^1.1.1", + "proc-log": "^1.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^1.0.1", + "read-package-json-fast": "^2.0.2", + "readdir-scoped-modules": "^1.1.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "ssri": "^8.0.1", + "treeverse": "^1.0.4", + "walk-up-path": "^1.0.0" + } + }, + "@npmcli/ci-detect": { "version": "1.3.0", "bundled": true, - "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - } + "dev": true }, - "brace-expansion": { - "version": "1.1.11", + "@npmcli/config": { + "version": "2.3.0", "bundled": true, "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "ini": "^2.0.0", + "mkdirp-infer-owner": "^2.0.0", + "nopt": "^5.0.0", + "semver": "^7.3.4", + "walk-up-path": "^1.0.0" } }, - "buffer-from": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "builtins": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "byline": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "byte-size": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "cacache": { - "version": "12.0.3", + "@npmcli/disparity-colors": { + "version": "1.0.1", "bundled": true, "dev": true, "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" + "ansi-styles": "^4.3.0" } }, - "call-limit": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "capture-stack-trace": { + "@npmcli/fs": { "version": "1.0.0", "bundled": true, - "dev": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "chalk": { - "version": "2.4.1", - "bundled": true, "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@gar/promisify": "^1.0.1", + "semver": "^7.3.5" } }, - "chownr": { - "version": "1.1.4", - "bundled": true, - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "cidr-regex": { - "version": "2.0.10", + "@npmcli/git": { + "version": "2.1.0", "bundled": true, "dev": true, "requires": { - "ip-regex": "^2.1.0" + "@npmcli/promise-spawn": "^1.3.2", + "lru-cache": "^6.0.0", + "mkdirp": "^1.0.4", + "npm-pick-manifest": "^6.1.1", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^2.0.2" } }, - "cli-boxes": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "cli-columns": { - "version": "3.1.2", + "@npmcli/installed-package-contents": { + "version": "1.0.7", "bundled": true, "dev": true, "requires": { - "string-width": "^2.0.0", - "strip-ansi": "^3.0.1" + "npm-bundled": "^1.1.1", + "npm-normalize-package-bin": "^1.0.1" } }, - "cli-table3": { - "version": "0.5.1", + "@npmcli/map-workspaces": { + "version": "1.0.4", "bundled": true, "dev": true, "requires": { - "colors": "^1.1.2", - "object-assign": "^4.1.0", - "string-width": "^2.1.1" + "@npmcli/name-from-folder": "^1.0.1", + "glob": "^7.1.6", + "minimatch": "^3.0.4", + "read-package-json-fast": "^2.0.1" } }, - "cliui": { - "version": "5.0.0", + "@npmcli/metavuln-calculator": { + "version": "1.1.1", "bundled": true, "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "cacache": "^15.0.5", + "pacote": "^11.1.11", + "semver": "^7.3.2" } }, - "clone": { - "version": "1.0.4", - "bundled": true, - "dev": true - }, - "cmd-shim": { - "version": "3.0.3", + "@npmcli/move-file": { + "version": "1.1.2", "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "mkdirp": "~0.5.0" + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" } }, - "code-point-at": { - "version": "1.1.0", + "@npmcli/name-from-folder": { + "version": "1.0.1", "bundled": true, "dev": true }, - "color-convert": { - "version": "1.9.1", - "bundled": true, - "dev": true, - "requires": { - "color-name": "^1.1.1" - } - }, - "color-name": { - "version": "1.1.3", + "@npmcli/node-gyp": { + "version": "1.0.2", "bundled": true, "dev": true }, - "colors": { - "version": "1.3.3", + "@npmcli/package-json": { + "version": "1.0.1", "bundled": true, "dev": true, - "optional": true + "requires": { + "json-parse-even-better-errors": "^2.3.1" + } }, - "columnify": { - "version": "1.5.4", + "@npmcli/promise-spawn": { + "version": "1.3.2", "bundled": true, "dev": true, "requires": { - "strip-ansi": "^3.0.0", - "wcwidth": "^1.0.0" + "infer-owner": "^1.0.4" } }, - "combined-stream": { - "version": "1.0.6", + "@npmcli/run-script": { + "version": "1.8.6", "bundled": true, "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "@npmcli/node-gyp": "^1.0.2", + "@npmcli/promise-spawn": "^1.3.2", + "node-gyp": "^7.1.0", + "read-package-json-fast": "^2.0.1" } }, - "concat-map": { - "version": "0.0.1", + "@tootallnate/once": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "abbrev": { + "version": "1.1.1", "bundled": true, "dev": true }, - "concat-stream": { - "version": "1.6.2", + "agent-base": { + "version": "6.0.2", "bundled": true, "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "debug": "4" } }, - "config-chain": { - "version": "1.1.12", + "agentkeepalive": { + "version": "4.1.4", "bundled": true, "dev": true, "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" } }, - "configstore": { - "version": "3.1.5", + "aggregate-error": { + "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "dot-prop": "^4.2.1", - "graceful-fs": "^4.1.2", - "make-dir": "^1.0.0", - "unique-string": "^1.0.0", - "write-file-atomic": "^2.0.0", - "xdg-basedir": "^3.0.0" + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" } }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", + "ajv": { + "version": "6.12.6", "bundled": true, "dev": true, "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "iferr": { - "version": "0.1.5", - "bundled": true, - "dev": true - } + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "core-util-is": { - "version": "1.0.2", + "ansi-regex": { + "version": "2.1.1", "bundled": true, "dev": true }, - "create-error-class": { - "version": "3.0.2", + "ansi-styles": { + "version": "4.3.0", "bundled": true, "dev": true, "requires": { - "capture-stack-trace": "^1.0.0" + "color-convert": "^2.0.1" } }, - "cross-spawn": { - "version": "5.1.0", + "ansicolors": { + "version": "0.3.2", "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "lru-cache": { - "version": "4.1.5", - "bundled": true, - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "yallist": { - "version": "2.1.2", - "bundled": true, - "dev": true - } - } + "dev": true }, - "crypto-random-string": { - "version": "1.0.0", + "ansistyles": { + "version": "0.1.3", "bundled": true, "dev": true }, - "cyclist": { - "version": "0.2.2", + "aproba": { + "version": "2.0.0", "bundled": true, "dev": true }, - "dashdash": { - "version": "1.14.1", + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.6", "bundled": true, "dev": true, "requires": { - "assert-plus": "^1.0.0" + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" } }, - "debug": { - "version": "3.1.0", + "asap": { + "version": "2.0.6", + "bundled": true, + "dev": true + }, + "asn1": { + "version": "0.2.4", "bundled": true, "dev": true, "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true - } + "safer-buffer": "~2.1.0" } }, - "debuglog": { - "version": "1.0.1", + "assert-plus": { + "version": "1.0.0", "bundled": true, "dev": true }, - "decamelize": { - "version": "1.2.0", + "asynckit": { + "version": "0.4.0", + "bundled": true, + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", "bundled": true, "dev": true }, - "decode-uri-component": { - "version": "0.2.0", + "aws4": { + "version": "1.11.0", "bundled": true, "dev": true }, - "deep-extend": { - "version": "0.6.0", + "balanced-match": { + "version": "1.0.2", "bundled": true, "dev": true }, - "defaults": { - "version": "1.0.3", + "bcrypt-pbkdf": { + "version": "1.0.2", "bundled": true, "dev": true, "requires": { - "clone": "^1.0.2" + "tweetnacl": "^0.14.3" } }, - "define-properties": { - "version": "1.1.3", + "bin-links": { + "version": "2.2.1", "bundled": true, "dev": true, "requires": { - "object-keys": "^1.0.12" + "cmd-shim": "^4.0.1", + "mkdirp": "^1.0.3", + "npm-normalize-package-bin": "^1.0.0", + "read-cmd-shim": "^2.0.0", + "rimraf": "^3.0.0", + "write-file-atomic": "^3.0.3" } }, - "delayed-stream": { - "version": "1.0.0", + "binary-extensions": { + "version": "2.2.0", "bundled": true, "dev": true }, - "delegates": { - "version": "1.0.0", + "brace-expansion": { + "version": "1.1.11", "bundled": true, - "dev": true + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "detect-indent": { - "version": "5.0.0", + "builtins": { + "version": "1.0.3", "bundled": true, "dev": true }, - "detect-newline": { - "version": "2.1.0", + "cacache": { + "version": "15.3.0", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/fs": "^1.0.0", + "@npmcli/move-file": "^1.0.1", + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "infer-owner": "^1.0.4", + "lru-cache": "^6.0.0", + "minipass": "^3.1.1", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^1.0.3", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.0.2", + "unique-filename": "^1.1.1" + } + }, + "caseless": { + "version": "0.12.0", "bundled": true, "dev": true }, - "dezalgo": { - "version": "1.0.3", + "chalk": { + "version": "4.1.2", "bundled": true, "dev": true, "requires": { - "asap": "^2.0.0", - "wrappy": "1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "dot-prop": { - "version": "4.2.1", + "chownr": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "cidr-regex": { + "version": "3.1.1", "bundled": true, "dev": true, "requires": { - "is-obj": "^1.0.0" + "ip-regex": "^4.1.0" } }, - "dotenv": { - "version": "5.0.1", + "clean-stack": { + "version": "2.2.0", "bundled": true, "dev": true }, - "duplexer3": { - "version": "0.1.4", + "cli-columns": { + "version": "3.1.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "string-width": "^2.0.0", + "strip-ansi": "^3.0.1" + } }, - "duplexify": { - "version": "3.6.0", + "cli-table3": { + "version": "0.6.0", "bundled": true, "dev": true, "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^4.2.0" }, "dependencies": { - "readable-stream": { - "version": "2.3.6", + "ansi-regex": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "4.2.2", "bundled": true, "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "string_decoder": { - "version": "1.1.1", + "strip-ansi": { + "version": "6.0.0", "bundled": true, "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "ansi-regex": "^5.0.0" } } } }, - "ecc-jsbn": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "editor": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", + "clone": { + "version": "1.0.4", "bundled": true, "dev": true }, - "encoding": { - "version": "0.1.12", + "cmd-shim": { + "version": "4.1.0", "bundled": true, "dev": true, "requires": { - "iconv-lite": "~0.4.13" + "mkdirp-infer-owner": "^2.0.0" } }, - "end-of-stream": { - "version": "1.4.1", + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "color-convert": { + "version": "2.0.1", "bundled": true, "dev": true, "requires": { - "once": "^1.4.0" + "color-name": "~1.1.4" } }, - "env-paths": { - "version": "2.2.0", + "color-name": { + "version": "1.1.4", "bundled": true, "dev": true }, - "err-code": { - "version": "1.1.2", + "color-support": { + "version": "1.1.3", "bundled": true, "dev": true }, - "errno": { - "version": "0.1.7", + "colors": { + "version": "1.4.0", "bundled": true, "dev": true, - "requires": { - "prr": "~1.0.1" - } + "optional": true }, - "es-abstract": { - "version": "1.12.0", + "columnify": { + "version": "1.5.4", "bundled": true, "dev": true, "requires": { - "es-to-primitive": "^1.1.1", - "function-bind": "^1.1.1", - "has": "^1.0.1", - "is-callable": "^1.1.3", - "is-regex": "^1.0.4" + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" } }, - "es-to-primitive": { - "version": "1.2.0", + "combined-stream": { + "version": "1.0.8", "bundled": true, "dev": true, "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" + "delayed-stream": "~1.0.0" } }, - "es6-promise": { - "version": "4.2.8", + "common-ancestor-path": { + "version": "1.0.1", "bundled": true, "dev": true }, - "es6-promisify": { - "version": "5.0.0", + "concat-map": { + "version": "0.0.1", "bundled": true, - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } + "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", + "console-control-strings": { + "version": "1.1.0", "bundled": true, "dev": true }, - "execa": { - "version": "0.7.0", + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "dashdash": { + "version": "1.14.1", "bundled": true, "dev": true, "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "4.3.2", + "bundled": true, + "dev": true, + "requires": { + "ms": "2.1.2" }, "dependencies": { - "get-stream": { - "version": "3.0.0", + "ms": { + "version": "2.1.2", "bundled": true, "dev": true } } }, - "extend": { - "version": "3.0.2", + "debuglog": { + "version": "1.0.1", "bundled": true, "dev": true }, - "extsprintf": { - "version": "1.3.0", + "defaults": { + "version": "1.0.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "clone": "^1.0.2" + } }, - "fast-json-stable-stringify": { - "version": "2.0.0", + "delayed-stream": { + "version": "1.0.0", "bundled": true, "dev": true }, - "figgy-pudding": { - "version": "3.5.1", + "delegates": { + "version": "1.0.0", "bundled": true, "dev": true }, - "find-npm-prefix": { - "version": "1.0.2", + "depd": { + "version": "1.1.2", "bundled": true, "dev": true }, - "flush-write-stream": { + "dezalgo": { "version": "1.0.3", "bundled": true, "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.4" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "asap": "^2.0.0", + "wrappy": "1" } }, - "forever-agent": { - "version": "0.6.1", + "diff": { + "version": "5.0.0", "bundled": true, "dev": true }, - "form-data": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, - "from2": { - "version": "2.3.0", + "ecc-jsbn": { + "version": "0.1.2", "bundled": true, "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "fs-minipass": { - "version": "1.2.7", + "emoji-regex": { + "version": "8.0.0", "bundled": true, - "dev": true, - "requires": { - "minipass": "^2.6.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } + "dev": true }, - "fs-vacuum": { - "version": "1.2.10", + "encoding": { + "version": "0.1.13", "bundled": true, "dev": true, + "optional": true, "requires": { - "graceful-fs": "^4.1.2", - "path-is-inside": "^1.0.1", - "rimraf": "^2.5.2" + "iconv-lite": "^0.6.2" } }, - "fs-write-stream-atomic": { - "version": "1.0.10", + "env-paths": { + "version": "2.2.1", "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - }, - "dependencies": { - "iferr": { - "version": "0.1.5", - "bundled": true, - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } + "dev": true }, - "fs.realpath": { - "version": "1.0.0", + "err-code": { + "version": "2.0.3", "bundled": true, "dev": true }, - "function-bind": { - "version": "1.1.1", + "extend": { + "version": "3.0.2", "bundled": true, "dev": true }, - "gauge": { - "version": "2.7.4", + "extsprintf": { + "version": "1.3.0", "bundled": true, - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } + "dev": true }, - "genfun": { - "version": "5.0.0", + "fast-deep-equal": { + "version": "3.1.3", "bundled": true, "dev": true }, - "gentle-fs": { - "version": "2.3.1", + "fast-json-stable-stringify": { + "version": "2.1.0", + "bundled": true, + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "bundled": true, + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "bundled": true, + "dev": true + }, + "fs-minipass": { + "version": "2.1.0", "bundled": true, "dev": true, "requires": { - "aproba": "^1.1.2", - "chownr": "^1.1.2", - "cmd-shim": "^3.0.3", - "fs-vacuum": "^1.2.10", - "graceful-fs": "^4.1.11", - "iferr": "^0.1.5", - "infer-owner": "^1.0.4", - "mkdirp": "^0.5.1", - "path-is-inside": "^1.0.2", - "read-cmd-shim": "^1.0.1", - "slide": "^1.1.6" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "iferr": { - "version": "0.1.5", - "bundled": true, - "dev": true - } + "minipass": "^3.0.0" } }, - "get-caller-file": { - "version": "2.0.5", + "fs.realpath": { + "version": "1.0.0", "bundled": true, "dev": true }, - "get-stream": { - "version": "4.1.0", + "function-bind": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "gauge": { + "version": "3.0.1", "bundled": true, "dev": true, "requires": { - "pump": "^3.0.0" + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1 || ^2.0.0", + "strip-ansi": "^3.0.1 || ^4.0.0", + "wide-align": "^1.1.2" } }, "getpass": { @@ -8539,7 +7292,7 @@ } }, "glob": { - "version": "7.1.6", + "version": "7.2.0", "bundled": true, "dev": true, "requires": { @@ -8551,41 +7304,8 @@ "path-is-absolute": "^1.0.0" } }, - "global-dirs": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "requires": { - "ini": "^1.3.4" - } - }, - "got": { - "version": "6.7.1", - "bundled": true, - "dev": true, - "requires": { - "create-error-class": "^3.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^3.0.0", - "is-redirect": "^1.0.0", - "is-retry-allowed": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "safe-buffer": "^5.0.1", - "timed-out": "^4.0.0", - "unzip-response": "^2.0.1", - "url-parse-lax": "^1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "3.0.0", - "bundled": true, - "dev": true - } - } - }, "graceful-fs": { - "version": "4.2.4", + "version": "4.2.8", "bundled": true, "dev": true }, @@ -8601,29 +7321,6 @@ "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "bundled": true, - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "bundled": true, - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "bundled": true, - "dev": true - } } }, "has": { @@ -8635,12 +7332,7 @@ } }, "has-flag": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "has-symbols": { - "version": "1.0.0", + "version": "4.0.0", "bundled": true, "dev": true }, @@ -8650,22 +7342,26 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", + "version": "4.0.2", "bundled": true, - "dev": true + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "http-cache-semantics": { - "version": "3.8.1", + "version": "4.1.0", "bundled": true, "dev": true }, "http-proxy-agent": { - "version": "2.1.0", + "version": "4.0.1", "bundled": true, "dev": true, "requires": { - "agent-base": "4", - "debug": "3.1.0" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" } }, "http-signature": { @@ -8679,12 +7375,12 @@ } }, "https-proxy-agent": { - "version": "2.2.4", + "version": "5.0.0", "bundled": true, "dev": true, "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" + "agent-base": "6", + "debug": "4" } }, "humanize-ms": { @@ -8696,33 +7392,29 @@ } }, "iconv-lite": { - "version": "0.4.23", + "version": "0.6.3", "bundled": true, "dev": true, + "optional": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" } }, - "iferr": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, "ignore-walk": { - "version": "3.0.3", + "version": "3.0.4", "bundled": true, "dev": true, "requires": { "minimatch": "^3.0.4" } }, - "import-lazy": { - "version": "2.1.0", + "imurmurhash": { + "version": "0.1.4", "bundled": true, "dev": true }, - "imurmurhash": { - "version": "0.1.4", + "indent-string": { + "version": "4.0.0", "bundled": true, "dev": true }, @@ -8746,22 +7438,21 @@ "dev": true }, "ini": { - "version": "1.3.5", + "version": "2.0.0", "bundled": true, "dev": true }, "init-package-json": { - "version": "1.10.3", + "version": "2.0.5", "bundled": true, "dev": true, "requires": { - "glob": "^7.1.1", - "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", + "npm-package-arg": "^8.1.5", "promzard": "^0.3.0", "read": "~1.0.1", - "read-package-json": "1 || 2", - "semver": "2.x || 3.x || 4 || 5", - "validate-npm-package-license": "^3.0.1", + "read-package-json": "^4.1.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^3.0.0" } }, @@ -8771,119 +7462,41 @@ "dev": true }, "ip-regex": { - "version": "2.1.0", - "bundled": true, - "dev": true - }, - "is-callable": { - "version": "1.1.4", + "version": "4.3.0", "bundled": true, "dev": true }, - "is-ci": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "requires": { - "ci-info": "^1.5.0" - }, - "dependencies": { - "ci-info": { - "version": "1.6.0", - "bundled": true, - "dev": true - } - } - }, "is-cidr": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "cidr-regex": "^2.0.10" - } - }, - "is-date-object": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", + "version": "4.0.2", "bundled": true, "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "cidr-regex": "^3.1.1" } }, - "is-installed-globally": { - "version": "0.1.0", + "is-core-module": { + "version": "2.7.0", "bundled": true, "dev": true, "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" + "has": "^1.0.3" } }, - "is-npm": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-obj": { - "version": "1.0.1", + "is-fullwidth-code-point": { + "version": "2.0.0", "bundled": true, "dev": true }, - "is-path-inside": { + "is-lambda": { "version": "1.0.1", "bundled": true, - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-redirect": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-retry-allowed": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, "dev": true }, - "is-symbol": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, "is-typedarray": { "version": "1.0.0", "bundled": true, "dev": true }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, "isexe": { "version": "2.0.0", "bundled": true, @@ -8897,11 +7510,10 @@ "jsbn": { "version": "0.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, - "json-parse-better-errors": { - "version": "1.0.2", + "json-parse-even-better-errors": { + "version": "2.3.1", "bundled": true, "dev": true }, @@ -8910,6 +7522,16 @@ "bundled": true, "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "bundled": true, + "dev": true + }, + "json-stringify-nice": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "bundled": true, @@ -8931,624 +7553,455 @@ "verror": "1.10.0" } }, - "latest-version": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "package-json": "^4.0.0" - } + "just-diff": { + "version": "3.1.1", + "bundled": true, + "dev": true }, - "lazy-property": { - "version": "1.0.0", + "just-diff-apply": { + "version": "3.0.0", "bundled": true, "dev": true }, - "libcipm": { - "version": "4.0.8", + "libnpmaccess": { + "version": "4.0.3", "bundled": true, "dev": true, "requires": { - "bin-links": "^1.1.2", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.5.1", - "find-npm-prefix": "^1.0.2", - "graceful-fs": "^4.1.11", - "ini": "^1.3.5", - "lock-verify": "^2.1.0", - "mkdirp": "^0.5.1", - "npm-lifecycle": "^3.0.0", - "npm-logical-tree": "^1.2.1", - "npm-package-arg": "^6.1.0", - "pacote": "^9.1.0", - "read-package-json": "^2.0.13", - "rimraf": "^2.6.2", - "worker-farm": "^1.6.0" - } - }, - "libnpm": { - "version": "3.0.1", + "aproba": "^2.0.0", + "minipass": "^3.1.1", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0" + } + }, + "libnpmdiff": { + "version": "2.0.4", "bundled": true, "dev": true, "requires": { - "bin-links": "^1.1.2", - "bluebird": "^3.5.3", - "find-npm-prefix": "^1.0.2", - "libnpmaccess": "^3.0.2", - "libnpmconfig": "^1.2.1", - "libnpmhook": "^5.0.3", - "libnpmorg": "^1.0.1", - "libnpmpublish": "^1.1.2", - "libnpmsearch": "^2.0.2", - "libnpmteam": "^1.0.2", - "lock-verify": "^2.0.2", - "npm-lifecycle": "^3.0.0", - "npm-logical-tree": "^1.2.1", - "npm-package-arg": "^6.1.0", - "npm-profile": "^4.0.2", - "npm-registry-fetch": "^4.0.0", - "npmlog": "^4.1.2", - "pacote": "^9.5.3", - "read-package-json": "^2.0.13", - "stringify-package": "^1.0.0" + "@npmcli/disparity-colors": "^1.0.1", + "@npmcli/installed-package-contents": "^1.0.7", + "binary-extensions": "^2.2.0", + "diff": "^5.0.0", + "minimatch": "^3.0.4", + "npm-package-arg": "^8.1.4", + "pacote": "^11.3.4", + "tar": "^6.1.0" } }, - "libnpmaccess": { - "version": "3.0.2", + "libnpmexec": { + "version": "2.0.1", "bundled": true, "dev": true, "requires": { - "aproba": "^2.0.0", - "get-stream": "^4.0.0", - "npm-package-arg": "^6.1.0", - "npm-registry-fetch": "^4.0.0" + "@npmcli/arborist": "^2.3.0", + "@npmcli/ci-detect": "^1.3.0", + "@npmcli/run-script": "^1.8.4", + "chalk": "^4.1.0", + "mkdirp-infer-owner": "^2.0.0", + "npm-package-arg": "^8.1.2", + "pacote": "^11.3.1", + "proc-log": "^1.0.0", + "read": "^1.0.7", + "read-package-json-fast": "^2.0.2", + "walk-up-path": "^1.0.0" } }, - "libnpmconfig": { - "version": "1.2.1", + "libnpmfund": { + "version": "1.1.0", "bundled": true, "dev": true, "requires": { - "figgy-pudding": "^3.5.1", - "find-up": "^3.0.0", - "ini": "^1.3.5" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.2.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "bundled": true, - "dev": true - } + "@npmcli/arborist": "^2.5.0" } }, "libnpmhook": { - "version": "5.0.3", + "version": "6.0.3", "bundled": true, "dev": true, "requires": { "aproba": "^2.0.0", - "figgy-pudding": "^3.4.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" + "npm-registry-fetch": "^11.0.0" } }, "libnpmorg": { - "version": "1.0.1", + "version": "2.0.3", "bundled": true, "dev": true, "requires": { "aproba": "^2.0.0", - "figgy-pudding": "^3.4.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" + "npm-registry-fetch": "^11.0.0" + } + }, + "libnpmpack": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "@npmcli/run-script": "^1.8.3", + "npm-package-arg": "^8.1.0", + "pacote": "^11.2.6" } }, "libnpmpublish": { - "version": "1.1.2", + "version": "4.0.2", "bundled": true, "dev": true, "requires": { - "aproba": "^2.0.0", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.0.0", - "lodash.clonedeep": "^4.5.0", - "normalize-package-data": "^2.4.0", - "npm-package-arg": "^6.1.0", - "npm-registry-fetch": "^4.0.0", - "semver": "^5.5.1", - "ssri": "^6.0.1" + "normalize-package-data": "^3.0.2", + "npm-package-arg": "^8.1.2", + "npm-registry-fetch": "^11.0.0", + "semver": "^7.1.3", + "ssri": "^8.0.1" } }, "libnpmsearch": { - "version": "2.0.2", + "version": "3.1.2", "bundled": true, "dev": true, "requires": { - "figgy-pudding": "^3.5.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" + "npm-registry-fetch": "^11.0.0" } }, "libnpmteam": { - "version": "1.0.2", + "version": "2.0.4", "bundled": true, "dev": true, "requires": { "aproba": "^2.0.0", - "figgy-pudding": "^3.4.1", - "get-stream": "^4.0.0", - "npm-registry-fetch": "^4.0.0" + "npm-registry-fetch": "^11.0.0" } }, - "libnpx": { - "version": "10.2.4", + "libnpmversion": { + "version": "1.2.1", "bundled": true, "dev": true, "requires": { - "dotenv": "^5.0.1", - "npm-package-arg": "^6.0.0", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.0", - "update-notifier": "^2.3.0", - "which": "^1.3.0", - "y18n": "^4.0.0", - "yargs": "^14.2.3" + "@npmcli/git": "^2.0.7", + "@npmcli/run-script": "^1.8.4", + "json-parse-even-better-errors": "^2.3.1", + "semver": "^7.3.5", + "stringify-package": "^1.0.1" } }, - "lock-verify": { - "version": "2.1.0", + "lru-cache": { + "version": "6.0.0", "bundled": true, "dev": true, "requires": { - "npm-package-arg": "^6.1.0", - "semver": "^5.4.1" + "yallist": "^4.0.0" } }, - "lockfile": { - "version": "1.0.4", + "make-fetch-happen": { + "version": "9.1.0", "bundled": true, "dev": true, "requires": { - "signal-exit": "^3.0.2" + "agentkeepalive": "^4.1.3", + "cacache": "^15.2.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^6.0.0", + "minipass": "^3.1.3", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^1.3.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.2", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^6.0.0", + "ssri": "^8.0.0" } }, - "lodash._baseindexof": { - "version": "3.1.0", + "mime-db": { + "version": "1.49.0", "bundled": true, "dev": true }, - "lodash._baseuniq": { - "version": "4.6.0", + "mime-types": { + "version": "2.1.32", "bundled": true, "dev": true, "requires": { - "lodash._createset": "~4.0.0", - "lodash._root": "~3.0.0" + "mime-db": "1.49.0" } }, - "lodash._bindcallback": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "lodash._cacheindexof": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "lodash._createcache": { - "version": "3.1.2", + "minimatch": { + "version": "3.0.4", "bundled": true, "dev": true, "requires": { - "lodash._getnative": "^3.0.0" + "brace-expansion": "^1.1.7" } }, - "lodash._createset": { - "version": "4.0.3", - "bundled": true, - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "bundled": true, - "dev": true - }, - "lodash._root": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "bundled": true, - "dev": true - }, - "lodash.restparam": { - "version": "3.6.1", - "bundled": true, - "dev": true - }, - "lodash.union": { - "version": "4.6.0", - "bundled": true, - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "bundled": true, - "dev": true - }, - "lodash.without": { - "version": "4.4.0", - "bundled": true, - "dev": true - }, - "lowercase-keys": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "lru-cache": { - "version": "5.1.1", + "minipass": { + "version": "3.1.5", "bundled": true, "dev": true, "requires": { - "yallist": "^3.0.2" + "yallist": "^4.0.0" } }, - "make-dir": { - "version": "1.3.0", + "minipass-collect": { + "version": "1.0.2", "bundled": true, "dev": true, "requires": { - "pify": "^3.0.0" + "minipass": "^3.0.0" } }, - "make-fetch-happen": { - "version": "5.0.2", + "minipass-fetch": { + "version": "1.4.1", "bundled": true, "dev": true, "requires": { - "agentkeepalive": "^3.4.1", - "cacache": "^12.0.0", - "http-cache-semantics": "^3.8.1", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "node-fetch-npm": "^2.0.2", - "promise-retry": "^1.1.1", - "socks-proxy-agent": "^4.0.0", - "ssri": "^6.0.0" + "encoding": "^0.1.12", + "minipass": "^3.1.0", + "minipass-sized": "^1.0.3", + "minizlib": "^2.0.0" } }, - "meant": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "mime-db": { - "version": "1.35.0", - "bundled": true, - "dev": true - }, - "mime-types": { - "version": "2.1.19", + "minipass-flush": { + "version": "1.0.5", "bundled": true, "dev": true, "requires": { - "mime-db": "~1.35.0" + "minipass": "^3.0.0" } }, - "minimatch": { - "version": "3.0.4", + "minipass-json-stream": { + "version": "1.0.1", "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "jsonparse": "^1.3.1", + "minipass": "^3.0.0" } }, - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true - }, - "minizlib": { - "version": "1.3.3", + "minipass-pipeline": { + "version": "1.2.4", "bundled": true, "dev": true, "requires": { - "minipass": "^2.9.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } + "minipass": "^3.0.0" } }, - "mississippi": { - "version": "3.0.0", + "minipass-sized": { + "version": "1.0.3", "bundled": true, "dev": true, "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" + "minipass": "^3.0.0" } }, - "mkdirp": { - "version": "0.5.5", + "minizlib": { + "version": "2.1.2", "bundled": true, "dev": true, "requires": { - "minimist": "^1.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "bundled": true, - "dev": true - } + "minipass": "^3.0.0", + "yallist": "^4.0.0" } }, - "move-concurrently": { - "version": "1.0.1", + "mkdirp": { + "version": "1.0.4", + "bundled": true, + "dev": true + }, + "mkdirp-infer-owner": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - }, - "dependencies": { - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true - } + "chownr": "^2.0.0", + "infer-owner": "^1.0.4", + "mkdirp": "^1.0.3" } }, "ms": { - "version": "2.1.1", + "version": "2.1.3", "bundled": true, "dev": true }, "mute-stream": { - "version": "0.0.7", + "version": "0.0.8", "bundled": true, "dev": true }, - "node-fetch-npm": { - "version": "2.0.2", + "negotiator": { + "version": "0.6.2", "bundled": true, - "dev": true, - "requires": { - "encoding": "^0.1.11", - "json-parse-better-errors": "^1.0.0", - "safe-buffer": "^5.1.1" - } + "dev": true }, "node-gyp": { - "version": "5.1.0", + "version": "7.1.2", "bundled": true, "dev": true, "requires": { "env-paths": "^2.2.0", "glob": "^7.1.4", - "graceful-fs": "^4.2.2", - "mkdirp": "^0.5.1", - "nopt": "^4.0.1", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", "npmlog": "^4.1.2", - "request": "^2.88.0", - "rimraf": "^2.6.3", - "semver": "^5.7.1", - "tar": "^4.4.12", - "which": "^1.3.1" + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "dependencies": { + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } } }, "nopt": { - "version": "4.0.3", + "version": "5.0.0", "bundled": true, "dev": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1" } }, "normalize-package-data": { - "version": "2.5.0", + "version": "3.0.3", "bundled": true, "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "resolve": { - "version": "1.10.0", - "bundled": true, - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } } }, "npm-audit-report": { - "version": "1.3.3", + "version": "2.1.5", "bundled": true, "dev": true, "requires": { - "cli-table3": "^0.5.0", - "console-control-strings": "^1.1.0" + "chalk": "^4.0.0" } }, "npm-bundled": { - "version": "1.1.1", + "version": "1.1.2", "bundled": true, "dev": true, "requires": { "npm-normalize-package-bin": "^1.0.1" } }, - "npm-cache-filename": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, "npm-install-checks": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "semver": "^2.3.0 || 3.x || 4 || 5" - } - }, - "npm-lifecycle": { - "version": "3.1.5", + "version": "4.0.0", "bundled": true, "dev": true, "requires": { - "byline": "^5.0.0", - "graceful-fs": "^4.1.15", - "node-gyp": "^5.0.2", - "resolve-from": "^4.0.0", - "slide": "^1.1.6", - "uid-number": "0.0.6", - "umask": "^1.1.0", - "which": "^1.3.1" + "semver": "^7.1.1" } }, - "npm-logical-tree": { - "version": "1.2.1", - "bundled": true, - "dev": true - }, "npm-normalize-package-bin": { "version": "1.0.1", "bundled": true, "dev": true }, "npm-package-arg": { - "version": "6.1.1", + "version": "8.1.5", "bundled": true, "dev": true, "requires": { - "hosted-git-info": "^2.7.1", - "osenv": "^0.1.5", - "semver": "^5.6.0", + "hosted-git-info": "^4.0.1", + "semver": "^7.3.4", "validate-npm-package-name": "^3.0.0" } }, "npm-packlist": { - "version": "1.4.8", + "version": "2.2.2", "bundled": true, "dev": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", + "glob": "^7.1.6", + "ignore-walk": "^3.0.3", + "npm-bundled": "^1.1.1", "npm-normalize-package-bin": "^1.0.1" } }, "npm-pick-manifest": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1", - "npm-package-arg": "^6.0.0", - "semver": "^5.4.1" - } - }, - "npm-profile": { - "version": "4.0.4", + "version": "6.1.1", "bundled": true, "dev": true, "requires": { - "aproba": "^1.1.2 || 2", - "figgy-pudding": "^3.4.1", - "npm-registry-fetch": "^4.0.0" + "npm-install-checks": "^4.0.0", + "npm-normalize-package-bin": "^1.0.1", + "npm-package-arg": "^8.1.2", + "semver": "^7.3.4" } }, - "npm-registry-fetch": { - "version": "4.0.7", + "npm-profile": { + "version": "5.0.4", "bundled": true, "dev": true, "requires": { - "JSONStream": "^1.3.4", - "bluebird": "^3.5.1", - "figgy-pudding": "^3.4.1", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "npm-package-arg": "^6.1.0", - "safe-buffer": "^5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "bundled": true, - "dev": true - } + "npm-registry-fetch": "^11.0.0" } }, - "npm-run-path": { - "version": "2.0.2", + "npm-registry-fetch": { + "version": "11.0.0", "bundled": true, "dev": true, "requires": { - "path-key": "^2.0.0" + "make-fetch-happen": "^9.0.1", + "minipass": "^3.1.3", + "minipass-fetch": "^1.3.0", + "minipass-json-stream": "^1.0.1", + "minizlib": "^2.0.0", + "npm-package-arg": "^8.0.0" } }, "npm-user-validate": { @@ -9557,14 +8010,25 @@ "dev": true }, "npmlog": { - "version": "4.1.2", + "version": "5.0.1", "bundled": true, "dev": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + }, + "dependencies": { + "are-we-there-yet": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + } + } } }, "number-is-nan": { @@ -9582,20 +8046,6 @@ "bundled": true, "dev": true }, - "object-keys": { - "version": "1.0.12", - "bundled": true, - "dev": true - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, "once": { "version": "1.4.0", "bundled": true, @@ -9609,165 +8059,72 @@ "bundled": true, "dev": true }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "package-json": { - "version": "4.0.1", + "p-map": { + "version": "4.0.0", "bundled": true, "dev": true, "requires": { - "got": "^6.7.1", - "registry-auth-token": "^3.0.1", - "registry-url": "^3.0.3", - "semver": "^5.1.0" + "aggregate-error": "^3.0.0" } }, "pacote": { - "version": "9.5.12", + "version": "11.3.5", "bundled": true, "dev": true, "requires": { - "bluebird": "^3.5.3", - "cacache": "^12.0.2", - "chownr": "^1.1.2", - "figgy-pudding": "^3.5.1", - "get-stream": "^4.1.0", - "glob": "^7.1.3", + "@npmcli/git": "^2.1.0", + "@npmcli/installed-package-contents": "^1.0.6", + "@npmcli/promise-spawn": "^1.2.0", + "@npmcli/run-script": "^1.8.2", + "cacache": "^15.0.5", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", "infer-owner": "^1.0.4", - "lru-cache": "^5.1.1", - "make-fetch-happen": "^5.0.0", - "minimatch": "^3.0.4", - "minipass": "^2.3.5", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "normalize-package-data": "^2.4.0", - "npm-normalize-package-bin": "^1.0.0", - "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.1.12", - "npm-pick-manifest": "^3.0.0", - "npm-registry-fetch": "^4.0.0", - "osenv": "^0.1.5", - "promise-inflight": "^1.0.1", - "promise-retry": "^1.1.1", - "protoduck": "^5.0.1", - "rimraf": "^2.6.2", - "safe-buffer": "^5.1.2", - "semver": "^5.6.0", - "ssri": "^6.0.1", - "tar": "^4.4.10", - "unique-filename": "^1.1.1", - "which": "^1.3.1" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "parallel-transform": { - "version": "1.1.0", + "minipass": "^3.1.3", + "mkdirp": "^1.0.3", + "npm-package-arg": "^8.0.1", + "npm-packlist": "^2.1.4", + "npm-pick-manifest": "^6.0.0", + "npm-registry-fetch": "^11.0.0", + "promise-retry": "^2.0.1", + "read-package-json-fast": "^2.0.1", + "rimraf": "^3.0.2", + "ssri": "^8.0.1", + "tar": "^6.1.0" + } + }, + "parse-conflict-json": { + "version": "1.1.1", "bundled": true, "dev": true, "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "json-parse-even-better-errors": "^2.3.0", + "just-diff": "^3.0.1", + "just-diff-apply": "^3.0.0" } }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, "path-is-absolute": { "version": "1.0.1", "bundled": true, "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "bundled": true, - "dev": true - }, "performance-now": { "version": "2.1.0", "bundled": true, "dev": true }, - "pify": { - "version": "3.0.0", + "proc-log": { + "version": "1.0.0", "bundled": true, "dev": true }, - "prepend-http": { - "version": "1.0.4", + "promise-all-reject-late": { + "version": "1.0.1", "bundled": true, "dev": true }, - "process-nextick-args": { - "version": "2.0.0", + "promise-call-limit": { + "version": "1.0.1", "bundled": true, "dev": true }, @@ -9777,19 +8134,12 @@ "dev": true }, "promise-retry": { - "version": "1.1.1", + "version": "2.0.1", "bundled": true, "dev": true, "requires": { - "err-code": "^1.0.0", - "retry": "^0.10.0" - }, - "dependencies": { - "retry": { - "version": "0.10.1", - "bundled": true, - "dev": true - } + "err-code": "^2.0.2", + "retry": "^0.12.0" } }, "promzard": { @@ -9800,66 +8150,13 @@ "read": "1" } }, - "proto-list": { - "version": "1.2.4", - "bundled": true, - "dev": true - }, - "protoduck": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "requires": { - "genfun": "^5.0.0" - } - }, - "prr": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, "psl": { - "version": "1.1.29", + "version": "1.8.0", "bundled": true, "dev": true }, - "pump": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "bundled": true, - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, "punycode": { - "version": "1.4.1", + "version": "2.1.1", "bundled": true, "dev": true }, @@ -9873,32 +8170,6 @@ "bundled": true, "dev": true }, - "query-string": { - "version": "6.8.2", - "bundled": true, - "dev": true, - "requires": { - "decode-uri-component": "^0.2.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - } - }, - "qw": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, "read": { "version": "1.0.7", "bundled": true, @@ -9908,47 +8179,28 @@ } }, "read-cmd-shim": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2" - } - }, - "read-installed": { - "version": "4.0.3", + "version": "2.0.0", "bundled": true, - "dev": true, - "requires": { - "debuglog": "^1.0.1", - "graceful-fs": "^4.1.2", - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "slide": "~1.1.3", - "util-extend": "^1.0.1" - } + "dev": true }, "read-package-json": { - "version": "2.1.1", + "version": "4.1.1", "bundled": true, "dev": true, "requires": { "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "json-parse-better-errors": "^1.0.1", - "normalize-package-data": "^2.0.0", + "json-parse-even-better-errors": "^2.3.0", + "normalize-package-data": "^3.0.0", "npm-normalize-package-bin": "^1.0.0" } }, - "read-package-tree": { - "version": "5.3.1", + "read-package-json-fast": { + "version": "2.0.3", "bundled": true, "dev": true, "requires": { - "read-package-json": "^2.0.0", - "readdir-scoped-modules": "^1.0.0", - "util-promisify": "^2.1.0" + "json-parse-even-better-errors": "^2.3.0", + "npm-normalize-package-bin": "^1.0.1" } }, "readable-stream": { @@ -9972,25 +8224,8 @@ "once": "^1.3.0" } }, - "registry-auth-token": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "rc": "^1.0.1" - } - }, "request": { - "version": "2.88.0", + "version": "2.88.2", "bundled": true, "dev": true, "requires": { @@ -10001,7 +8236,7 @@ "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", - "har-validator": "~5.1.0", + "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -10011,194 +8246,99 @@ "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", + "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" - } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "retry": { - "version": "0.12.0", - "bundled": true, - "dev": true - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-queue": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "requires": { - "aproba": "^1.1.1" }, "dependencies": { - "aproba": { - "version": "1.2.0", + "form-data": { + "version": "2.3.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "2.5.0", + "bundled": true, + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } } } }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.7.1", + "retry": { + "version": "0.12.0", "bundled": true, "dev": true }, - "semver-diff": { - "version": "2.1.0", + "rimraf": { + "version": "3.0.2", "bundled": true, "dev": true, "requires": { - "semver": "^5.0.3" + "glob": "^7.1.3" } }, - "set-blocking": { - "version": "2.0.0", + "safe-buffer": { + "version": "5.2.1", "bundled": true, "dev": true }, - "sha": { - "version": "3.0.0", + "safer-buffer": { + "version": "2.1.2", "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2" - } + "dev": true }, - "shebang-command": { - "version": "1.2.0", + "semver": { + "version": "7.3.5", "bundled": true, "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "lru-cache": "^6.0.0" } }, - "shebang-regex": { - "version": "1.0.0", + "set-blocking": { + "version": "2.0.0", "bundled": true, "dev": true }, "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "slide": { - "version": "1.1.6", + "version": "3.0.3", "bundled": true, "dev": true }, "smart-buffer": { - "version": "4.1.0", + "version": "4.2.0", "bundled": true, "dev": true }, "socks": { - "version": "2.3.3", + "version": "2.6.1", "bundled": true, "dev": true, "requires": { - "ip": "1.1.5", + "ip": "^1.1.5", "smart-buffer": "^4.1.0" } }, "socks-proxy-agent": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "agent-base": "~4.2.1", - "socks": "~2.3.2" - }, - "dependencies": { - "agent-base": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - } - } - }, - "sorted-object": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "sorted-union-stream": { - "version": "2.1.3", + "version": "6.1.0", "bundled": true, "dev": true, "requires": { - "from2": "^1.3.0", - "stream-iterate": "^1.1.0" - }, - "dependencies": { - "from2": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "~1.1.10" - } - }, - "isarray": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "bundled": true, - "dev": true - } + "agent-base": "^6.0.2", + "debug": "^4.3.1", + "socks": "^2.6.1" } }, "spdx-correct": { - "version": "3.0.0", + "version": "3.1.1", "bundled": true, "dev": true, "requires": { @@ -10207,12 +8347,12 @@ } }, "spdx-exceptions": { - "version": "2.1.0", + "version": "2.3.0", "bundled": true, "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", + "version": "3.0.1", "bundled": true, "dev": true, "requires": { @@ -10221,17 +8361,12 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "bundled": true, - "dev": true - }, - "split-on-first": { - "version": "1.1.0", + "version": "3.0.10", "bundled": true, "dev": true }, "sshpk": { - "version": "1.14.2", + "version": "1.16.1", "bundled": true, "dev": true, "requires": { @@ -10247,65 +8382,13 @@ } }, "ssri": { - "version": "6.0.1", - "bundled": true, - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "stream-each": { - "version": "1.2.2", - "bundled": true, - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-iterate": { - "version": "1.2.0", + "version": "8.0.1", "bundled": true, "dev": true, "requires": { - "readable-stream": "^2.1.5", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } + "minipass": "^3.1.1" } }, - "stream-shift": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "strict-uri-encode": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, "string-width": { "version": "2.1.1", "bundled": true, @@ -10320,11 +8403,6 @@ "bundled": true, "dev": true }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, "strip-ansi": { "version": "4.0.0", "bundled": true, @@ -10341,13 +8419,6 @@ "dev": true, "requires": { "safe-buffer": "~5.2.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.0", - "bundled": true, - "dev": true - } } }, "stringify-package": { @@ -10363,55 +8434,25 @@ "ansi-regex": "^2.0.0" } }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, "supports-color": { - "version": "5.4.0", + "version": "7.2.0", "bundled": true, "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, "tar": { - "version": "4.4.13", - "bundled": true, - "dev": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - } - } - }, - "term-size": { - "version": "1.2.0", + "version": "6.1.11", "bundled": true, "dev": true, "requires": { - "execa": "^0.7.0" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" } }, "text-table": { @@ -10419,62 +8460,15 @@ "bundled": true, "dev": true }, - "through": { - "version": "2.3.8", - "bundled": true, - "dev": true - }, - "through2": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "timed-out": { - "version": "4.0.1", - "bundled": true, - "dev": true - }, "tiny-relative-date": { "version": "1.3.0", "bundled": true, "dev": true }, - "tough-cookie": { - "version": "2.4.3", + "treeverse": { + "version": "1.0.4", "bundled": true, - "dev": true, - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - } + "dev": true }, "tunnel-agent": { "version": "0.6.0", @@ -10487,23 +8481,15 @@ "tweetnacl": { "version": "0.14.5", "bundled": true, - "dev": true, - "optional": true - }, - "typedarray": { - "version": "0.0.6", - "bundled": true, "dev": true }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true - }, - "umask": { - "version": "1.1.0", + "typedarray-to-buffer": { + "version": "3.1.5", "bundled": true, - "dev": true + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } }, "unique-filename": { "version": "1.1.1", @@ -10514,69 +8500,19 @@ } }, "unique-slug": { - "version": "2.0.0", + "version": "2.0.2", "bundled": true, "dev": true, "requires": { "imurmurhash": "^0.1.4" } }, - "unique-string": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "crypto-random-string": "^1.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "unzip-response": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "update-notifier": { - "version": "2.5.0", - "bundled": true, - "dev": true, - "requires": { - "boxen": "^1.2.1", - "chalk": "^2.0.1", - "configstore": "^3.0.0", - "import-lazy": "^2.1.0", - "is-ci": "^1.0.10", - "is-installed-globally": "^0.1.0", - "is-npm": "^1.0.0", - "latest-version": "^3.0.0", - "semver-diff": "^2.0.0", - "xdg-basedir": "^3.0.0" - } - }, "uri-js": { - "version": "4.4.0", + "version": "4.4.1", "bundled": true, "dev": true, "requires": { "punycode": "^2.1.0" - }, - "dependencies": { - "punycode": { - "version": "2.1.1", - "bundled": true, - "dev": true - } - } - }, - "url-parse-lax": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "prepend-http": "^1.0.1" } }, "util-deprecate": { @@ -10584,21 +8520,8 @@ "bundled": true, "dev": true }, - "util-extend": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "util-promisify": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3" - } - }, "uuid": { - "version": "3.3.3", + "version": "3.4.0", "bundled": true, "dev": true }, @@ -10612,118 +8535,50 @@ } }, "validate-npm-package-name": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtins": "^1.0.3" - } - }, - "verror": { - "version": "1.10.0", - "bundled": true, - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "which": { - "version": "1.3.1", + "version": "3.0.0", "bundled": true, "dev": true, "requires": { - "isexe": "^2.0.0" + "builtins": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "wide-align": { - "version": "1.1.2", + "verror": { + "version": "1.10.0", "bundled": true, "dev": true, "requires": { - "string-width": "^1.0.2" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" } }, - "widest-line": { - "version": "2.0.1", + "walk-up-path": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "wcwidth": { + "version": "1.0.1", "bundled": true, "dev": true, "requires": { - "string-width": "^2.1.1" + "defaults": "^1.0.3" } }, - "worker-farm": { - "version": "1.7.0", + "which": { + "version": "2.0.2", "bundled": true, "dev": true, "requires": { - "errno": "~0.1.7" + "isexe": "^2.0.0" } }, - "wrap-ansi": { - "version": "5.1.0", + "wide-align": { + "version": "1.1.3", "bundled": true, "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "string-width": "^1.0.2 || 2" } }, "wrappy": { @@ -10732,136 +8587,20 @@ "dev": true }, "write-file-atomic": { - "version": "2.4.3", + "version": "3.0.3", "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, - "xdg-basedir": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "xtend": { - "version": "4.0.1", - "bundled": true, - "dev": true - }, - "y18n": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, "yallist": { - "version": "3.0.3", + "version": "4.0.0", "bundled": true, "dev": true - }, - "yargs": { - "version": "14.2.3", - "bundled": true, - "dev": true, - "requires": { - "cliui": "^5.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^15.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "find-up": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "locate-path": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "15.0.1", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "bundled": true, - "dev": true - } - } } } }, @@ -10872,14 +8611,6 @@ "dev": true, "requires": { "path-key": "^3.0.0" - }, - "dependencies": { - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - } } }, "null-check": { @@ -10978,12 +8709,6 @@ "has": "^1.0.3" } }, - "octokit-pagination-methods": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz", - "integrity": "sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ==", - "dev": true - }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -11000,6 +8725,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "opencollective-postinstall": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz", @@ -11026,16 +8760,6 @@ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, - "os-name": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", - "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", - "dev": true, - "requires": { - "macos-release": "^2.2.0", - "windows-release": "^3.1.0" - } - }, "os-shim": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/os-shim/-/os-shim-0.1.3.tgz", @@ -11051,6 +8775,12 @@ "shell-quote": "^1.4.2" } }, + "p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "dev": true + }, "p-filter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", @@ -11060,12 +8790,6 @@ "p-map": "^2.0.0" } }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true - }, "p-is-promise": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz", @@ -11103,13 +8827,13 @@ "dev": true }, "p-retry": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.2.0.tgz", - "integrity": "sha512-jPH38/MRh263KKcq0wBNOGFJbm+U6784RilTmHjB/HM9kH9V8WlCpVUcdOmip9cjXOh6MxZ5yk1z2SjDUJfWmA==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", + "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", "dev": true, "requires": { "@types/retry": "^0.12.0", - "retry": "^0.12.0" + "retry": "^0.13.1" } }, "p-try": { @@ -11209,9 +8933,9 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { @@ -11425,16 +9149,6 @@ "safe-buffer": "^5.1.2" } }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -11521,10 +9235,16 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "randombytes": { @@ -11651,6 +9371,16 @@ } } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, "redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", @@ -11660,12 +9390,6 @@ "esprima": "~4.0.0" } }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -11683,9 +9407,9 @@ "dev": true }, "registry-auth-token": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.1.1.tgz", - "integrity": "sha512-9bKS7nTl9+/A1s7tnPeGrUpRcVY+LUh7bfFgzpndALdPfXQBfQV77rQVtqgUV3ti4vc/Ik81Ex8UJDWDQ12zQA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", + "integrity": "sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw==", "dev": true, "requires": { "rc": "^1.2.8" @@ -11714,12 +9438,6 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -11762,9 +9480,9 @@ "dev": true }, "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "dev": true }, "reusify": { @@ -11797,10 +9515,13 @@ } }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } }, "safe-buffer": { "version": "5.2.1", @@ -11829,106 +9550,54 @@ "dev": true }, "semantic-release": { - "version": "15.14.0", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-15.14.0.tgz", - "integrity": "sha512-Cn43W35AOLY0RMcDbtwhJODJmWg6YCs1+R5jRQsTmmkEGzkV4B2F/QXkjVZpl4UbH91r93GGH0xhoq9kh7I5PA==", + "version": "17.4.7", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.4.7.tgz", + "integrity": "sha512-3Ghu8mKCJgCG3QzE5xphkYWM19lGE3XjFdOXQIKBM2PBpBvgFQ/lXv31oX0+fuN/UjNFO/dqhNs8ATLBhg6zBg==", "dev": true, "requires": { - "@semantic-release/commit-analyzer": "^6.1.0", - "@semantic-release/error": "^2.2.0", - "@semantic-release/github": "^5.1.0", - "@semantic-release/npm": "^5.0.5", - "@semantic-release/release-notes-generator": "^7.1.2", - "aggregate-error": "^3.0.0", - "cosmiconfig": "^6.0.0", - "debug": "^4.0.0", - "env-ci": "^4.0.0", - "execa": "^3.2.0", - "figures": "^3.0.0", - "find-versions": "^3.0.0", - "get-stream": "^5.0.0", - "git-log-parser": "^1.2.0", - "hook-std": "^2.0.0", - "hosted-git-info": "^3.0.0", - "lodash": "^4.17.15", - "marked": "^0.7.0", - "marked-terminal": "^3.2.0", - "p-locate": "^4.0.0", - "p-reduce": "^2.0.0", - "read-pkg-up": "^7.0.0", - "resolve-from": "^5.0.0", - "semver": "^6.0.0", - "signale": "^1.2.1", - "yargs": "^15.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "@semantic-release/commit-analyzer": "^8.0.0", + "@semantic-release/error": "^2.2.0", + "@semantic-release/github": "^7.0.0", + "@semantic-release/npm": "^7.0.0", + "@semantic-release/release-notes-generator": "^9.0.0", + "aggregate-error": "^3.0.0", + "cosmiconfig": "^7.0.0", + "debug": "^4.0.0", + "env-ci": "^5.0.0", + "execa": "^5.0.0", + "figures": "^3.0.0", + "find-versions": "^4.0.0", + "get-stream": "^6.0.0", + "git-log-parser": "^1.2.0", + "hook-std": "^2.0.0", + "hosted-git-info": "^4.0.0", + "lodash": "^4.17.21", + "marked": "^2.0.0", + "marked-terminal": "^4.1.1", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "p-reduce": "^2.0.0", + "read-pkg-up": "^7.0.0", + "resolve-from": "^5.0.0", + "semver": "^7.3.2", + "semver-diff": "^3.1.1", + "signale": "^1.2.1", + "yargs": "^16.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" - } - }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "emoji-regex": { @@ -11937,15 +9606,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -11956,13 +9616,22 @@ "path-exists": "^4.0.0" } }, + "find-versions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "dev": true, + "requires": { + "semver-regex": "^3.1.2" + } + }, "hosted-git-info": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-3.0.4.tgz", - "integrity": "sha512-4oT62d2jwSDBbLLFLZE+1vPuQ1h8p9wjrJ8Mqx5TjsyWmBMV5B13eJqn8pvluqubLf3cJPTfiYCIwNwDNmzScQ==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", + "integrity": "sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg==", "dev": true, "requires": { - "lru-cache": "^5.1.1" + "lru-cache": "^6.0.0" } }, "is-fullwidth-code-point": { @@ -11980,6 +9649,16 @@ "p-locate": "^4.1.0" } }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -12011,14 +9690,14 @@ "dev": true }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -12028,10 +9707,10 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "read-pkg": { @@ -12072,29 +9751,32 @@ "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "type-fest": { @@ -12103,50 +9785,19 @@ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } } } @@ -12163,6 +9814,29 @@ "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", "dev": true }, + "semver-diff": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz", + "integrity": "sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "semver-regex": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.3.tgz", + "integrity": "sha512-Aqi54Mk9uYTjVexLnR67rTyBusmwd04cLkHy9hNvk3+G3nT2Oyg7E0l4XVbOaNwIvQ3hHeYxGcyEy+mKreyBFQ==", + "dev": true + }, "serialize-error": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-4.1.0.tgz", @@ -12180,12 +9854,6 @@ } } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", @@ -12235,18 +9903,18 @@ } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shell-quote": { @@ -12256,9 +9924,9 @@ "dev": true }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", "dev": true }, "signale": { @@ -12270,6 +9938,17 @@ "chalk": "^2.3.2", "figures": "^2.0.0", "pkg-conf": "^2.1.0" + }, + "dependencies": { + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + } } }, "simple-concat": { @@ -12573,12 +10252,25 @@ } }, "split2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", - "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", "dev": true, "requires": { - "through2": "^2.0.2" + "readable-stream": "^3.0.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } } }, "sprintf-js": { @@ -12800,18 +10492,21 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", @@ -12888,20 +10583,29 @@ } }, "supports-hyperlinks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", - "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "requires": { - "has-flag": "^2.0.0", - "supports-color": "^5.0.0" + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" }, "dependencies": { "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -12955,9 +10659,9 @@ } }, "temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-2.0.0.tgz", + "integrity": "sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==", "dev": true }, "temp-fs": { @@ -12981,20 +10685,22 @@ } }, "tempy": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.3.0.tgz", - "integrity": "sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tempy/-/tempy-1.0.1.tgz", + "integrity": "sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==", "dev": true, "requires": { - "temp-dir": "^1.0.0", - "type-fest": "^0.3.1", - "unique-string": "^1.0.0" + "del": "^6.0.0", + "is-stream": "^2.0.0", + "temp-dir": "^2.0.0", + "type-fest": "^0.16.0", + "unique-string": "^2.0.0" }, "dependencies": { "type-fest": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", - "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.16.0.tgz", + "integrity": "sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==", "dev": true } } @@ -13143,16 +10849,22 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", + "dev": true + }, "traverse": { "version": "0.6.6", "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", "dev": true }, - "trim-off-newlines": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", - "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", "dev": true }, "tsconfig-paths": { @@ -13195,9 +10907,9 @@ "dev": true }, "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", "dev": true }, "type-is": { @@ -13221,24 +10933,11 @@ "integrity": "sha512-uXEtSresNUlXQ1QL4/3dQORcGv7+J2ookOG2ybA/ga9+HYEXueT2o+8dUJQkpedsyTyCJ6jCCirRcKtdtx1kbg==" }, "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", + "integrity": "sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==", "dev": true, - "optional": true, - "requires": { - "commander": "~2.20.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } + "optional": true }, "umd": { "version": "3.0.3", @@ -13272,22 +10971,19 @@ } }, "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", + "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", "dev": true, "requires": { - "crypto-random-string": "^1.0.0" + "crypto-random-string": "^2.0.0" } }, "universal-user-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-4.0.1.tgz", - "integrity": "sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==", - "dev": true, - "requires": { - "os-name": "^3.1.0" - } + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", + "dev": true }, "universalify": { "version": "0.1.2", @@ -13625,6 +11321,22 @@ } } }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", + "dev": true + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dev": true, + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -13634,74 +11346,24 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "which-pm-runs": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", "dev": true }, - "windows-release": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.3.0.tgz", - "integrity": "sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==", - "dev": true, - "requires": { - "execa": "^1.0.0" - }, - "dependencies": { - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - } - } - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -13814,9 +11476,9 @@ "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" }, "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yaml": { @@ -13883,21 +11545,10 @@ } }, "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true }, "yauzl": { "version": "2.10.0", @@ -13908,6 +11559,12 @@ "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index dae4f3f83..c9b1e69a7 100644 --- a/package.json +++ b/package.json @@ -444,10 +444,10 @@ "yargs": "^16.1.1" }, "devDependencies": { - "@commitlint/cli": "^8.3.4", - "@commitlint/config-conventional": "^8.3.4", - "@semantic-release/changelog": "^3.0.6", - "@semantic-release/git": "^7.0.18", + "@commitlint/cli": "^12.1.4", + "@commitlint/config-conventional": "^12.1.4", + "@semantic-release/changelog": "^5.0.1", + "@semantic-release/git": "^9.0.1", "browserify": "^16.2.3", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", @@ -478,7 +478,7 @@ "mocks": "^0.0.15", "proxyquire": "^2.1.3", "puppeteer": "^1.20.0", - "semantic-release": "^15.14.0", + "semantic-release": "^17.4.7", "sinon": "7.3.2", "sinon-chai": "^3.5.0", "supertest": "^4.0.2", diff --git a/release.config.js b/release.config.js index 7bf58b9dd..2a488e6fc 100644 --- a/release.config.js +++ b/release.config.js @@ -1,7 +1,7 @@ module.exports = { // Add logging for releases until we are fully confident of the release solution. debug: true, - branch: 'master', + branches: 'master', verifyConditions: [ '@semantic-release/changelog', '@semantic-release/npm', From f1aeaec09e49856747b8f650d06b4dcc61eb637e Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Thu, 28 Oct 2021 21:49:52 +0200 Subject: [PATCH 346/374] fix(middleware): replace %X_UA_COMPATIBLE% marker anywhere in the file Previously %X_UA_COMPATIBLE% marker was only replaced if it was located at the start of the line. The limitation looks pretty arbitrary and caused the marker not to be replaced in the custom debug.html file used by Angular CLI as the marker was not located at the start of the line (probably because the file was re-formatted). This commit changes the behavior to replace the marker anywhere within the file, not just at the start of the line and thus fixes the problem for Angular CLI and potentially other people using custom files. Fixes #3711 --- lib/middleware/karma.js | 6 +++--- static/client.html | 2 +- static/debug.html | 2 +- test/unit/middleware/karma.spec.js | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index c92ae21a1..5f701e7e7 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -45,7 +45,7 @@ function getQuery (urlStr) { function getXUACompatibleMetaElement (url) { const query = getQuery(url) if (query['x-ua-compatible']) { - return `\n` + return `` } return '' } @@ -107,7 +107,7 @@ function createKarmaMiddleware ( } else { // serve client.html return serveStaticFile('/client.html', requestedRangeHeader, response, (data) => data - .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) + .replace('%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) .replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url))) } } @@ -226,7 +226,7 @@ function createKarmaMiddleware ( .replace('%CLIENT_CONFIG%', 'window.__karma__.config = ' + JSON.stringify(client) + ';\n') .replace('%SCRIPT_URL_ARRAY%', () => 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n') .replace('%MAPPINGS%', () => 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n') - .replace('\n%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) + .replace('%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url)) }) }) } else if (requestUrl === '/context.json') { diff --git a/static/client.html b/static/client.html index 4e069e1ef..73fb856a4 100644 --- a/static/client.html +++ b/static/client.html @@ -5,7 +5,7 @@ --> -%X_UA_COMPATIBLE% + %X_UA_COMPATIBLE% Karma diff --git a/static/debug.html b/static/debug.html index 3fc6173f2..e8c667674 100644 --- a/static/debug.html +++ b/static/debug.html @@ -6,7 +6,7 @@ --> -%X_UA_COMPATIBLE% + %X_UA_COMPATIBLE% Karma DEBUG RUNNER diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js index b6a0d5d59..4f6b873c2 100644 --- a/test/unit/middleware/karma.spec.js +++ b/test/unit/middleware/karma.spec.js @@ -27,10 +27,10 @@ describe('middleware.karma', () => { const fsMock = mocks.fs.create({ karma: { static: { - 'client.html': mocks.fs.file(0, 'CLIENT HTML\n%X_UA_COMPATIBLE%%X_UA_COMPATIBLE_URL%'), + 'client.html': mocks.fs.file(0, 'CLIENT HTML%X_UA_COMPATIBLE%%X_UA_COMPATIBLE_URL%'), 'client_with_context.html': mocks.fs.file(0, 'CLIENT_WITH_CONTEXT\n%SCRIPT_URL_ARRAY%'), 'context.html': mocks.fs.file(0, 'CONTEXT\n%SCRIPTS%'), - 'debug.html': mocks.fs.file(0, 'DEBUG\n%SCRIPTS%\n%X_UA_COMPATIBLE%'), + 'debug.html': mocks.fs.file(0, 'DEBUG\n%SCRIPTS%%X_UA_COMPATIBLE%'), 'karma.js': mocks.fs.file(0, 'root: %KARMA_URL_ROOT%, proxy: %KARMA_PROXY_PATH%, v: %KARMA_VERSION%') } } @@ -170,7 +170,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'CLIENT HTML\n?x-ua-compatible=xxx%3Dyyy') + expect(response).to.beServedAs(200, 'CLIENT HTML?x-ua-compatible=xxx%3Dyyy') done() }) @@ -182,7 +182,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'DEBUG\n\n') + expect(response).to.beServedAs(200, 'DEBUG\n') done() }) From 920fa33ee99a60302e2dd5e0a0520f8f90536c12 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 1 Nov 2021 20:58:03 +0000 Subject: [PATCH 347/374] chore(release): 6.3.7 [skip ci] ## [6.3.7](https://github.com/karma-runner/karma/compare/v6.3.6...v6.3.7) (2021-11-01) ### Bug Fixes * **middleware:** replace %X_UA_COMPATIBLE% marker anywhere in the file ([f1aeaec](https://github.com/karma-runner/karma/commit/f1aeaec09e49856747b8f650d06b4dcc61eb637e)), closes [#3711](https://github.com/karma-runner/karma/issues/3711) --- CHANGELOG.md | 7 +++++++ package-lock.json | 2 +- package.json | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e5e7d130..114fabbe4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [6.3.7](https://github.com/karma-runner/karma/compare/v6.3.6...v6.3.7) (2021-11-01) + + +### Bug Fixes + +* **middleware:** replace %X_UA_COMPATIBLE% marker anywhere in the file ([f1aeaec](https://github.com/karma-runner/karma/commit/f1aeaec09e49856747b8f650d06b4dcc61eb637e)), closes [#3711](https://github.com/karma-runner/karma/issues/3711) + ## [6.3.6](https://github.com/karma-runner/karma/compare/v6.3.5...v6.3.6) (2021-10-25) diff --git a/package-lock.json b/package-lock.json index cb533ea13..f46acaa45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "karma", - "version": "6.3.6", + "version": "6.3.7", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index c9b1e69a7..af665bfa0 100644 --- a/package.json +++ b/package.json @@ -493,7 +493,7 @@ "engines": { "node": ">= 10" }, - "version": "6.3.6", + "version": "6.3.7", "license": "MIT", "husky": { "hooks": { From a2261bb662c4ffb303bc56bf021247be683b1e0d Mon Sep 17 00:00:00 2001 From: Yaroslav Admin Date: Sat, 30 Oct 2021 13:21:54 +0200 Subject: [PATCH 348/374] build: use matching commitlint config The commit conventions enforced by commitlint (conventional) were different than the conventions used by the semantic-release (angular). In practice, is was never a problem as they are pretty similar, but it's better to be consistent anyways. Update the commit conventions documentation according to the change and also extend it with the information about which kind of release is triggered by which commit type. Add explicit configuration for release rules for semantic-release to the configuration file - rules are the same as before, but now it is easier to see what they actually are. --- commitlint.config.js | 2 +- docs/dev/06-git-commit-msg.md | 43 ++++++++++++++++------------------- package-lock.json | 14 ++++++++---- package.json | 2 +- release.config.js | 22 +++++++++++++++++- 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/commitlint.config.js b/commitlint.config.js index 4fedde6da..f78763c23 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -1 +1 @@ -module.exports = { extends: ['@commitlint/config-conventional'] } +module.exports = { extends: ['@commitlint/config-angular'] } diff --git a/docs/dev/06-git-commit-msg.md b/docs/dev/06-git-commit-msg.md index 0365657bb..4793c809a 100644 --- a/docs/dev/06-git-commit-msg.md +++ b/docs/dev/06-git-commit-msg.md @@ -2,6 +2,8 @@ showInMenu: false --- +In the repository we use and enforce the commit message conventions. The conventions are verified using [commitlint] with [Angular config](https://www.npmjs.com/package/@commitlint/config-angular). + ## The reasons for these conventions: - automatic generating of the changelog - simple navigation through git history (e.g. ignoring style changes) @@ -9,9 +11,9 @@ showInMenu: false ## Format of the commit message: ```bash (): - + - +