From 008e401ae9759958f8576e7568bf857493fb9dfa Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Thu, 14 Nov 2019 16:02:59 +0200 Subject: [PATCH 01/40] polling instrumentation callbacks --- .prettierrc | 4 +++ package.json | 2 +- src/consumer.ts | 68 +++++++++++++++++++++++++++---------------------- 3 files changed, 42 insertions(+), 32 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..3f584f60 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ +{ + "printWidth": 120, + "singleQuote": true +} diff --git a/package.json b/package.json index 80a19372..349ef1cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.4.0", + "version": "5.5.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/consumer.ts b/src/consumer.ts index 681e1d74..42f3a9d1 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -34,9 +34,9 @@ function createTimeout(duration: number): TimeoutResponse[] { } function assertOptions(options: ConsumerOptions): void { - requiredOptions.forEach((option) => { + requiredOptions.forEach(option => { const possibilities = option.split('|'); - if (!possibilities.find((p) => options[p])) { + if (!possibilities.find(p => options[p])) { throw new Error(`Missing SQS consumer option [ ${possibilities.join(' or ')} ].`); } }); @@ -48,7 +48,7 @@ function assertOptions(options: ConsumerOptions): void { function isConnectionError(err: Error): Boolean { if (err instanceof SQSError) { - return (err.statusCode === 403 || err.code === 'CredentialsError' || err.code === 'UnknownEndpoint'); + return err.statusCode === 403 || err.code === 'CredentialsError' || err.code === 'UnknownEndpoint'; } return false; } @@ -85,12 +85,16 @@ export interface ConsumerOptions { handleMessageTimeout?: number; handleMessage?(message: SQSMessage): Promise; handleMessageBatch?(messages: SQSMessage[]): Promise; + pollingStartedInstrumentCallback?(eventData: object): void; + pollingFinishedInstrumentCallback?(eventData: object): void; } export class Consumer extends EventEmitter { private queueUrl: string; private handleMessage: (message: SQSMessage) => Promise; private handleMessageBatch: (message: SQSMessage[]) => Promise; + private pollingStartedInstrumentCallback?: (eventData: object) => void; + private pollingFinishedInstrumentCallback?: (eventData: object) => void; private handleMessageTimeout: number; private attributeNames: string[]; private messageAttributeNames: string[]; @@ -109,6 +113,8 @@ export class Consumer extends EventEmitter { this.queueUrl = options.queueUrl; this.handleMessage = options.handleMessage; this.handleMessageBatch = options.handleMessageBatch; + this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; + this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; this.handleMessageTimeout = options.handleMessageTimeout; this.attributeNames = options.attributeNames || []; this.messageAttributeNames = options.messageAttributeNames || []; @@ -120,9 +126,11 @@ export class Consumer extends EventEmitter { this.authenticationErrorTimeout = options.authenticationErrorTimeout || 10000; this.pollingWaitTimeMs = options.pollingWaitTimeMs || 0; - this.sqs = options.sqs || new SQS({ - region: options.region || process.env.AWS_REGION || 'eu-west-1' - }); + this.sqs = + options.sqs || + new SQS({ + region: options.region || process.env.AWS_REGION || 'eu-west-1' + }); autoBind(this); } @@ -151,6 +159,10 @@ export class Consumer extends EventEmitter { private async handleSqsResponse(response: ReceieveMessageResponse): Promise { debug('Received SQS response'); debug(response); + this.pollingFinishedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); if (response) { if (hasMessages(response)) { @@ -189,9 +201,7 @@ export class Consumer extends EventEmitter { private async receiveMessage(params: ReceiveMessageRequest): Promise { try { - return await this.sqs - .receiveMessage(params) - .promise(); + return await this.sqs.receiveMessage(params).promise(); } catch (err) { throw toSQSError(err, `SQS receive message failed: ${err.message}`); } @@ -206,9 +216,7 @@ export class Consumer extends EventEmitter { }; try { - await this.sqs - .deleteMessage(deleteParams) - .promise(); + await this.sqs.deleteMessage(deleteParams).promise(); } catch (err) { throw toSQSError(err, `SQS delete message failed: ${err.message}`); } @@ -220,10 +228,7 @@ export class Consumer extends EventEmitter { try { if (this.handleMessageTimeout) { [timeout, pending] = createTimeout(this.handleMessageTimeout); - await Promise.race([ - this.handleMessage(message), - pending - ]); + await Promise.race([this.handleMessage(message), pending]); } else { await this.handleMessage(message); } @@ -266,6 +271,10 @@ export class Consumer extends EventEmitter { } debug('Polling for messages'); + this.pollingStartedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); const receiveParams = { QueueUrl: this.queueUrl, AttributeNames: this.attributeNames, @@ -278,29 +287,31 @@ export class Consumer extends EventEmitter { let currentPollingTimeout = this.pollingWaitTimeMs; this.receiveMessage(receiveParams) .then(this.handleSqsResponse) - .catch((err) => { + .catch(err => { this.emit('error', err); if (isConnectionError(err)) { debug('There was an authentication error. Pausing before retrying.'); currentPollingTimeout = this.authenticationErrorTimeout; } return; - }).then(() => { - setTimeout(this.poll, currentPollingTimeout); - }).catch((err) => { + }) + .then(() => { + setTimeout(this.poll, currentPollingTimeout); + }) + .catch(err => { this.emit('error', err); }); } private async processMessageBatch(messages: SQSMessage[]): Promise { - messages.forEach((message) => { + messages.forEach(message => { this.emit('message_received', message); }); try { await this.executeBatchHandler(messages); await this.deleteMessageBatch(messages); - messages.forEach((message) => { + messages.forEach(message => { this.emit('message_processed', message); }); } catch (err) { @@ -317,7 +328,7 @@ export class Consumer extends EventEmitter { } private async deleteMessageBatch(messages: SQSMessage[]): Promise { - debug('Deleting messages %s', messages.map((msg) => msg.MessageId).join(' ,')); + debug('Deleting messages %s', messages.map(msg => msg.MessageId).join(' ,')); const deleteParams = { QueueUrl: this.queueUrl, @@ -328,9 +339,7 @@ export class Consumer extends EventEmitter { }; try { - await this.sqs - .deleteMessageBatch(deleteParams) - .promise(); + await this.sqs.deleteMessageBatch(deleteParams).promise(); } catch (err) { throw toSQSError(err, `SQS delete message failed: ${err.message}`); } @@ -348,15 +357,12 @@ export class Consumer extends EventEmitter { private async terminateVisabilityTimeoutBatch(messages: SQSMessage[]): Promise> { const params = { QueueUrl: this.queueUrl, - Entries: messages.map((message) => ({ + Entries: messages.map(message => ({ Id: message.MessageId, ReceiptHandle: message.ReceiptHandle, VisibilityTimeout: 0 })) }; - return this.sqs - .changeMessageVisibilityBatch(params) - .promise(); + return this.sqs.changeMessageVisibilityBatch(params).promise(); } - } From 081e6c1cbc739940b2661cd3ee050f2e1a297460 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Thu, 14 Nov 2019 17:06:21 +0200 Subject: [PATCH 02/40] remove dist from gitignore --- .gitignore | 2 +- dist/bind.d.ts | 1 + dist/bind.js | 15 +++ dist/consumer.d.ts | 58 +++++++++ dist/consumer.js | 300 +++++++++++++++++++++++++++++++++++++++++++++ dist/errors.d.ts | 13 ++ dist/errors.js | 17 +++ dist/index.d.ts | 1 + dist/index.js | 4 + 9 files changed, 410 insertions(+), 1 deletion(-) create mode 100644 dist/bind.d.ts create mode 100644 dist/bind.js create mode 100644 dist/consumer.d.ts create mode 100644 dist/consumer.js create mode 100644 dist/errors.d.ts create mode 100644 dist/errors.js create mode 100644 dist/index.d.ts create mode 100644 dist/index.js diff --git a/.gitignore b/.gitignore index be2e166c..8f61d2f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ node_modules test.js coverage -dist +# dist .nyc_output diff --git a/dist/bind.d.ts b/dist/bind.d.ts new file mode 100644 index 00000000..f761ddfe --- /dev/null +++ b/dist/bind.d.ts @@ -0,0 +1 @@ +export declare function autoBind(obj: object): void; diff --git a/dist/bind.js b/dist/bind.js new file mode 100644 index 00000000..df71c05f --- /dev/null +++ b/dist/bind.js @@ -0,0 +1,15 @@ +'use strict'; +Object.defineProperty(exports, "__esModule", { value: true }); +function isMethod(propertyName, value) { + return propertyName !== 'constructor' && typeof value === 'function'; +} +function autoBind(obj) { + const propertyNames = Object.getOwnPropertyNames(obj.constructor.prototype); + propertyNames.forEach((propertyName) => { + const value = obj[propertyName]; + if (isMethod(propertyName, value)) { + obj[propertyName] = value.bind(obj); + } + }); +} +exports.autoBind = autoBind; diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts new file mode 100644 index 00000000..9e1704dc --- /dev/null +++ b/dist/consumer.d.ts @@ -0,0 +1,58 @@ +import * as SQS from 'aws-sdk/clients/sqs'; +import { EventEmitter } from 'events'; +declare type SQSMessage = SQS.Types.Message; +export interface ConsumerOptions { + queueUrl?: string; + attributeNames?: string[]; + messageAttributeNames?: string[]; + stopped?: boolean; + batchSize?: number; + visibilityTimeout?: number; + waitTimeSeconds?: number; + authenticationErrorTimeout?: number; + pollingWaitTimeMs?: number; + terminateVisibilityTimeout?: boolean; + sqs?: SQS; + region?: string; + handleMessageTimeout?: number; + handleMessage?(message: SQSMessage): Promise; + handleMessageBatch?(messages: SQSMessage[]): Promise; + pollingStartedInstrumentCallback?(eventData: object): void; + pollingFinishedInstrumentCallback?(eventData: object): void; +} +export declare class Consumer extends EventEmitter { + private queueUrl; + private handleMessage; + private handleMessageBatch; + private pollingStartedInstrumentCallback?; + private pollingFinishedInstrumentCallback?; + private handleMessageTimeout; + private attributeNames; + private messageAttributeNames; + private stopped; + private batchSize; + private visibilityTimeout; + private waitTimeSeconds; + private authenticationErrorTimeout; + private pollingWaitTimeMs; + private terminateVisibilityTimeout; + private sqs; + constructor(options: ConsumerOptions); + readonly isRunning: boolean; + static create(options: ConsumerOptions): Consumer; + start(): void; + stop(): void; + private handleSqsResponse; + private processMessage; + private receiveMessage; + private deleteMessage; + private executeHandler; + private terminateVisabilityTimeout; + private emitError; + private poll; + private processMessageBatch; + private deleteMessageBatch; + private executeBatchHandler; + private terminateVisabilityTimeoutBatch; +} +export {}; diff --git a/dist/consumer.js b/dist/consumer.js new file mode 100644 index 00000000..e8487f83 --- /dev/null +++ b/dist/consumer.js @@ -0,0 +1,300 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const SQS = require("aws-sdk/clients/sqs"); +const Debug = require("debug"); +const events_1 = require("events"); +const bind_1 = require("./bind"); +const errors_1 = require("./errors"); +const debug = Debug('sqs-consumer'); +const requiredOptions = [ + 'queueUrl', + // only one of handleMessage / handleMessagesBatch is required + 'handleMessage|handleMessageBatch' +]; +function createTimeout(duration) { + let timeout; + const pending = new Promise((_, reject) => { + timeout = setTimeout(() => { + reject(new errors_1.TimeoutError()); + }, duration); + }); + return [timeout, pending]; +} +function assertOptions(options) { + requiredOptions.forEach(option => { + const possibilities = option.split('|'); + if (!possibilities.find(p => options[p])) { + throw new Error(`Missing SQS consumer option [ ${possibilities.join(' or ')} ].`); + } + }); + if (options.batchSize > 10 || options.batchSize < 1) { + throw new Error('SQS batchSize option must be between 1 and 10.'); + } +} +function isConnectionError(err) { + if (err instanceof errors_1.SQSError) { + return err.statusCode === 403 || err.code === 'CredentialsError' || err.code === 'UnknownEndpoint'; + } + return false; +} +function toSQSError(err, message) { + const sqsError = new errors_1.SQSError(message); + sqsError.code = err.code; + sqsError.statusCode = err.statusCode; + sqsError.region = err.region; + sqsError.retryable = err.retryable; + sqsError.hostname = err.hostname; + sqsError.time = err.time; + return sqsError; +} +function hasMessages(response) { + return response.Messages && response.Messages.length > 0; +} +class Consumer extends events_1.EventEmitter { + constructor(options) { + super(); + assertOptions(options); + this.queueUrl = options.queueUrl; + this.handleMessage = options.handleMessage; + this.handleMessageBatch = options.handleMessageBatch; + this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; + this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; + this.handleMessageTimeout = options.handleMessageTimeout; + this.attributeNames = options.attributeNames || []; + this.messageAttributeNames = options.messageAttributeNames || []; + this.stopped = true; + this.batchSize = options.batchSize || 1; + this.visibilityTimeout = options.visibilityTimeout; + this.terminateVisibilityTimeout = options.terminateVisibilityTimeout || false; + this.waitTimeSeconds = options.waitTimeSeconds || 20; + this.authenticationErrorTimeout = options.authenticationErrorTimeout || 10000; + this.pollingWaitTimeMs = options.pollingWaitTimeMs || 0; + this.sqs = + options.sqs || + new SQS({ + region: options.region || process.env.AWS_REGION || 'eu-west-1' + }); + bind_1.autoBind(this); + } + get isRunning() { + return !this.stopped; + } + static create(options) { + return new Consumer(options); + } + start() { + if (this.stopped) { + debug('Starting consumer'); + this.stopped = false; + this.poll(); + } + } + stop() { + debug('Stopping consumer'); + this.stopped = true; + } + async handleSqsResponse(response) { + debug('Received SQS response'); + debug(response); + this.pollingFinishedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); + if (response) { + if (hasMessages(response)) { + if (this.handleMessageBatch) { + // prefer handling messages in batch when available + await this.processMessageBatch(response.Messages); + } + else { + await Promise.all(response.Messages.map(this.processMessage)); + } + this.emit('response_processed'); + } + else { + this.emit('empty'); + } + } + } + async processMessage(message) { + this.emit('message_received', message); + try { + await this.executeHandler(message); + await this.deleteMessage(message); + this.emit('message_processed', message); + } + catch (err) { + this.emitError(err, message); + if (this.terminateVisibilityTimeout) { + try { + await this.terminateVisabilityTimeout(message); + } + catch (err) { + this.emit('error', err, message); + } + } + } + } + async receiveMessage(params) { + try { + return await this.sqs.receiveMessage(params).promise(); + } + catch (err) { + throw toSQSError(err, `SQS receive message failed: ${err.message}`); + } + } + async deleteMessage(message) { + debug('Deleting message %s', message.MessageId); + const deleteParams = { + QueueUrl: this.queueUrl, + ReceiptHandle: message.ReceiptHandle + }; + try { + await this.sqs.deleteMessage(deleteParams).promise(); + } + catch (err) { + throw toSQSError(err, `SQS delete message failed: ${err.message}`); + } + } + async executeHandler(message) { + let timeout; + let pending; + try { + if (this.handleMessageTimeout) { + [timeout, pending] = createTimeout(this.handleMessageTimeout); + await Promise.race([this.handleMessage(message), pending]); + } + else { + await this.handleMessage(message); + } + } + catch (err) { + if (err instanceof errors_1.TimeoutError) { + err.message = `Message handler timed out after ${this.handleMessageTimeout}ms: Operation timed out.`; + } + else { + err.message = `Unexpected message handler failure: ${err.message}`; + } + throw err; + } + finally { + clearTimeout(timeout); + } + } + async terminateVisabilityTimeout(message) { + return this.sqs + .changeMessageVisibility({ + QueueUrl: this.queueUrl, + ReceiptHandle: message.ReceiptHandle, + VisibilityTimeout: 0 + }) + .promise(); + } + emitError(err, message) { + if (err.name === errors_1.SQSError.name) { + this.emit('error', err, message); + } + else if (err instanceof errors_1.TimeoutError) { + this.emit('timeout_error', err, message); + } + else { + this.emit('processing_error', err, message); + } + } + poll() { + if (this.stopped) { + this.emit('stopped'); + return; + } + debug('Polling for messages'); + this.pollingStartedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); + const receiveParams = { + QueueUrl: this.queueUrl, + AttributeNames: this.attributeNames, + MessageAttributeNames: this.messageAttributeNames, + MaxNumberOfMessages: this.batchSize, + WaitTimeSeconds: this.waitTimeSeconds, + VisibilityTimeout: this.visibilityTimeout + }; + let currentPollingTimeout = this.pollingWaitTimeMs; + this.receiveMessage(receiveParams) + .then(this.handleSqsResponse) + .catch(err => { + this.emit('error', err); + if (isConnectionError(err)) { + debug('There was an authentication error. Pausing before retrying.'); + currentPollingTimeout = this.authenticationErrorTimeout; + } + return; + }) + .then(() => { + setTimeout(this.poll, currentPollingTimeout); + }) + .catch(err => { + this.emit('error', err); + }); + } + async processMessageBatch(messages) { + messages.forEach(message => { + this.emit('message_received', message); + }); + try { + await this.executeBatchHandler(messages); + await this.deleteMessageBatch(messages); + messages.forEach(message => { + this.emit('message_processed', message); + }); + } + catch (err) { + this.emit('error', err, messages); + if (this.terminateVisibilityTimeout) { + try { + await this.terminateVisabilityTimeoutBatch(messages); + } + catch (err) { + this.emit('error', err, messages); + } + } + } + } + async deleteMessageBatch(messages) { + debug('Deleting messages %s', messages.map(msg => msg.MessageId).join(' ,')); + const deleteParams = { + QueueUrl: this.queueUrl, + Entries: messages.map(message => ({ + Id: message.MessageId, + ReceiptHandle: message.ReceiptHandle + })) + }; + try { + await this.sqs.deleteMessageBatch(deleteParams).promise(); + } + catch (err) { + throw toSQSError(err, `SQS delete message failed: ${err.message}`); + } + } + async executeBatchHandler(messages) { + try { + await this.handleMessageBatch(messages); + } + catch (err) { + err.message = `Unexpected message handler failure: ${err.message}`; + throw err; + } + } + async terminateVisabilityTimeoutBatch(messages) { + const params = { + QueueUrl: this.queueUrl, + Entries: messages.map(message => ({ + Id: message.MessageId, + ReceiptHandle: message.ReceiptHandle, + VisibilityTimeout: 0 + })) + }; + return this.sqs.changeMessageVisibilityBatch(params).promise(); + } +} +exports.Consumer = Consumer; diff --git a/dist/errors.d.ts b/dist/errors.d.ts new file mode 100644 index 00000000..f14df68c --- /dev/null +++ b/dist/errors.d.ts @@ -0,0 +1,13 @@ +declare class SQSError extends Error { + code: string; + statusCode: number; + region: string; + hostname: string; + time: Date; + retryable: boolean; + constructor(message: string); +} +declare class TimeoutError extends Error { + constructor(message?: string); +} +export { SQSError, TimeoutError }; diff --git a/dist/errors.js b/dist/errors.js new file mode 100644 index 00000000..1e30c249 --- /dev/null +++ b/dist/errors.js @@ -0,0 +1,17 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +class SQSError extends Error { + constructor(message) { + super(message); + this.name = this.constructor.name; + } +} +exports.SQSError = SQSError; +class TimeoutError extends Error { + constructor(message = 'Operation timed out.') { + super(message); + this.message = message; + this.name = 'TimeoutError'; + } +} +exports.TimeoutError = TimeoutError; diff --git a/dist/index.d.ts b/dist/index.d.ts new file mode 100644 index 00000000..84ff4197 --- /dev/null +++ b/dist/index.d.ts @@ -0,0 +1 @@ +export { Consumer, ConsumerOptions } from './consumer'; diff --git a/dist/index.js b/dist/index.js new file mode 100644 index 00000000..20a65164 --- /dev/null +++ b/dist/index.js @@ -0,0 +1,4 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var consumer_1 = require("./consumer"); +exports.Consumer = consumer_1.Consumer; From 775472fb4117656c1a3ef96d4cb13b4c7d8ddb81 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Thu, 14 Nov 2019 17:06:35 +0200 Subject: [PATCH 03/40] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 349ef1cd..c24f92c0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.5.0", + "version": "5.6.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 53cc6e0e9aa3c26985def8e590885c0c2b4f266b Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Tue, 19 Nov 2019 15:36:51 +0200 Subject: [PATCH 04/40] polling instrument null check --- src/consumer.ts | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/consumer.ts b/src/consumer.ts index 42f3a9d1..e334ac0f 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -159,10 +159,13 @@ export class Consumer extends EventEmitter { private async handleSqsResponse(response: ReceieveMessageResponse): Promise { debug('Received SQS response'); debug(response); - this.pollingFinishedInstrumentCallback({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl - }); + + if (this.pollingFinishedInstrumentCallback) { + this.pollingFinishedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); + } if (response) { if (hasMessages(response)) { @@ -271,10 +274,12 @@ export class Consumer extends EventEmitter { } debug('Polling for messages'); - this.pollingStartedInstrumentCallback({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl - }); + if (this.pollingStartedInstrumentCallback) { + this.pollingStartedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); + } const receiveParams = { QueueUrl: this.queueUrl, AttributeNames: this.attributeNames, From aba3ab7e5eecf5c65b52338734725795f4329bb3 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Tue, 19 Nov 2019 15:37:03 +0200 Subject: [PATCH 05/40] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c24f92c0..fffe022d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.6.0", + "version": "5.7.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From c22643e8dec7651f8e4ceaaf09e2f24c827d401a Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Tue, 19 Nov 2019 15:55:52 +0200 Subject: [PATCH 06/40] build ts --- dist/consumer.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/dist/consumer.js b/dist/consumer.js index e8487f83..67171699 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -96,10 +96,12 @@ class Consumer extends events_1.EventEmitter { async handleSqsResponse(response) { debug('Received SQS response'); debug(response); - this.pollingFinishedInstrumentCallback({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl - }); + if (this.pollingFinishedInstrumentCallback) { + this.pollingFinishedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); + } if (response) { if (hasMessages(response)) { if (this.handleMessageBatch) { @@ -207,10 +209,12 @@ class Consumer extends events_1.EventEmitter { return; } debug('Polling for messages'); - this.pollingStartedInstrumentCallback({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl - }); + if (this.pollingStartedInstrumentCallback) { + this.pollingStartedInstrumentCallback({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl + }); + } const receiveParams = { QueueUrl: this.queueUrl, AttributeNames: this.attributeNames, From 052af9121ad066ec0ed19b420967023de627fff2 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Tue, 19 Nov 2019 15:56:10 +0200 Subject: [PATCH 07/40] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fffe022d..2fd6df4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.0", + "version": "5.7.1", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 697c58de70275ea49e210807ff6153dde34e05a8 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 24 Nov 2019 12:33:38 +0200 Subject: [PATCH 08/40] add message uuid to errors --- dist/consumer.js | 10 ++++++++++ package-lock.json | 5 ++--- package.json | 3 ++- src/consumer.ts | 11 +++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/dist/consumer.js b/dist/consumer.js index 67171699..d53854df 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -5,6 +5,7 @@ const Debug = require("debug"); const events_1 = require("events"); const bind_1 = require("./bind"); const errors_1 = require("./errors"); +const lodash_1 = require("lodash"); const debug = Debug('sqs-consumer'); const requiredOptions = [ 'queueUrl', @@ -50,6 +51,14 @@ function toSQSError(err, message) { function hasMessages(response) { return response.Messages && response.Messages.length > 0; } +function addMessageUuidToError(error, message) { + try { + const messageBody = JSON.parse(message.Body); + const messageUuid = lodash_1.default.get(messageBody, 'payload.uuid', ''); + error.messageUuid = messageUuid; + } + catch (err) { } +} class Consumer extends events_1.EventEmitter { constructor(options) { super(); @@ -171,6 +180,7 @@ class Consumer extends events_1.EventEmitter { } } catch (err) { + addMessageUuidToError(err, message); if (err instanceof errors_1.TimeoutError) { err.message = `Message handler timed out after ${this.handleMessageTimeout}ms: Operation timed out.`; } diff --git a/package-lock.json b/package-lock.json index f9b201a5..48eb7b4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.4.0", + "version": "5.7.2", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1241,8 +1241,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" }, "lodash.flattendeep": { "version": "4.4.0", diff --git a/package.json b/package.json index 2fd6df4e..62349adf 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,8 @@ }, "dependencies": { "aws-sdk": "^2.443.0", - "debug": "^4.1.1" + "debug": "^4.1.1", + "lodash": "^4.17.15" }, "nyc": { "include": [ diff --git a/src/consumer.ts b/src/consumer.ts index e334ac0f..fbbf75e4 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -5,6 +5,7 @@ import * as Debug from 'debug'; import { EventEmitter } from 'events'; import { autoBind } from './bind'; import { SQSError, TimeoutError } from './errors'; +import _ from 'lodash'; const debug = Debug('sqs-consumer'); @@ -69,6 +70,15 @@ function hasMessages(response: ReceieveMessageResponse): boolean { return response.Messages && response.Messages.length > 0; } +function addMessageUuidToError(error, message): void { + try { + const messageBody = JSON.parse(message.Body); + const messageUuid = _.get(messageBody, 'payload.uuid', ''); + + error.messageUuid = messageUuid; + } catch (err) {} +} + export interface ConsumerOptions { queueUrl?: string; attributeNames?: string[]; @@ -236,6 +246,7 @@ export class Consumer extends EventEmitter { await this.handleMessage(message); } } catch (err) { + addMessageUuidToError(err, message); if (err instanceof TimeoutError) { err.message = `Message handler timed out after ${this.handleMessageTimeout}ms: Operation timed out.`; } else { From 351362a5908775bb1ae8958df49ec0c155875049 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 24 Nov 2019 12:40:46 +0200 Subject: [PATCH 09/40] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 62349adf..817ee979 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.1", + "version": "5.7.3", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 8894a2c924abf648664b94c72add9263fca09ff0 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 24 Nov 2019 14:25:06 +0200 Subject: [PATCH 10/40] remove lodash --- package-lock.json | 5 +++-- package.json | 3 +-- src/consumer.ts | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 48eb7b4e..ff655a7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.2", + "version": "5.7.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1241,7 +1241,8 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true }, "lodash.flattendeep": { "version": "4.4.0", diff --git a/package.json b/package.json index 817ee979..f3664fdf 100644 --- a/package.json +++ b/package.json @@ -51,8 +51,7 @@ }, "dependencies": { "aws-sdk": "^2.443.0", - "debug": "^4.1.1", - "lodash": "^4.17.15" + "debug": "^4.1.1" }, "nyc": { "include": [ diff --git a/src/consumer.ts b/src/consumer.ts index fbbf75e4..83c5dd2a 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -5,7 +5,6 @@ import * as Debug from 'debug'; import { EventEmitter } from 'events'; import { autoBind } from './bind'; import { SQSError, TimeoutError } from './errors'; -import _ from 'lodash'; const debug = Debug('sqs-consumer'); @@ -73,7 +72,7 @@ function hasMessages(response: ReceieveMessageResponse): boolean { function addMessageUuidToError(error, message): void { try { const messageBody = JSON.parse(message.Body); - const messageUuid = _.get(messageBody, 'payload.uuid', ''); + const messageUuid = messageBody && messageBody.payload && messageBody.payload.uuid; error.messageUuid = messageUuid; } catch (err) {} From a88d7bc697596d1bc448a876daad9492171d7dd9 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 24 Nov 2019 14:25:23 +0200 Subject: [PATCH 11/40] update version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f3664fdf..d4010412 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.3", + "version": "5.7.4", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From d4715141cb174ee912154529743f096f39dc96e4 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 24 Nov 2019 14:27:34 +0200 Subject: [PATCH 12/40] update version --- dist/consumer.js | 3 +-- package.json | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dist/consumer.js b/dist/consumer.js index d53854df..df59d6da 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -5,7 +5,6 @@ const Debug = require("debug"); const events_1 = require("events"); const bind_1 = require("./bind"); const errors_1 = require("./errors"); -const lodash_1 = require("lodash"); const debug = Debug('sqs-consumer'); const requiredOptions = [ 'queueUrl', @@ -54,7 +53,7 @@ function hasMessages(response) { function addMessageUuidToError(error, message) { try { const messageBody = JSON.parse(message.Body); - const messageUuid = lodash_1.default.get(messageBody, 'payload.uuid', ''); + const messageUuid = messageBody && messageBody.payload && messageBody.payload.uuid; error.messageUuid = messageUuid; } catch (err) { } diff --git a/package.json b/package.json index d4010412..92c95525 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.4", + "version": "5.7.5", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 3de9bcc121df177fbf31b6e5d4c89bd32e7d94ce Mon Sep 17 00:00:00 2001 From: Ran Nir <> Date: Mon, 18 May 2020 17:25:43 +0300 Subject: [PATCH 13/40] current owrk --- dist/consumer.d.ts | 12 ++-- dist/consumer.js | 151 +++++++++++++++++++-------------------- package.json | 4 +- src/consumer.ts | 171 +++++++++++++++++++++++---------------------- 4 files changed, 169 insertions(+), 169 deletions(-) diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts index 9e1704dc..0f9a6478 100644 --- a/dist/consumer.d.ts +++ b/dist/consumer.d.ts @@ -6,6 +6,7 @@ export interface ConsumerOptions { attributeNames?: string[]; messageAttributeNames?: string[]; stopped?: boolean; + concurencyLimit?: number; batchSize?: number; visibilityTimeout?: number; waitTimeSeconds?: number; @@ -16,9 +17,10 @@ export interface ConsumerOptions { region?: string; handleMessageTimeout?: number; handleMessage?(message: SQSMessage): Promise; - handleMessageBatch?(messages: SQSMessage[]): Promise; + handleMessageBatch?(messages: SQSMessage[], consumer: Consumer): Promise; pollingStartedInstrumentCallback?(eventData: object): void; pollingFinishedInstrumentCallback?(eventData: object): void; + batchSizeUpdatedInstrument?(eventData: object): void; } export declare class Consumer extends EventEmitter { private queueUrl; @@ -26,10 +28,12 @@ export declare class Consumer extends EventEmitter { private handleMessageBatch; private pollingStartedInstrumentCallback?; private pollingFinishedInstrumentCallback?; + private batchSizeUpdatedInstrument?; private handleMessageTimeout; private attributeNames; private messageAttributeNames; private stopped; + private concurencyLimit; private batchSize; private visibilityTimeout; private waitTimeSeconds; @@ -42,6 +46,9 @@ export declare class Consumer extends EventEmitter { static create(options: ConsumerOptions): Consumer; start(): void; stop(): void; + reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise; + private reportNumberOfMessagesReceived; + private updateBatchSize; private handleSqsResponse; private processMessage; private receiveMessage; @@ -51,8 +58,5 @@ export declare class Consumer extends EventEmitter { private emitError; private poll; private processMessageBatch; - private deleteMessageBatch; - private executeBatchHandler; - private terminateVisabilityTimeoutBatch; } export {}; diff --git a/dist/consumer.js b/dist/consumer.js index df59d6da..be8e9534 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -67,11 +67,13 @@ class Consumer extends events_1.EventEmitter { this.handleMessageBatch = options.handleMessageBatch; this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; + this.batchSizeUpdatedInstrument = options.batchSizeUpdatedInstrument; this.handleMessageTimeout = options.handleMessageTimeout; this.attributeNames = options.attributeNames || []; this.messageAttributeNames = options.messageAttributeNames || []; this.stopped = true; this.batchSize = options.batchSize || 1; + this.concurencyLimit = options.concurencyLimit || 30; this.visibilityTimeout = options.visibilityTimeout; this.terminateVisibilityTimeout = options.terminateVisibilityTimeout || false; this.waitTimeSeconds = options.waitTimeSeconds || 20; @@ -101,13 +103,49 @@ class Consumer extends events_1.EventEmitter { debug('Stopping consumer'); this.stopped = true; } + async reportMessageFromBatchFinished(message, error) { + debug('Message from batch has finised'); + this.concurencyLimit++; + this.updateBatchSize(); + try { + if (error) + throw error; + await this.deleteMessage(message); + this.emit('message_processed', message); + } + catch (err) { + this.emitError(err, message); + } + } + reportNumberOfMessagesReceived(numberOfMessages) { + debug('decrementing next batch size'); + this.concurencyLimit = this.concurencyLimit - numberOfMessages; + this.updateBatchSize(); + } + updateBatchSize() { + debug('Updating next batch size'); + this.batchSize = Math.min(10, this.concurencyLimit); + // instrument current batch size + if (this.batchSizeUpdatedInstrument) { + this.batchSizeUpdatedInstrument({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + currentConcurencyLimit: this.concurencyLimit, + batchSize: this.batchSize + }); + } + } async handleSqsResponse(response) { debug('Received SQS response'); debug(response); + const hasResponseWithMessages = !!response && hasMessages(response); + const numberOfMessages = hasResponseWithMessages ? response.Messages.length : 0; if (this.pollingFinishedInstrumentCallback) { + // instrument pod how many messages received this.pollingFinishedInstrumentCallback({ instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl + queueUrl: this.queueUrl, + messagesReceived: numberOfMessages }); } if (response) { @@ -221,93 +259,48 @@ class Consumer extends events_1.EventEmitter { if (this.pollingStartedInstrumentCallback) { this.pollingStartedInstrumentCallback({ instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl + queueUrl: this.queueUrl, + // instrument i am about to request this.batchSize messages + batchSize: this.batchSize }); } - const receiveParams = { - QueueUrl: this.queueUrl, - AttributeNames: this.attributeNames, - MessageAttributeNames: this.messageAttributeNames, - MaxNumberOfMessages: this.batchSize, - WaitTimeSeconds: this.waitTimeSeconds, - VisibilityTimeout: this.visibilityTimeout - }; let currentPollingTimeout = this.pollingWaitTimeMs; - this.receiveMessage(receiveParams) - .then(this.handleSqsResponse) - .catch(err => { - this.emit('error', err); - if (isConnectionError(err)) { - debug('There was an authentication error. Pausing before retrying.'); - currentPollingTimeout = this.authenticationErrorTimeout; - } - return; - }) - .then(() => { + if (this.batchSize > 0) { + const receiveParams = { + QueueUrl: this.queueUrl, + AttributeNames: this.attributeNames, + MessageAttributeNames: this.messageAttributeNames, + MaxNumberOfMessages: this.batchSize, + WaitTimeSeconds: this.waitTimeSeconds, + VisibilityTimeout: this.visibilityTimeout + }; + this.receiveMessage(receiveParams) + .then(this.handleSqsResponse) + .catch(err => { + this.emit('error', err); + if (isConnectionError(err)) { + debug('There was an authentication error. Pausing before retrying.'); + currentPollingTimeout = this.authenticationErrorTimeout; + } + return; + }) + .then(() => { + setTimeout(this.poll, currentPollingTimeout); + }) + .catch(err => { + this.emit('error', err); + }); + } + else { setTimeout(this.poll, currentPollingTimeout); - }) - .catch(err => { - this.emit('error', err); - }); + } } async processMessageBatch(messages) { messages.forEach(message => { this.emit('message_received', message); }); - try { - await this.executeBatchHandler(messages); - await this.deleteMessageBatch(messages); - messages.forEach(message => { - this.emit('message_processed', message); - }); - } - catch (err) { - this.emit('error', err, messages); - if (this.terminateVisibilityTimeout) { - try { - await this.terminateVisabilityTimeoutBatch(messages); - } - catch (err) { - this.emit('error', err, messages); - } - } - } - } - async deleteMessageBatch(messages) { - debug('Deleting messages %s', messages.map(msg => msg.MessageId).join(' ,')); - const deleteParams = { - QueueUrl: this.queueUrl, - Entries: messages.map(message => ({ - Id: message.MessageId, - ReceiptHandle: message.ReceiptHandle - })) - }; - try { - await this.sqs.deleteMessageBatch(deleteParams).promise(); - } - catch (err) { - throw toSQSError(err, `SQS delete message failed: ${err.message}`); - } - } - async executeBatchHandler(messages) { - try { - await this.handleMessageBatch(messages); - } - catch (err) { - err.message = `Unexpected message handler failure: ${err.message}`; - throw err; - } - } - async terminateVisabilityTimeoutBatch(messages) { - const params = { - QueueUrl: this.queueUrl, - Entries: messages.map(message => ({ - Id: message.MessageId, - ReceiptHandle: message.ReceiptHandle, - VisibilityTimeout: 0 - })) - }; - return this.sqs.changeMessageVisibilityBatch(params).promise(); + this.reportNumberOfMessagesReceived(messages.length); + this.handleMessageBatch(messages, this); } } exports.Consumer = Consumer; diff --git a/package.json b/package.json index 92c95525..45334889 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.5", + "version": "5.7.6", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -66,4 +66,4 @@ "sourceMap": true, "instrument": true } -} +} \ No newline at end of file diff --git a/src/consumer.ts b/src/consumer.ts index 83c5dd2a..36790384 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -83,6 +83,7 @@ export interface ConsumerOptions { attributeNames?: string[]; messageAttributeNames?: string[]; stopped?: boolean; + concurencyLimit?: number; batchSize?: number; visibilityTimeout?: number; waitTimeSeconds?: number; @@ -93,21 +94,24 @@ export interface ConsumerOptions { region?: string; handleMessageTimeout?: number; handleMessage?(message: SQSMessage): Promise; - handleMessageBatch?(messages: SQSMessage[]): Promise; + handleMessageBatch?(messages: SQSMessage[], consumer: Consumer): Promise; pollingStartedInstrumentCallback?(eventData: object): void; pollingFinishedInstrumentCallback?(eventData: object): void; + batchSizeUpdatedInstrument?(eventData: object): void; } export class Consumer extends EventEmitter { private queueUrl: string; private handleMessage: (message: SQSMessage) => Promise; - private handleMessageBatch: (message: SQSMessage[]) => Promise; + private handleMessageBatch: (message: SQSMessage[], consumer: Consumer) => Promise; private pollingStartedInstrumentCallback?: (eventData: object) => void; private pollingFinishedInstrumentCallback?: (eventData: object) => void; + private batchSizeUpdatedInstrument?: (eventData: object) => void; private handleMessageTimeout: number; private attributeNames: string[]; private messageAttributeNames: string[]; private stopped: boolean; + private concurencyLimit: number; private batchSize: number; private visibilityTimeout: number; private waitTimeSeconds: number; @@ -124,11 +128,13 @@ export class Consumer extends EventEmitter { this.handleMessageBatch = options.handleMessageBatch; this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; + this.batchSizeUpdatedInstrument = options.batchSizeUpdatedInstrument; this.handleMessageTimeout = options.handleMessageTimeout; this.attributeNames = options.attributeNames || []; this.messageAttributeNames = options.messageAttributeNames || []; this.stopped = true; this.batchSize = options.batchSize || 1; + this.concurencyLimit = options.concurencyLimit || 30; this.visibilityTimeout = options.visibilityTimeout; this.terminateVisibilityTimeout = options.terminateVisibilityTimeout || false; this.waitTimeSeconds = options.waitTimeSeconds || 20; @@ -165,14 +171,57 @@ export class Consumer extends EventEmitter { this.stopped = true; } + public async reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise { + debug('Message from batch has finised'); + + this.concurencyLimit++; + this.updateBatchSize(); + + try { + if (error) throw error; + + await this.deleteMessage(message); + this.emit('message_processed', message); + } catch (err) { + this.emitError(err, message); + } + } + + private reportNumberOfMessagesReceived(numberOfMessages: number): void { + debug('decrementing next batch size'); + this.concurencyLimit = this.concurencyLimit - numberOfMessages; + this.updateBatchSize(); + } + + private updateBatchSize(): void { + debug('Updating next batch size'); + + this.batchSize = Math.min(10, this.concurencyLimit); + + // instrument current batch size + if (this.batchSizeUpdatedInstrument) { + this.batchSizeUpdatedInstrument({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + currentConcurencyLimit: this.concurencyLimit, + batchSize: this.batchSize + }); + } + } + private async handleSqsResponse(response: ReceieveMessageResponse): Promise { debug('Received SQS response'); debug(response); + const hasResponseWithMessages = !!response && hasMessages(response); + const numberOfMessages = hasResponseWithMessages ? response.Messages.length : 0; + if (this.pollingFinishedInstrumentCallback) { + // instrument pod how many messages received this.pollingFinishedInstrumentCallback({ instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl + queueUrl: this.queueUrl, + messagesReceived: numberOfMessages }); } @@ -287,35 +336,43 @@ export class Consumer extends EventEmitter { if (this.pollingStartedInstrumentCallback) { this.pollingStartedInstrumentCallback({ instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl + queueUrl: this.queueUrl, + // instrument i am about to request this.batchSize messages + batchSize: this.batchSize }); } - const receiveParams = { - QueueUrl: this.queueUrl, - AttributeNames: this.attributeNames, - MessageAttributeNames: this.messageAttributeNames, - MaxNumberOfMessages: this.batchSize, - WaitTimeSeconds: this.waitTimeSeconds, - VisibilityTimeout: this.visibilityTimeout - }; let currentPollingTimeout = this.pollingWaitTimeMs; - this.receiveMessage(receiveParams) - .then(this.handleSqsResponse) - .catch(err => { - this.emit('error', err); - if (isConnectionError(err)) { - debug('There was an authentication error. Pausing before retrying.'); - currentPollingTimeout = this.authenticationErrorTimeout; - } - return; - }) - .then(() => { - setTimeout(this.poll, currentPollingTimeout); - }) - .catch(err => { - this.emit('error', err); - }); + + if (this.batchSize > 0) { + const receiveParams = { + QueueUrl: this.queueUrl, + AttributeNames: this.attributeNames, + MessageAttributeNames: this.messageAttributeNames, + MaxNumberOfMessages: this.batchSize, + WaitTimeSeconds: this.waitTimeSeconds, + VisibilityTimeout: this.visibilityTimeout + }; + + this.receiveMessage(receiveParams) + .then(this.handleSqsResponse) + .catch(err => { + this.emit('error', err); + if (isConnectionError(err)) { + debug('There was an authentication error. Pausing before retrying.'); + currentPollingTimeout = this.authenticationErrorTimeout; + } + return; + }) + .then(() => { + setTimeout(this.poll, currentPollingTimeout); + }) + .catch(err => { + this.emit('error', err); + }); + } else { + setTimeout(this.poll, currentPollingTimeout); + } } private async processMessageBatch(messages: SQSMessage[]): Promise { @@ -323,61 +380,7 @@ export class Consumer extends EventEmitter { this.emit('message_received', message); }); - try { - await this.executeBatchHandler(messages); - await this.deleteMessageBatch(messages); - messages.forEach(message => { - this.emit('message_processed', message); - }); - } catch (err) { - this.emit('error', err, messages); - - if (this.terminateVisibilityTimeout) { - try { - await this.terminateVisabilityTimeoutBatch(messages); - } catch (err) { - this.emit('error', err, messages); - } - } - } - } - - private async deleteMessageBatch(messages: SQSMessage[]): Promise { - debug('Deleting messages %s', messages.map(msg => msg.MessageId).join(' ,')); - - const deleteParams = { - QueueUrl: this.queueUrl, - Entries: messages.map(message => ({ - Id: message.MessageId, - ReceiptHandle: message.ReceiptHandle - })) - }; - - try { - await this.sqs.deleteMessageBatch(deleteParams).promise(); - } catch (err) { - throw toSQSError(err, `SQS delete message failed: ${err.message}`); - } - } - - private async executeBatchHandler(messages: SQSMessage[]): Promise { - try { - await this.handleMessageBatch(messages); - } catch (err) { - err.message = `Unexpected message handler failure: ${err.message}`; - throw err; - } - } - - private async terminateVisabilityTimeoutBatch(messages: SQSMessage[]): Promise> { - const params = { - QueueUrl: this.queueUrl, - Entries: messages.map(message => ({ - Id: message.MessageId, - ReceiptHandle: message.ReceiptHandle, - VisibilityTimeout: 0 - })) - }; - return this.sqs.changeMessageVisibilityBatch(params).promise(); + this.reportNumberOfMessagesReceived(messages.length); + this.handleMessageBatch(messages, this); } } From cc79c01c8b90de4008383990987856a0aef7922e Mon Sep 17 00:00:00 2001 From: Ran Nir <> Date: Tue, 19 May 2020 11:36:33 +0300 Subject: [PATCH 14/40] timeout for batch size zero --- dist/consumer.d.ts | 2 ++ dist/consumer.js | 3 ++- src/consumer.ts | 5 ++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts index 0f9a6478..fbbace79 100644 --- a/dist/consumer.d.ts +++ b/dist/consumer.d.ts @@ -12,6 +12,7 @@ export interface ConsumerOptions { waitTimeSeconds?: number; authenticationErrorTimeout?: number; pollingWaitTimeMs?: number; + pollingWaitTimeMsBatchSizeZero?: number; terminateVisibilityTimeout?: boolean; sqs?: SQS; region?: string; @@ -39,6 +40,7 @@ export declare class Consumer extends EventEmitter { private waitTimeSeconds; private authenticationErrorTimeout; private pollingWaitTimeMs; + private pollingWaitTimeMsBatchSizeZero; private terminateVisibilityTimeout; private sqs; constructor(options: ConsumerOptions); diff --git a/dist/consumer.js b/dist/consumer.js index be8e9534..3c3f3faf 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -79,6 +79,7 @@ class Consumer extends events_1.EventEmitter { this.waitTimeSeconds = options.waitTimeSeconds || 20; this.authenticationErrorTimeout = options.authenticationErrorTimeout || 10000; this.pollingWaitTimeMs = options.pollingWaitTimeMs || 0; + this.pollingWaitTimeMsBatchSizeZero = options.pollingWaitTimeMsBatchSizeZero || 5; this.sqs = options.sqs || new SQS({ @@ -292,7 +293,7 @@ class Consumer extends events_1.EventEmitter { }); } else { - setTimeout(this.poll, currentPollingTimeout); + setTimeout(this.poll, this.pollingWaitTimeMsBatchSizeZero); } } async processMessageBatch(messages) { diff --git a/src/consumer.ts b/src/consumer.ts index 36790384..ff5ad24b 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -89,6 +89,7 @@ export interface ConsumerOptions { waitTimeSeconds?: number; authenticationErrorTimeout?: number; pollingWaitTimeMs?: number; + pollingWaitTimeMsBatchSizeZero?: number; terminateVisibilityTimeout?: boolean; sqs?: SQS; region?: string; @@ -117,6 +118,7 @@ export class Consumer extends EventEmitter { private waitTimeSeconds: number; private authenticationErrorTimeout: number; private pollingWaitTimeMs: number; + private pollingWaitTimeMsBatchSizeZero: number; private terminateVisibilityTimeout: boolean; private sqs: SQS; @@ -140,6 +142,7 @@ export class Consumer extends EventEmitter { this.waitTimeSeconds = options.waitTimeSeconds || 20; this.authenticationErrorTimeout = options.authenticationErrorTimeout || 10000; this.pollingWaitTimeMs = options.pollingWaitTimeMs || 0; + this.pollingWaitTimeMsBatchSizeZero = options.pollingWaitTimeMsBatchSizeZero || 5; this.sqs = options.sqs || @@ -371,7 +374,7 @@ export class Consumer extends EventEmitter { this.emit('error', err); }); } else { - setTimeout(this.poll, currentPollingTimeout); + setTimeout(this.poll, this.pollingWaitTimeMsBatchSizeZero); } } From eecc743709b72c5b34e0f471882c9314054e4edb Mon Sep 17 00:00:00 2001 From: Ran Nir <> Date: Tue, 19 May 2020 11:42:14 +0300 Subject: [PATCH 15/40] upgrade version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45334889..66108d85 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.6", + "version": "5.7.7", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 63284d737ed13c02b51b835ad73e1bd3827677d8 Mon Sep 17 00:00:00 2001 From: Ran Nir <> Date: Wed, 20 May 2020 14:23:45 +0300 Subject: [PATCH 16/40] review fixes --- src/consumer.ts | 98 +++++++++++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 36 deletions(-) diff --git a/src/consumer.ts b/src/consumer.ts index ff5ad24b..a7777516 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -2,6 +2,7 @@ import { AWSError } from 'aws-sdk'; import * as SQS from 'aws-sdk/clients/sqs'; import { PromiseResult } from 'aws-sdk/lib/request'; import * as Debug from 'debug'; +import * as crypto from 'crypto'; import { EventEmitter } from 'events'; import { autoBind } from './bind'; import { SQSError, TimeoutError } from './errors'; @@ -23,6 +24,10 @@ interface TimeoutResponse { pending: Promise; } +function generateUuid(): string { + return crypto.randomBytes(16).toString('hex'); +} + function createTimeout(duration: number): TimeoutResponse[] { let timeout; const pending = new Promise((_, reject) => { @@ -83,13 +88,13 @@ export interface ConsumerOptions { attributeNames?: string[]; messageAttributeNames?: string[]; stopped?: boolean; - concurencyLimit?: number; + concurrencyLimit?: number; batchSize?: number; visibilityTimeout?: number; waitTimeSeconds?: number; authenticationErrorTimeout?: number; pollingWaitTimeMs?: number; - pollingWaitTimeMsBatchSizeZero?: number; + msDelayOnEmptyBatchSize?: number; terminateVisibilityTimeout?: boolean; sqs?: SQS; region?: string; @@ -98,7 +103,9 @@ export interface ConsumerOptions { handleMessageBatch?(messages: SQSMessage[], consumer: Consumer): Promise; pollingStartedInstrumentCallback?(eventData: object): void; pollingFinishedInstrumentCallback?(eventData: object): void; - batchSizeUpdatedInstrument?(eventData: object): void; + batchStartedInstrumentCallBack?(eventData: object): void; + batchFinishedInstrumentCallBack?(eventData: object): void; + batchFailedInstrumentCallBack?(eventData: object): void; } export class Consumer extends EventEmitter { @@ -107,18 +114,21 @@ export class Consumer extends EventEmitter { private handleMessageBatch: (message: SQSMessage[], consumer: Consumer) => Promise; private pollingStartedInstrumentCallback?: (eventData: object) => void; private pollingFinishedInstrumentCallback?: (eventData: object) => void; - private batchSizeUpdatedInstrument?: (eventData: object) => void; + private batchStartedInstrumentCallBack?: (eventData: object) => void; + private batchFinishedInstrumentCallBack?: (eventData: object) => void; + private batchFailedInstrumentCallBack?: (eventData: object) => void; private handleMessageTimeout: number; private attributeNames: string[]; private messageAttributeNames: string[]; private stopped: boolean; - private concurencyLimit: number; + private concurrencyLimit: number; + private freeConcurrentSlots: number; private batchSize: number; private visibilityTimeout: number; private waitTimeSeconds: number; private authenticationErrorTimeout: number; private pollingWaitTimeMs: number; - private pollingWaitTimeMsBatchSizeZero: number; + private msDelayOnEmptyBatchSize: number; private terminateVisibilityTimeout: boolean; private sqs: SQS; @@ -130,19 +140,19 @@ export class Consumer extends EventEmitter { this.handleMessageBatch = options.handleMessageBatch; this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; - this.batchSizeUpdatedInstrument = options.batchSizeUpdatedInstrument; this.handleMessageTimeout = options.handleMessageTimeout; this.attributeNames = options.attributeNames || []; this.messageAttributeNames = options.messageAttributeNames || []; this.stopped = true; this.batchSize = options.batchSize || 1; - this.concurencyLimit = options.concurencyLimit || 30; + this.concurrencyLimit = options.concurrencyLimit || 30; + this.freeConcurrentSlots = this.concurrencyLimit; this.visibilityTimeout = options.visibilityTimeout; this.terminateVisibilityTimeout = options.terminateVisibilityTimeout || false; this.waitTimeSeconds = options.waitTimeSeconds || 20; this.authenticationErrorTimeout = options.authenticationErrorTimeout || 10000; this.pollingWaitTimeMs = options.pollingWaitTimeMs || 0; - this.pollingWaitTimeMsBatchSizeZero = options.pollingWaitTimeMsBatchSizeZero || 5; + this.msDelayOnEmptyBatchSize = options.msDelayOnEmptyBatchSize || 5; this.sqs = options.sqs || @@ -177,8 +187,7 @@ export class Consumer extends EventEmitter { public async reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise { debug('Message from batch has finised'); - this.concurencyLimit++; - this.updateBatchSize(); + this.freeConcurrentSlots++; try { if (error) throw error; @@ -191,25 +200,8 @@ export class Consumer extends EventEmitter { } private reportNumberOfMessagesReceived(numberOfMessages: number): void { - debug('decrementing next batch size'); - this.concurencyLimit = this.concurencyLimit - numberOfMessages; - this.updateBatchSize(); - } - - private updateBatchSize(): void { - debug('Updating next batch size'); - - this.batchSize = Math.min(10, this.concurencyLimit); - - // instrument current batch size - if (this.batchSizeUpdatedInstrument) { - this.batchSizeUpdatedInstrument({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl, - currentConcurencyLimit: this.concurencyLimit, - batchSize: this.batchSize - }); - } + debug('Reducing number of messages received from freeConcurrentSlots'); + this.freeConcurrentSlots = this.freeConcurrentSlots - numberOfMessages; } private async handleSqsResponse(response: ReceieveMessageResponse): Promise { @@ -335,24 +327,25 @@ export class Consumer extends EventEmitter { return; } + const pollBatchSize = Math.min(this.batchSize, this.freeConcurrentSlots); + debug('Polling for messages'); if (this.pollingStartedInstrumentCallback) { this.pollingStartedInstrumentCallback({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, - // instrument i am about to request this.batchSize messages - batchSize: this.batchSize + pollBatchSize }); } let currentPollingTimeout = this.pollingWaitTimeMs; - if (this.batchSize > 0) { + if (pollBatchSize > 0) { const receiveParams = { QueueUrl: this.queueUrl, AttributeNames: this.attributeNames, MessageAttributeNames: this.messageAttributeNames, - MaxNumberOfMessages: this.batchSize, + MaxNumberOfMessages: pollBatchSize, WaitTimeSeconds: this.waitTimeSeconds, VisibilityTimeout: this.visibilityTimeout }; @@ -374,7 +367,7 @@ export class Consumer extends EventEmitter { this.emit('error', err); }); } else { - setTimeout(this.poll, this.pollingWaitTimeMsBatchSizeZero); + setTimeout(this.poll, this.msDelayOnEmptyBatchSize); } } @@ -384,6 +377,39 @@ export class Consumer extends EventEmitter { }); this.reportNumberOfMessagesReceived(messages.length); - this.handleMessageBatch(messages, this); + const batchUuid = generateUuid(); + + if (this.batchStartedInstrumentCallBack) { + this.batchStartedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length + }); + } + + try { + await this.handleMessageBatch(messages, this); + + if (this.batchFinishedInstrumentCallBack) { + this.batchFinishedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length + }); + } + } catch (err) { + if (this.batchFailedInstrumentCallBack) { + this.batchFailedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length + }); + } + + throw err; + } } } From 4ccc15dae5ace9375a266636b2c887768b62a8b5 Mon Sep 17 00:00:00 2001 From: Ran Nir <> Date: Wed, 20 May 2020 14:24:13 +0300 Subject: [PATCH 17/40] increment minor version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 66108d85..3b067d27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.7", + "version": "5.7.8", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From b40b69df6fc93460a9d40aa30185ac21c340f356 Mon Sep 17 00:00:00 2001 From: Ran Nir <> Date: Wed, 20 May 2020 14:24:48 +0300 Subject: [PATCH 18/40] yarn build --- dist/consumer.d.ts | 18 +++++++----- dist/consumer.js | 73 +++++++++++++++++++++++++++++----------------- 2 files changed, 57 insertions(+), 34 deletions(-) diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts index fbbace79..d83f0881 100644 --- a/dist/consumer.d.ts +++ b/dist/consumer.d.ts @@ -6,13 +6,13 @@ export interface ConsumerOptions { attributeNames?: string[]; messageAttributeNames?: string[]; stopped?: boolean; - concurencyLimit?: number; + concurrencyLimit?: number; batchSize?: number; visibilityTimeout?: number; waitTimeSeconds?: number; authenticationErrorTimeout?: number; pollingWaitTimeMs?: number; - pollingWaitTimeMsBatchSizeZero?: number; + msDelayOnEmptyBatchSize?: number; terminateVisibilityTimeout?: boolean; sqs?: SQS; region?: string; @@ -21,7 +21,9 @@ export interface ConsumerOptions { handleMessageBatch?(messages: SQSMessage[], consumer: Consumer): Promise; pollingStartedInstrumentCallback?(eventData: object): void; pollingFinishedInstrumentCallback?(eventData: object): void; - batchSizeUpdatedInstrument?(eventData: object): void; + batchStartedInstrumentCallBack?(eventData: object): void; + batchFinishedInstrumentCallBack?(eventData: object): void; + batchFailedInstrumentCallBack?(eventData: object): void; } export declare class Consumer extends EventEmitter { private queueUrl; @@ -29,18 +31,21 @@ export declare class Consumer extends EventEmitter { private handleMessageBatch; private pollingStartedInstrumentCallback?; private pollingFinishedInstrumentCallback?; - private batchSizeUpdatedInstrument?; + private batchStartedInstrumentCallBack?; + private batchFinishedInstrumentCallBack?; + private batchFailedInstrumentCallBack?; private handleMessageTimeout; private attributeNames; private messageAttributeNames; private stopped; - private concurencyLimit; + private concurrencyLimit; + private freeConcurrentSlots; private batchSize; private visibilityTimeout; private waitTimeSeconds; private authenticationErrorTimeout; private pollingWaitTimeMs; - private pollingWaitTimeMsBatchSizeZero; + private msDelayOnEmptyBatchSize; private terminateVisibilityTimeout; private sqs; constructor(options: ConsumerOptions); @@ -50,7 +55,6 @@ export declare class Consumer extends EventEmitter { stop(): void; reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise; private reportNumberOfMessagesReceived; - private updateBatchSize; private handleSqsResponse; private processMessage; private receiveMessage; diff --git a/dist/consumer.js b/dist/consumer.js index 3c3f3faf..52d30dc5 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -2,6 +2,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const SQS = require("aws-sdk/clients/sqs"); const Debug = require("debug"); +const crypto = require("crypto"); const events_1 = require("events"); const bind_1 = require("./bind"); const errors_1 = require("./errors"); @@ -11,6 +12,9 @@ const requiredOptions = [ // only one of handleMessage / handleMessagesBatch is required 'handleMessage|handleMessageBatch' ]; +function generateUuid() { + return crypto.randomBytes(16).toString('hex'); +} function createTimeout(duration) { let timeout; const pending = new Promise((_, reject) => { @@ -67,19 +71,19 @@ class Consumer extends events_1.EventEmitter { this.handleMessageBatch = options.handleMessageBatch; this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; - this.batchSizeUpdatedInstrument = options.batchSizeUpdatedInstrument; this.handleMessageTimeout = options.handleMessageTimeout; this.attributeNames = options.attributeNames || []; this.messageAttributeNames = options.messageAttributeNames || []; this.stopped = true; this.batchSize = options.batchSize || 1; - this.concurencyLimit = options.concurencyLimit || 30; + this.concurrencyLimit = options.concurrencyLimit || 30; + this.freeConcurrentSlots = this.concurrencyLimit; this.visibilityTimeout = options.visibilityTimeout; this.terminateVisibilityTimeout = options.terminateVisibilityTimeout || false; this.waitTimeSeconds = options.waitTimeSeconds || 20; this.authenticationErrorTimeout = options.authenticationErrorTimeout || 10000; this.pollingWaitTimeMs = options.pollingWaitTimeMs || 0; - this.pollingWaitTimeMsBatchSizeZero = options.pollingWaitTimeMsBatchSizeZero || 5; + this.msDelayOnEmptyBatchSize = options.msDelayOnEmptyBatchSize || 5; this.sqs = options.sqs || new SQS({ @@ -106,8 +110,7 @@ class Consumer extends events_1.EventEmitter { } async reportMessageFromBatchFinished(message, error) { debug('Message from batch has finised'); - this.concurencyLimit++; - this.updateBatchSize(); + this.freeConcurrentSlots++; try { if (error) throw error; @@ -119,22 +122,8 @@ class Consumer extends events_1.EventEmitter { } } reportNumberOfMessagesReceived(numberOfMessages) { - debug('decrementing next batch size'); - this.concurencyLimit = this.concurencyLimit - numberOfMessages; - this.updateBatchSize(); - } - updateBatchSize() { - debug('Updating next batch size'); - this.batchSize = Math.min(10, this.concurencyLimit); - // instrument current batch size - if (this.batchSizeUpdatedInstrument) { - this.batchSizeUpdatedInstrument({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl, - currentConcurencyLimit: this.concurencyLimit, - batchSize: this.batchSize - }); - } + debug('Reducing number of messages received from freeConcurrentSlots'); + this.freeConcurrentSlots = this.freeConcurrentSlots - numberOfMessages; } async handleSqsResponse(response) { debug('Received SQS response'); @@ -256,22 +245,22 @@ class Consumer extends events_1.EventEmitter { this.emit('stopped'); return; } + const pollBatchSize = Math.min(this.batchSize, this.freeConcurrentSlots); debug('Polling for messages'); if (this.pollingStartedInstrumentCallback) { this.pollingStartedInstrumentCallback({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, - // instrument i am about to request this.batchSize messages - batchSize: this.batchSize + pollBatchSize }); } let currentPollingTimeout = this.pollingWaitTimeMs; - if (this.batchSize > 0) { + if (pollBatchSize > 0) { const receiveParams = { QueueUrl: this.queueUrl, AttributeNames: this.attributeNames, MessageAttributeNames: this.messageAttributeNames, - MaxNumberOfMessages: this.batchSize, + MaxNumberOfMessages: pollBatchSize, WaitTimeSeconds: this.waitTimeSeconds, VisibilityTimeout: this.visibilityTimeout }; @@ -293,7 +282,7 @@ class Consumer extends events_1.EventEmitter { }); } else { - setTimeout(this.poll, this.pollingWaitTimeMsBatchSizeZero); + setTimeout(this.poll, this.msDelayOnEmptyBatchSize); } } async processMessageBatch(messages) { @@ -301,7 +290,37 @@ class Consumer extends events_1.EventEmitter { this.emit('message_received', message); }); this.reportNumberOfMessagesReceived(messages.length); - this.handleMessageBatch(messages, this); + const batchUuid = generateUuid(); + if (this.batchStartedInstrumentCallBack) { + this.batchStartedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length + }); + } + try { + await this.handleMessageBatch(messages, this); + if (this.batchFinishedInstrumentCallBack) { + this.batchFinishedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length + }); + } + } + catch (err) { + if (this.batchFailedInstrumentCallBack) { + this.batchFailedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length + }); + } + throw err; + } } } exports.Consumer = Consumer; From 2e8c900201a4adaa4d7f7216845ff59506a33528 Mon Sep 17 00:00:00 2001 From: Ran Nir <> Date: Wed, 20 May 2020 17:35:55 +0300 Subject: [PATCH 19/40] addition of data in instrumentation and version upgrade --- dist/consumer.js | 30 +++++++++++++++--------- package.json | 2 +- src/consumer.ts | 59 +++++++++++++++++++++++++++--------------------- 3 files changed, 53 insertions(+), 38 deletions(-) diff --git a/dist/consumer.js b/dist/consumer.js index 52d30dc5..ee0e4a47 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -71,6 +71,9 @@ class Consumer extends events_1.EventEmitter { this.handleMessageBatch = options.handleMessageBatch; this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; + this.batchStartedInstrumentCallBack = options.batchStartedInstrumentCallBack; + this.batchFinishedInstrumentCallBack = options.batchFinishedInstrumentCallBack; + this.batchFailedInstrumentCallBack = options.batchFailedInstrumentCallBack; this.handleMessageTimeout = options.handleMessageTimeout; this.attributeNames = options.attributeNames || []; this.messageAttributeNames = options.messageAttributeNames || []; @@ -135,7 +138,8 @@ class Consumer extends events_1.EventEmitter { this.pollingFinishedInstrumentCallback({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, - messagesReceived: numberOfMessages + messagesReceived: numberOfMessages, + freeConcurrentSlots: this.freeConcurrentSlots }); } if (response) { @@ -251,7 +255,8 @@ class Consumer extends events_1.EventEmitter { this.pollingStartedInstrumentCallback({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, - pollBatchSize + pollBatchSize, + freeConcurrentSlots: this.freeConcurrentSlots }); } let currentPollingTimeout = this.pollingWaitTimeMs; @@ -296,31 +301,34 @@ class Consumer extends events_1.EventEmitter { instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, batchUuid, - numberOfMessages: messages.length + numberOfMessages: messages.length, + freeConcurrentSlots: this.freeConcurrentSlots }); } - try { - await this.handleMessageBatch(messages, this); + this.handleMessageBatch(messages, this) + .then(() => { if (this.batchFinishedInstrumentCallBack) { this.batchFinishedInstrumentCallBack({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, batchUuid, - numberOfMessages: messages.length + numberOfMessages: messages.length, + freeConcurrentSlots: this.freeConcurrentSlots }); } - } - catch (err) { + }) + .catch(err => { if (this.batchFailedInstrumentCallBack) { this.batchFailedInstrumentCallBack({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, batchUuid, - numberOfMessages: messages.length + numberOfMessages: messages.length, + freeConcurrentSlots: this.freeConcurrentSlots, + error: err }); } - throw err; - } + }); } } exports.Consumer = Consumer; diff --git a/package.json b/package.json index 3b067d27..f59ca405 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.8", + "version": "5.7.81", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/consumer.ts b/src/consumer.ts index a7777516..8b71bbf5 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -140,6 +140,9 @@ export class Consumer extends EventEmitter { this.handleMessageBatch = options.handleMessageBatch; this.pollingStartedInstrumentCallback = options.pollingStartedInstrumentCallback; this.pollingFinishedInstrumentCallback = options.pollingFinishedInstrumentCallback; + this.batchStartedInstrumentCallBack = options.batchStartedInstrumentCallBack; + this.batchFinishedInstrumentCallBack = options.batchFinishedInstrumentCallBack; + this.batchFailedInstrumentCallBack = options.batchFailedInstrumentCallBack; this.handleMessageTimeout = options.handleMessageTimeout; this.attributeNames = options.attributeNames || []; this.messageAttributeNames = options.messageAttributeNames || []; @@ -216,7 +219,8 @@ export class Consumer extends EventEmitter { this.pollingFinishedInstrumentCallback({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, - messagesReceived: numberOfMessages + messagesReceived: numberOfMessages, + freeConcurrentSlots: this.freeConcurrentSlots }); } @@ -334,7 +338,8 @@ export class Consumer extends EventEmitter { this.pollingStartedInstrumentCallback({ instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, - pollBatchSize + pollBatchSize, + freeConcurrentSlots: this.freeConcurrentSlots }); } @@ -384,32 +389,34 @@ export class Consumer extends EventEmitter { instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, batchUuid, - numberOfMessages: messages.length + numberOfMessages: messages.length, + freeConcurrentSlots: this.freeConcurrentSlots }); } - try { - await this.handleMessageBatch(messages, this); - - if (this.batchFinishedInstrumentCallBack) { - this.batchFinishedInstrumentCallBack({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl, - batchUuid, - numberOfMessages: messages.length - }); - } - } catch (err) { - if (this.batchFailedInstrumentCallBack) { - this.batchFailedInstrumentCallBack({ - instanceId: process.env.HOSTNAME, - queueUrl: this.queueUrl, - batchUuid, - numberOfMessages: messages.length - }); - } - - throw err; - } + this.handleMessageBatch(messages, this) + .then(() => { + if (this.batchFinishedInstrumentCallBack) { + this.batchFinishedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length, + freeConcurrentSlots: this.freeConcurrentSlots + }); + } + }) + .catch(err => { + if (this.batchFailedInstrumentCallBack) { + this.batchFailedInstrumentCallBack({ + instanceId: process.env.HOSTNAME, + queueUrl: this.queueUrl, + batchUuid, + numberOfMessages: messages.length, + freeConcurrentSlots: this.freeConcurrentSlots, + error: err + }); + } + }); } } From 57c2e17466be1bf6356ca4f09fa1edc8803583db Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Thu, 24 Mar 2022 10:15:57 +0200 Subject: [PATCH 20/40] add setters for concurrency props --- dist/consumer.d.ts | 2 ++ dist/consumer.js | 41 +++++++++++++++++++++++++---------------- package-lock.json | 2 +- package.json | 2 +- src/consumer.ts | 44 ++++++++++++++++++++++++++++---------------- 5 files changed, 57 insertions(+), 34 deletions(-) diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts index d83f0881..90e1aa09 100644 --- a/dist/consumer.d.ts +++ b/dist/consumer.d.ts @@ -53,6 +53,8 @@ export declare class Consumer extends EventEmitter { static create(options: ConsumerOptions): Consumer; start(): void; stop(): void; + setBatchSize(newBatchSize: number): void; + setConcurrencyLimit(newConcurrencyLimit: number): void; reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise; private reportNumberOfMessagesReceived; private handleSqsResponse; diff --git a/dist/consumer.js b/dist/consumer.js index ee0e4a47..234b977f 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -10,7 +10,7 @@ const debug = Debug('sqs-consumer'); const requiredOptions = [ 'queueUrl', // only one of handleMessage / handleMessagesBatch is required - 'handleMessage|handleMessageBatch' + 'handleMessage|handleMessageBatch', ]; function generateUuid() { return crypto.randomBytes(16).toString('hex'); @@ -25,9 +25,9 @@ function createTimeout(duration) { return [timeout, pending]; } function assertOptions(options) { - requiredOptions.forEach(option => { + requiredOptions.forEach((option) => { const possibilities = option.split('|'); - if (!possibilities.find(p => options[p])) { + if (!possibilities.find((p) => options[p])) { throw new Error(`Missing SQS consumer option [ ${possibilities.join(' or ')} ].`); } }); @@ -90,7 +90,7 @@ class Consumer extends events_1.EventEmitter { this.sqs = options.sqs || new SQS({ - region: options.region || process.env.AWS_REGION || 'eu-west-1' + region: options.region || process.env.AWS_REGION || 'eu-west-1', }); bind_1.autoBind(this); } @@ -111,6 +111,15 @@ class Consumer extends events_1.EventEmitter { debug('Stopping consumer'); this.stopped = true; } + setBatchSize(newBatchSize) { + this.batchSize = newBatchSize; + } + setConcurrencyLimit(newConcurrencyLimit) { + const concurrencyLimitDiff = newConcurrencyLimit - this.concurrencyLimit; + const newFreeConcurrentSlots = Math.max(0, this.freeConcurrentSlots + concurrencyLimitDiff); + this.concurrencyLimit = newConcurrencyLimit; + this.freeConcurrentSlots = newFreeConcurrentSlots; + } async reportMessageFromBatchFinished(message, error) { debug('Message from batch has finised'); this.freeConcurrentSlots++; @@ -139,7 +148,7 @@ class Consumer extends events_1.EventEmitter { instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, messagesReceived: numberOfMessages, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } if (response) { @@ -189,7 +198,7 @@ class Consumer extends events_1.EventEmitter { debug('Deleting message %s', message.MessageId); const deleteParams = { QueueUrl: this.queueUrl, - ReceiptHandle: message.ReceiptHandle + ReceiptHandle: message.ReceiptHandle, }; try { await this.sqs.deleteMessage(deleteParams).promise(); @@ -229,7 +238,7 @@ class Consumer extends events_1.EventEmitter { .changeMessageVisibility({ QueueUrl: this.queueUrl, ReceiptHandle: message.ReceiptHandle, - VisibilityTimeout: 0 + VisibilityTimeout: 0, }) .promise(); } @@ -256,7 +265,7 @@ class Consumer extends events_1.EventEmitter { instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, pollBatchSize, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } let currentPollingTimeout = this.pollingWaitTimeMs; @@ -267,11 +276,11 @@ class Consumer extends events_1.EventEmitter { MessageAttributeNames: this.messageAttributeNames, MaxNumberOfMessages: pollBatchSize, WaitTimeSeconds: this.waitTimeSeconds, - VisibilityTimeout: this.visibilityTimeout + VisibilityTimeout: this.visibilityTimeout, }; this.receiveMessage(receiveParams) .then(this.handleSqsResponse) - .catch(err => { + .catch((err) => { this.emit('error', err); if (isConnectionError(err)) { debug('There was an authentication error. Pausing before retrying.'); @@ -282,7 +291,7 @@ class Consumer extends events_1.EventEmitter { .then(() => { setTimeout(this.poll, currentPollingTimeout); }) - .catch(err => { + .catch((err) => { this.emit('error', err); }); } @@ -291,7 +300,7 @@ class Consumer extends events_1.EventEmitter { } } async processMessageBatch(messages) { - messages.forEach(message => { + messages.forEach((message) => { this.emit('message_received', message); }); this.reportNumberOfMessagesReceived(messages.length); @@ -302,7 +311,7 @@ class Consumer extends events_1.EventEmitter { queueUrl: this.queueUrl, batchUuid, numberOfMessages: messages.length, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } this.handleMessageBatch(messages, this) @@ -313,11 +322,11 @@ class Consumer extends events_1.EventEmitter { queueUrl: this.queueUrl, batchUuid, numberOfMessages: messages.length, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } }) - .catch(err => { + .catch((err) => { if (this.batchFailedInstrumentCallBack) { this.batchFailedInstrumentCallBack({ instanceId: process.env.HOSTNAME, @@ -325,7 +334,7 @@ class Consumer extends events_1.EventEmitter { batchUuid, numberOfMessages: messages.length, freeConcurrentSlots: this.freeConcurrentSlots, - error: err + error: err, }); } }); diff --git a/package-lock.json b/package-lock.json index ff655a7f..883c2cc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.3", + "version": "5.7.81", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f59ca405..d2d53ac5 100644 --- a/package.json +++ b/package.json @@ -66,4 +66,4 @@ "sourceMap": true, "instrument": true } -} \ No newline at end of file +} diff --git a/src/consumer.ts b/src/consumer.ts index 8b71bbf5..47c85b5f 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -16,7 +16,7 @@ type ReceiveMessageRequest = SQS.Types.ReceiveMessageRequest; const requiredOptions = [ 'queueUrl', // only one of handleMessage / handleMessagesBatch is required - 'handleMessage|handleMessageBatch' + 'handleMessage|handleMessageBatch', ]; interface TimeoutResponse { @@ -39,9 +39,9 @@ function createTimeout(duration: number): TimeoutResponse[] { } function assertOptions(options: ConsumerOptions): void { - requiredOptions.forEach(option => { + requiredOptions.forEach((option) => { const possibilities = option.split('|'); - if (!possibilities.find(p => options[p])) { + if (!possibilities.find((p) => options[p])) { throw new Error(`Missing SQS consumer option [ ${possibilities.join(' or ')} ].`); } }); @@ -160,7 +160,7 @@ export class Consumer extends EventEmitter { this.sqs = options.sqs || new SQS({ - region: options.region || process.env.AWS_REGION || 'eu-west-1' + region: options.region || process.env.AWS_REGION || 'eu-west-1', }); autoBind(this); @@ -187,6 +187,18 @@ export class Consumer extends EventEmitter { this.stopped = true; } + public setBatchSize(newBatchSize: number): void { + this.batchSize = newBatchSize; + } + + public setConcurrencyLimit(newConcurrencyLimit: number): void { + const concurrencyLimitDiff = newConcurrencyLimit - this.concurrencyLimit; + const newFreeConcurrentSlots = Math.max(0, this.freeConcurrentSlots + concurrencyLimitDiff); + + this.concurrencyLimit = newConcurrencyLimit; + this.freeConcurrentSlots = newFreeConcurrentSlots; + } + public async reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise { debug('Message from batch has finised'); @@ -220,7 +232,7 @@ export class Consumer extends EventEmitter { instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, messagesReceived: numberOfMessages, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } @@ -272,7 +284,7 @@ export class Consumer extends EventEmitter { const deleteParams = { QueueUrl: this.queueUrl, - ReceiptHandle: message.ReceiptHandle + ReceiptHandle: message.ReceiptHandle, }; try { @@ -310,7 +322,7 @@ export class Consumer extends EventEmitter { .changeMessageVisibility({ QueueUrl: this.queueUrl, ReceiptHandle: message.ReceiptHandle, - VisibilityTimeout: 0 + VisibilityTimeout: 0, }) .promise(); } @@ -339,7 +351,7 @@ export class Consumer extends EventEmitter { instanceId: process.env.HOSTNAME, queueUrl: this.queueUrl, pollBatchSize, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } @@ -352,12 +364,12 @@ export class Consumer extends EventEmitter { MessageAttributeNames: this.messageAttributeNames, MaxNumberOfMessages: pollBatchSize, WaitTimeSeconds: this.waitTimeSeconds, - VisibilityTimeout: this.visibilityTimeout + VisibilityTimeout: this.visibilityTimeout, }; this.receiveMessage(receiveParams) .then(this.handleSqsResponse) - .catch(err => { + .catch((err) => { this.emit('error', err); if (isConnectionError(err)) { debug('There was an authentication error. Pausing before retrying.'); @@ -368,7 +380,7 @@ export class Consumer extends EventEmitter { .then(() => { setTimeout(this.poll, currentPollingTimeout); }) - .catch(err => { + .catch((err) => { this.emit('error', err); }); } else { @@ -377,7 +389,7 @@ export class Consumer extends EventEmitter { } private async processMessageBatch(messages: SQSMessage[]): Promise { - messages.forEach(message => { + messages.forEach((message) => { this.emit('message_received', message); }); @@ -390,7 +402,7 @@ export class Consumer extends EventEmitter { queueUrl: this.queueUrl, batchUuid, numberOfMessages: messages.length, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } @@ -402,11 +414,11 @@ export class Consumer extends EventEmitter { queueUrl: this.queueUrl, batchUuid, numberOfMessages: messages.length, - freeConcurrentSlots: this.freeConcurrentSlots + freeConcurrentSlots: this.freeConcurrentSlots, }); } }) - .catch(err => { + .catch((err) => { if (this.batchFailedInstrumentCallBack) { this.batchFailedInstrumentCallBack({ instanceId: process.env.HOSTNAME, @@ -414,7 +426,7 @@ export class Consumer extends EventEmitter { batchUuid, numberOfMessages: messages.length, freeConcurrentSlots: this.freeConcurrentSlots, - error: err + error: err, }); } }); From e75309ddeaae0b269ceb9105c6eb0912f066c89a Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Thu, 24 Mar 2022 10:56:11 +0200 Subject: [PATCH 21/40] check non existent queue error and throw --- dist/consumer.js | 9 +++++++++ src/consumer.ts | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/dist/consumer.js b/dist/consumer.js index 234b977f..c34d8195 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -41,6 +41,12 @@ function isConnectionError(err) { } return false; } +function isNonExistentQueueError(err) { + if (err instanceof errors_1.SQSError) { + return err.code === 'AWS.SimpleQueueService.NonExistentQueue'; + } + return false; +} function toSQSError(err, message) { const sqsError = new errors_1.SQSError(message); sqsError.code = err.code; @@ -282,6 +288,9 @@ class Consumer extends events_1.EventEmitter { .then(this.handleSqsResponse) .catch((err) => { this.emit('error', err); + if (isNonExistentQueueError(err)) { + throw new Error(`Could not receive messages - non existent queue - ${this.queueUrl}`); + } if (isConnectionError(err)) { debug('There was an authentication error. Pausing before retrying.'); currentPollingTimeout = this.authenticationErrorTimeout; diff --git a/src/consumer.ts b/src/consumer.ts index 47c85b5f..5079938a 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -58,6 +58,14 @@ function isConnectionError(err: Error): Boolean { return false; } +function isNonExistentQueueError(err: Error): Boolean { + if (err instanceof SQSError) { + return err.code === 'AWS.SimpleQueueService.NonExistentQueue'; + } + + return false; +} + function toSQSError(err: AWSError, message: string): SQSError { const sqsError = new SQSError(message); sqsError.code = err.code; @@ -371,10 +379,14 @@ export class Consumer extends EventEmitter { .then(this.handleSqsResponse) .catch((err) => { this.emit('error', err); + if (isNonExistentQueueError(err)) { + throw new Error(`Could not receive messages - non existent queue - ${this.queueUrl}`); + } if (isConnectionError(err)) { debug('There was an authentication error. Pausing before retrying.'); currentPollingTimeout = this.authenticationErrorTimeout; } + return; }) .then(() => { From 4d4eca76faba7dbed3f83d5f28eb88c07abd4804 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Thu, 24 Mar 2022 12:21:40 +0200 Subject: [PATCH 22/40] bump version --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 883c2cc3..20b9e5ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.81", + "version": "5.8.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index d2d53ac5..260eb49d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.7.81", + "version": "5.8.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 2b2b49e6b441ec1d4d36c86ed8b1520d04e892bd Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 10 Apr 2022 09:26:02 +0300 Subject: [PATCH 23/40] add queue url to error events --- dist/consumer.js | 12 ++++++------ src/consumer.ts | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dist/consumer.js b/dist/consumer.js index c34d8195..c579da16 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -187,7 +187,7 @@ class Consumer extends events_1.EventEmitter { await this.terminateVisabilityTimeout(message); } catch (err) { - this.emit('error', err, message); + this.emit('error', err, message, this.queueUrl); } } } @@ -250,13 +250,13 @@ class Consumer extends events_1.EventEmitter { } emitError(err, message) { if (err.name === errors_1.SQSError.name) { - this.emit('error', err, message); + this.emit('error', err, message, this.queueUrl); } else if (err instanceof errors_1.TimeoutError) { - this.emit('timeout_error', err, message); + this.emit('timeout_error', err, message, this.queueUrl); } else { - this.emit('processing_error', err, message); + this.emit('processing_error', err, message, this.queueUrl); } } poll() { @@ -287,7 +287,7 @@ class Consumer extends events_1.EventEmitter { this.receiveMessage(receiveParams) .then(this.handleSqsResponse) .catch((err) => { - this.emit('error', err); + this.emit('unhandled_error', err, this.queueUrl); if (isNonExistentQueueError(err)) { throw new Error(`Could not receive messages - non existent queue - ${this.queueUrl}`); } @@ -301,7 +301,7 @@ class Consumer extends events_1.EventEmitter { setTimeout(this.poll, currentPollingTimeout); }) .catch((err) => { - this.emit('error', err); + this.emit('unhandled_error', err, this.queueUrl); }); } else { diff --git a/src/consumer.ts b/src/consumer.ts index 5079938a..23f2c9e1 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -273,7 +273,7 @@ export class Consumer extends EventEmitter { try { await this.terminateVisabilityTimeout(message); } catch (err) { - this.emit('error', err, message); + this.emit('error', err, message, this.queueUrl); } } } @@ -337,11 +337,11 @@ export class Consumer extends EventEmitter { private emitError(err: Error, message: SQSMessage): void { if (err.name === SQSError.name) { - this.emit('error', err, message); + this.emit('error', err, message, this.queueUrl); } else if (err instanceof TimeoutError) { - this.emit('timeout_error', err, message); + this.emit('timeout_error', err, message, this.queueUrl); } else { - this.emit('processing_error', err, message); + this.emit('processing_error', err, message, this.queueUrl); } } @@ -378,7 +378,7 @@ export class Consumer extends EventEmitter { this.receiveMessage(receiveParams) .then(this.handleSqsResponse) .catch((err) => { - this.emit('error', err); + this.emit('unhandled_error', err, this.queueUrl); if (isNonExistentQueueError(err)) { throw new Error(`Could not receive messages - non existent queue - ${this.queueUrl}`); } @@ -393,7 +393,7 @@ export class Consumer extends EventEmitter { setTimeout(this.poll, currentPollingTimeout); }) .catch((err) => { - this.emit('error', err); + this.emit('unhandled_error', err, this.queueUrl); }); } else { setTimeout(this.poll, this.msDelayOnEmptyBatchSize); From b604213251b44145578ba5c8eaf0f53048e22a68 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 10 Apr 2022 09:27:56 +0300 Subject: [PATCH 24/40] bump major version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 260eb49d..fec25681 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.8.0", + "version": "6.0.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 647e2a2f64a3078c8a46857a245a822617b39775 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 10 Apr 2022 12:03:10 +0300 Subject: [PATCH 25/40] add queueUrl to all emitted events data --- dist/consumer.js | 16 ++++++++-------- src/consumer.ts | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dist/consumer.js b/dist/consumer.js index c579da16..2f4ff975 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -127,13 +127,13 @@ class Consumer extends events_1.EventEmitter { this.freeConcurrentSlots = newFreeConcurrentSlots; } async reportMessageFromBatchFinished(message, error) { - debug('Message from batch has finised'); + debug('Message from batch has finished'); this.freeConcurrentSlots++; try { if (error) throw error; await this.deleteMessage(message); - this.emit('message_processed', message); + this.emit('message_processed', message, this.queueUrl); } catch (err) { this.emitError(err, message); @@ -166,19 +166,19 @@ class Consumer extends events_1.EventEmitter { else { await Promise.all(response.Messages.map(this.processMessage)); } - this.emit('response_processed'); + this.emit('response_processed', this.queueUrl); } else { - this.emit('empty'); + this.emit('empty', this.queueUrl); } } } async processMessage(message) { - this.emit('message_received', message); + this.emit('message_received', message, this.queueUrl); try { await this.executeHandler(message); await this.deleteMessage(message); - this.emit('message_processed', message); + this.emit('message_processed', message, this.queueUrl); } catch (err) { this.emitError(err, message); @@ -261,7 +261,7 @@ class Consumer extends events_1.EventEmitter { } poll() { if (this.stopped) { - this.emit('stopped'); + this.emit('stopped', this.queueUrl); return; } const pollBatchSize = Math.min(this.batchSize, this.freeConcurrentSlots); @@ -310,7 +310,7 @@ class Consumer extends events_1.EventEmitter { } async processMessageBatch(messages) { messages.forEach((message) => { - this.emit('message_received', message); + this.emit('message_received', message, this.queueUrl); }); this.reportNumberOfMessagesReceived(messages.length); const batchUuid = generateUuid(); diff --git a/src/consumer.ts b/src/consumer.ts index 23f2c9e1..ed7705d4 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -208,7 +208,7 @@ export class Consumer extends EventEmitter { } public async reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise { - debug('Message from batch has finised'); + debug('Message from batch has finished'); this.freeConcurrentSlots++; @@ -216,7 +216,7 @@ export class Consumer extends EventEmitter { if (error) throw error; await this.deleteMessage(message); - this.emit('message_processed', message); + this.emit('message_processed', message, this.queueUrl); } catch (err) { this.emitError(err, message); } @@ -252,20 +252,20 @@ export class Consumer extends EventEmitter { } else { await Promise.all(response.Messages.map(this.processMessage)); } - this.emit('response_processed'); + this.emit('response_processed', this.queueUrl); } else { - this.emit('empty'); + this.emit('empty', this.queueUrl); } } } private async processMessage(message: SQSMessage): Promise { - this.emit('message_received', message); + this.emit('message_received', message, this.queueUrl); try { await this.executeHandler(message); await this.deleteMessage(message); - this.emit('message_processed', message); + this.emit('message_processed', message, this.queueUrl); } catch (err) { this.emitError(err, message); @@ -347,7 +347,7 @@ export class Consumer extends EventEmitter { private poll(): void { if (this.stopped) { - this.emit('stopped'); + this.emit('stopped', this.queueUrl); return; } @@ -402,7 +402,7 @@ export class Consumer extends EventEmitter { private async processMessageBatch(messages: SQSMessage[]): Promise { messages.forEach((message) => { - this.emit('message_received', message); + this.emit('message_received', message, this.queueUrl); }); this.reportNumberOfMessagesReceived(messages.length); From f8fac8fb8e8f2cd822449c99fb6013e2d358e5cc Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Sun, 10 Apr 2022 12:04:40 +0300 Subject: [PATCH 26/40] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fec25681..e4bcabdf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "6.0.0", + "version": "6.1.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 737c0750d59f630850010be4650f8108d8c0f4d3 Mon Sep 17 00:00:00 2001 From: Moshik Eilon Date: Tue, 19 Apr 2022 15:13:58 +0300 Subject: [PATCH 27/40] add setter to polling wait time ms --- dist/consumer.d.ts | 1 + dist/consumer.js | 3 +++ package-lock.json | 2 +- package.json | 2 +- src/consumer.ts | 4 ++++ 5 files changed, 10 insertions(+), 2 deletions(-) diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts index 90e1aa09..4493e4b2 100644 --- a/dist/consumer.d.ts +++ b/dist/consumer.d.ts @@ -55,6 +55,7 @@ export declare class Consumer extends EventEmitter { stop(): void; setBatchSize(newBatchSize: number): void; setConcurrencyLimit(newConcurrencyLimit: number): void; + setPollingWaitTimeMs(newPollingWaitTimeMs: number): void; reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise; private reportNumberOfMessagesReceived; private handleSqsResponse; diff --git a/dist/consumer.js b/dist/consumer.js index 2f4ff975..b7dfe4eb 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -126,6 +126,9 @@ class Consumer extends events_1.EventEmitter { this.concurrencyLimit = newConcurrencyLimit; this.freeConcurrentSlots = newFreeConcurrentSlots; } + setPollingWaitTimeMs(newPollingWaitTimeMs) { + this.pollingWaitTimeMs = newPollingWaitTimeMs; + } async reportMessageFromBatchFinished(message, error) { debug('Message from batch has finished'); this.freeConcurrentSlots++; diff --git a/package-lock.json b/package-lock.json index 20b9e5ec..639fbc60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "5.8.0", + "version": "6.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index e4bcabdf..3b983e1e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "6.1.0", + "version": "6.2.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/consumer.ts b/src/consumer.ts index ed7705d4..df7d7ca3 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -207,6 +207,10 @@ export class Consumer extends EventEmitter { this.freeConcurrentSlots = newFreeConcurrentSlots; } + public setPollingWaitTimeMs(newPollingWaitTimeMs: number): void { + this.pollingWaitTimeMs = newPollingWaitTimeMs; + } + public async reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise { debug('Message from batch has finished'); From f995fc7a63a1c8f119ec932f1d4815e3181d6dc4 Mon Sep 17 00:00:00 2001 From: shaikatzz <139782053+shaikatzz@users.noreply.github.com> Date: Thu, 20 Jun 2024 11:41:09 +0300 Subject: [PATCH 28/40] Pin aws-sdk to 2.1547.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b983e1e..21b5abaa 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "typescript": "^2.6.1" }, "dependencies": { - "aws-sdk": "^2.443.0", + "aws-sdk": "2.1547.0", "debug": "^4.1.1" }, "nyc": { From 0b2eed7981a142a3dbc2c4149e434bd01b22c4c4 Mon Sep 17 00:00:00 2001 From: shaikatzz <139782053+shaikatzz@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:00:46 +0300 Subject: [PATCH 29/40] aws-sdk pin to 2.1491.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 21b5abaa..05c086b3 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "typescript": "^2.6.1" }, "dependencies": { - "aws-sdk": "2.1547.0", + "aws-sdk": "2.1491.0", "debug": "^4.1.1" }, "nyc": { From 3467030ac52a4f90845d6504ffd64ecc86dd9523 Mon Sep 17 00:00:00 2001 From: shaikatzz <139782053+shaikatzz@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:05:45 +0300 Subject: [PATCH 30/40] aws-sdk pin to 2.1490.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 05c086b3..b7e8e705 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "typescript": "^2.6.1" }, "dependencies": { - "aws-sdk": "2.1491.0", + "aws-sdk": "2.1490.0", "debug": "^4.1.1" }, "nyc": { From 78c63451566485a7a23fb6d45c559e0c948464cf Mon Sep 17 00:00:00 2001 From: Goral Tahan Date: Thu, 22 Aug 2024 15:57:46 +0300 Subject: [PATCH 31/40] make error optional --- src/consumer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/consumer.ts b/src/consumer.ts index df7d7ca3..2c0973f3 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -211,7 +211,7 @@ export class Consumer extends EventEmitter { this.pollingWaitTimeMs = newPollingWaitTimeMs; } - public async reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise { + public async reportMessageFromBatchFinished(message: SQSMessage, error?: Error): Promise { debug('Message from batch has finished'); this.freeConcurrentSlots++; From ecfa7f7a4037601d4a5786b929210f5806d88bb2 Mon Sep 17 00:00:00 2001 From: Goral Tahan Date: Sun, 25 Aug 2024 09:58:42 +0300 Subject: [PATCH 32/40] update d.js file --- dist/consumer.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts index 4493e4b2..838233ef 100644 --- a/dist/consumer.d.ts +++ b/dist/consumer.d.ts @@ -56,7 +56,7 @@ export declare class Consumer extends EventEmitter { setBatchSize(newBatchSize: number): void; setConcurrencyLimit(newConcurrencyLimit: number): void; setPollingWaitTimeMs(newPollingWaitTimeMs: number): void; - reportMessageFromBatchFinished(message: SQSMessage, error: Error): Promise; + reportMessageFromBatchFinished(message: SQSMessage, error?: Error): Promise; private reportNumberOfMessagesReceived; private handleSqsResponse; private processMessage; From e76011566ac36afcaa18e37e25718b745e2e6311 Mon Sep 17 00:00:00 2001 From: shaikatzz <139782053+shaikatzz@users.noreply.github.com> Date: Sun, 15 Dec 2024 10:04:21 +0200 Subject: [PATCH 33/40] use aws-sdk 2.1489.0 packages in monday uses that version, so prevent installing aws-sdk multiple times by downgrading it to the same version. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b7e8e705..31cd825f 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "typescript": "^2.6.1" }, "dependencies": { - "aws-sdk": "2.1490.0", + "aws-sdk": "2.1489.0", "debug": "^4.1.1" }, "nyc": { From 706f8737277045f7af7f00125333126d4883ec1b Mon Sep 17 00:00:00 2001 From: shaikatzz <139782053+shaikatzz@users.noreply.github.com> Date: Sun, 15 Dec 2024 10:34:29 +0200 Subject: [PATCH 34/40] Update package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 31cd825f..aa8fe7af 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "6.2.0", + "version": "6.3.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From b346a6a5e80b930cc3ea284f77934d5ece012a8b Mon Sep 17 00:00:00 2001 From: Shai Katz Date: Sun, 26 Jan 2025 16:15:56 +0200 Subject: [PATCH 35/40] Report concurrency slots updated --- package-lock.json | 2391 +++++++++++++++++++++++++++++++-------------- src/consumer.ts | 3 + 2 files changed, 1673 insertions(+), 721 deletions(-) diff --git a/package-lock.json b/package-lock.json index 639fbc60..de3db453 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,24 +1,52 @@ { "name": "sqs-consumer", "version": "6.2.0", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "sqs-consumer", + "version": "6.2.0", + "license": "Apache-2.0", + "dependencies": { + "aws-sdk": "2.1490.0", + "debug": "^4.1.1" + }, + "devDependencies": { + "@types/chai": "^4.1.4", + "@types/debug": "^4.1.3", + "@types/mocha": "^2.2.43", + "@types/node": "^10.12.18", + "@types/sinon": "^4.0.0", + "@types/typescript": "^2.0.0", + "chai": "^4.2.0", + "codeclimate-test-reporter": "^0.5.1", + "mocha": "^5.2.0", + "nyc": "^14.1.1", + "p-event": "^2.1.0", + "sinon": "^7.2.2", + "ts-node": "^3.3.0", + "tslint": "^5.17.0", + "tslint-config-airbnb": "^5.3.1", + "tslint-microsoft-contrib": "^5.0.3", + "typescript": "^2.6.1" + } + }, + "node_modules/@babel/code-frame": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", "dev": true, - "requires": { + "dependencies": { "@babel/highlight": "^7.0.0" } }, - "@babel/generator": { + "node_modules/@babel/generator": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.4.4", "jsesc": "^2.5.1", "lodash": "^4.17.11", @@ -26,69 +54,75 @@ "trim-right": "^1.0.1" } }, - "@babel/helper-function-name": { + "node_modules/@babel/helper-function-name": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", "dev": true, - "requires": { + "dependencies": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" } }, - "@babel/helper-get-function-arity": { + "node_modules/@babel/helper-get-function-arity": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.0.0" } }, - "@babel/helper-split-export-declaration": { + "node_modules/@babel/helper-split-export-declaration": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "dev": true, - "requires": { + "dependencies": { "@babel/types": "^7.4.4" } }, - "@babel/highlight": { + "node_modules/@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", "dev": true, - "requires": { + "dependencies": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, - "@babel/parser": { + "node_modules/@babel/parser": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", - "dev": true + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } }, - "@babel/template": { + "node_modules/@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.4.4", "@babel/types": "^7.4.4" } }, - "@babel/traverse": { + "node_modules/@babel/traverse": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.4", "@babel/helper-function-name": "^7.1.0", @@ -100,602 +134,849 @@ "lodash": "^4.17.11" } }, - "@babel/types": { + "node_modules/@babel/types": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", "dev": true, - "requires": { + "dependencies": { "esutils": "^2.0.2", "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" } }, - "@fimbul/bifrost": { + "node_modules/@fimbul/bifrost": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/@fimbul/bifrost/-/bifrost-0.17.0.tgz", "integrity": "sha512-gVTkJAOef5HtN6LPmrtt5fAUmBywwlgmObsU3FBhPoNeXPLaIl2zywXkJEtvvVLQnaFmtff3x+wIj5lHRCDE3Q==", "dev": true, - "requires": { + "dependencies": { "@fimbul/ymir": "^0.17.0", "get-caller-file": "^2.0.0", "tslib": "^1.8.1", "tsutils": "^3.5.0" }, + "peerDependencies": { + "tslint": "^5.0.0", + "typescript": ">= 3.0.1 || >= 3.3.0-dev || >= 3.4.0-dev" + } + }, + "node_modules/@fimbul/bifrost/node_modules/tsutils": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.8.0.tgz", + "integrity": "sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA==", + "dev": true, "dependencies": { - "tsutils": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.8.0.tgz", - "integrity": "sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev" } }, - "@fimbul/ymir": { + "node_modules/@fimbul/ymir": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/@fimbul/ymir/-/ymir-0.17.0.tgz", "integrity": "sha512-xMXM9KTXRLHLVS6dnX1JhHNEkmWHcAVCQ/4+DA1KKwC/AFnGHzu/7QfQttEPgw3xplT+ILf9e3i64jrFwB3JtA==", "dev": true, - "requires": { + "dependencies": { "inversify": "^5.0.0", "reflect-metadata": "^0.1.12", "tslib": "^1.8.1" + }, + "peerDependencies": { + "tsutils": ">=2.29.0", + "typescript": ">= 3.0.1 || >= 3.3.0-dev || >= 3.4.0-dev" } }, - "@sinonjs/commons": { + "node_modules/@sinonjs/commons": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", "dev": true, - "requires": { + "dependencies": { "type-detect": "4.0.8" } }, - "@sinonjs/formatio": { + "node_modules/@sinonjs/formatio": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", "dev": true, - "requires": { + "dependencies": { "@sinonjs/samsam": "^2 || ^3" } }, - "@sinonjs/samsam": { + "node_modules/@sinonjs/samsam": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.1.0.tgz", "integrity": "sha512-IXio+GWY+Q8XUjHUOgK7wx8fpvr7IFffgyXb1bnJFfX3001KmHt35Zq4tp7MXZyjJPCLPuadesDYNk41LYtVjw==", "dev": true, - "requires": { + "dependencies": { "@sinonjs/commons": "^1.0.2", "array-from": "^2.1.1", "lodash.get": "^4.4.2" } }, - "@types/chai": { + "node_modules/@types/chai": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", "dev": true }, - "@types/debug": { + "node_modules/@types/debug": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.3.tgz", "integrity": "sha512-PQverGatRgqIhRLracrC8k/j5A6QOASVLR0wuURx6ROQZx3OQ9PnTc/5Xrznny/xaO0TwdxSgGyG90NCzk37Rg==", "dev": true }, - "@types/mocha": { + "node_modules/@types/mocha": { "version": "2.2.48", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz", "integrity": "sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw==", "dev": true }, - "@types/node": { + "node_modules/@types/node": { "version": "10.12.21", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==", "dev": true }, - "@types/sinon": { + "node_modules/@types/sinon": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-4.3.3.tgz", "integrity": "sha512-Tt7w/ylBS/OEAlSCwzB0Db1KbxnkycP/1UkQpbvKFYoUuRn4uYsC3xh5TRPrOjTy0i8TIkSz1JdNL4GPVdf3KQ==", "dev": true }, - "@types/typescript": { + "node_modules/@types/typescript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/typescript/-/typescript-2.0.0.tgz", "integrity": "sha1-xDNTnJi64oaCswfqp6D9IRW4PCg=", + "deprecated": "This is a stub types definition for TypeScript (https://github.com/Microsoft/TypeScript). TypeScript provides its own type definitions, so you don't need @types/typescript installed!", "dev": true, - "requires": { + "dependencies": { "typescript": "*" } }, - "ajv": { + "node_modules/ajv": { "version": "6.8.1", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", "dev": true, - "requires": { + "dependencies": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, - "ansi-regex": { + "node_modules/ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { + "dependencies": { "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "append-transform": { + "node_modules/append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, - "requires": { + "dependencies": { "default-require-extensions": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "archy": { + "node_modules/archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, - "argparse": { + "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "requires": { + "dependencies": { "sprintf-js": "~1.0.2" } }, - "array-from": { + "node_modules/array-from": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", "dev": true }, - "arrify": { + "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "asn1": { + "node_modules/asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, - "requires": { + "dependencies": { "safer-buffer": "~2.1.0" } }, - "assert-plus": { + "node_modules/assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8" + } }, - "assertion-error": { + "node_modules/assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "async": { + "node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, - "asynckit": { + "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "aws-sdk": { - "version": "2.443.0", - "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.443.0.tgz", - "integrity": "sha512-I4vjwridWEQDq6L6GE3AsV0MzvRI1drPbHtxbI/K4Q4lmwMkskue+qiSlac4EY3ZJBuBIXGgIclKnkr8AuW71g==", - "requires": { - "buffer": "4.9.1", + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sdk": { + "version": "2.1490.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1490.0.tgz", + "integrity": "sha512-nRVP1+JVGHytxrPpc+6I41lTILzYeTOBAdNbgCi5bwRPrnEr/DxunyHWbGh92qupfHbm9dFcKdao4pOMPDOcVA==", + "dependencies": { + "buffer": "4.9.2", "events": "1.1.1", - "ieee754": "1.1.8", - "jmespath": "0.15.0", + "ieee754": "1.1.13", + "jmespath": "0.16.0", "querystring": "0.2.0", "sax": "1.2.1", "url": "0.10.3", - "uuid": "3.3.2", - "xml2js": "0.4.19" + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aws-sdk/node_modules/uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "bin": { + "uuid": "dist/bin/uuid" } }, - "aws-sign2": { + "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "aws4": { + "node_modules/aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "base64-js": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "bcrypt-pbkdf": { + "node_modules/bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, - "requires": { + "dependencies": { "tweetnacl": "^0.14.3" } }, - "brace-expansion": { + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "requires": { + "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, - "browser-stdout": { + "node_modules/browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "requires": { + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { "base64-js": "^1.0.2", "ieee754": "^1.1.4", "isarray": "^1.0.0" } }, - "builtin-modules": { + "node_modules/builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "caching-transform": { + "node_modules/caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", "dev": true, - "requires": { + "dependencies": { "hasha": "^3.0.0", "make-dir": "^2.0.0", "package-hash": "^3.0.0", "write-file-atomic": "^2.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "camelcase": { + "node_modules/call-bind-apply-helpers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", + "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", + "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "caseless": { + "node_modules/caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "chai": { + "node_modules/chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", "dev": true, - "requires": { + "dependencies": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", "pathval": "^1.1.0", "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" } }, - "chalk": { + "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "check-error": { + "node_modules/check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "cliui": { + "node_modules/cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, - "requires": { + "dependencies": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" } }, - "codeclimate-test-reporter": { + "node_modules/codeclimate-test-reporter": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/codeclimate-test-reporter/-/codeclimate-test-reporter-0.5.1.tgz", "integrity": "sha512-XCzmc8dH+R4orK11BCg5pBbXc35abxq9sept4YvUFRkFl9zb9MIVRrCKENe6U1TKAMTgvGJmrYyHn0y2lerpmg==", + "deprecated": "codeclimate-test-reporter has been deprecated in favor of our new unified test-reporter. Please visit https://docs.codeclimate.com/docs/configuring-test-coverage for details on setting up the new test-reporter.", "dev": true, - "requires": { + "dependencies": { "async": "~1.5.2", "commander": "2.9.0", "lcov-parse": "0.0.10", "request": "~2.88.0" + }, + "bin": { + "codeclimate-test-reporter": "bin/codeclimate.js" + }, + "engines": { + "node": ">= 4" } }, - "color-convert": { + "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, - "combined-stream": { + "node_modules/combined-stream": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", "dev": true, - "requires": { + "dependencies": { "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "commander": { + "node_modules/commander": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, - "requires": { + "dependencies": { "graceful-readlink": ">= 1.0.0" + }, + "engines": { + "node": ">= 0.6.x" } }, - "commondir": { + "node_modules/commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "concat-map": { + "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "convert-source-map": { + "node_modules/convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "~5.1.1" } }, - "core-util-is": { + "node_modules/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 }, - "cp-file": { + "node_modules/cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.2", "make-dir": "^2.0.0", "nested-error-stacks": "^2.0.0", "pify": "^4.0.1", "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=6" } }, - "cross-spawn": { + "node_modules/cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, - "requires": { + "dependencies": { "lru-cache": "^4.0.1", "which": "^1.2.9" } }, - "dashdash": { + "node_modules/dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" } }, - "debug": { + "node_modules/debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dependencies": { "ms": "^2.1.1" } }, - "decamelize": { + "node_modules/decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "deep-eql": { + "node_modules/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": { + "dependencies": { "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" } }, - "default-require-extensions": { + "node_modules/default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, - "requires": { + "dependencies": { "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "delayed-stream": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "diff": { + "node_modules/diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.3.1" + } }, - "doctrine": { + "node_modules/doctrine": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", "dev": true, - "requires": { + "dependencies": { "esutils": "^1.1.6", "isarray": "0.0.1" }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/doctrine/node_modules/esutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", + "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/doctrine/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", "dependencies": { - "esutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", - "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", - "dev": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "ecc-jsbn": { + "node_modules/ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, - "requires": { + "dependencies": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, - "emoji-regex": { + "node_modules/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 }, - "end-of-stream": { + "node_modules/end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "dev": true, - "requires": { + "dependencies": { "once": "^1.4.0" } }, - "error-ex": { + "node_modules/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": { + "dependencies": { "is-arrayish": "^0.2.1" } }, - "es6-error": { + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, - "escape-string-regexp": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.8.0" + } }, - "esprima": { + "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } }, - "esutils": { + "node_modules/esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "events": { + "node_modules/events": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=" + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" + } }, - "execa": { + "node_modules/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": { + "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", "is-stream": "^1.1.0", @@ -704,351 +985,628 @@ "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" }, + "engines": { + "node": ">=6" + } + }, + "node_modules/execa/node_modules/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, "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" } }, - "extend": { + "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, - "extsprintf": { + "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "dev": true, + "engines": [ + "node >=0.6.0" + ] }, - "fast-deep-equal": { + "node_modules/fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, - "fast-json-stable-stringify": { + "node_modules/fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, - "find-cache-dir": { + "node_modules/find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, - "requires": { + "dependencies": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "find-up": { + "node_modules/find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, - "requires": { + "dependencies": { "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "foreground-child": { + "node_modules/for-each": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.4.tgz", + "integrity": "sha512-kKaIINnFpzW6ffJNDjjyjrk21BkDx38c0xa/klsT8VzLCaMEefv4ZTacrcVR4DmgTeBra++jMDAfS/tS799YDw==", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, - "requires": { + "dependencies": { "cross-spawn": "^4", "signal-exit": "^3.0.0" } }, - "forever-agent": { + "node_modules/forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "form-data": { + "node_modules/form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, - "requires": { + "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" } }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "get-caller-file": { + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.1.tgz", "integrity": "sha512-SpOZHfz845AH0wJYVuZk2jWDqFmu7Xubsx+ldIpwzy5pDUpu7OJHK7QYNSA2NPlDSKQwM1GFaAkciOWjjW92Sg==", - "dev": true + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "get-func-name": { + "node_modules/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 + "dev": true, + "engines": { + "node": "*" + } }, - "get-stream": { + "node_modules/get-intrinsic": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/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": { + "dependencies": { "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "getpass": { + "node_modules/getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0" } }, - "glob": { + "node_modules/glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, - "requires": { + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" } }, - "globals": { + "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "graceful-fs": { + "node_modules/graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, - "graceful-readlink": { + "node_modules/graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, - "growl": { + "node_modules/growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4.x" + } }, - "handlebars": { + "node_modules/handlebars": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", "dev": true, - "requires": { + "dependencies": { "neo-async": "^2.6.0", "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" + "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 - } + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/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, + "engines": { + "node": ">=0.10.0" } }, - "har-schema": { + "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "har-validator": { + "node_modules/har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "deprecated": "this library is no longer supported", "dev": true, - "requires": { + "dependencies": { "ajv": "^6.5.5", "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "has-flag": { + "node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "hasha": { + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, - "requires": { + "dependencies": { "is-stream": "^1.0.1" + }, + "engines": { + "node": ">=4" } }, - "he": { + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true + "dev": true, + "bin": { + "he": "bin/he" + } }, - "homedir-polyfill": { + "node_modules/homedir-polyfill": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", "dev": true, - "requires": { + "dependencies": { "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "hosted-git-info": { + "node_modules/hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", "dev": true }, - "http-signature": { + "node_modules/http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, - "requires": { + "dependencies": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" }, - "imurmurhash": { + "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.8.19" + } }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, - "requires": { + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, - "inversify": { + "node_modules/inversify": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/inversify/-/inversify-5.0.1.tgz", "integrity": "sha512-Ieh06s48WnEYGcqHepdsJUIJUXpwH5o5vodAX+DK2JA/gjy4EbEcQZxw+uFfzysmKjiLXGYwNG3qDZsKVMcINQ==", "dev": true }, - "invert-kv": { + "node_modules/invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "is-arrayish": { + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, - "is-fullwidth-code-point": { + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", + "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-stream": { + "node_modules/is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "is-typedarray": { + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "isarray": { + "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, - "isexe": { + "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "isstream": { + "node_modules/isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, - "istanbul-lib-coverage": { + "node_modules/istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "istanbul-lib-hook": { + "node_modules/istanbul-lib-hook": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, - "requires": { + "dependencies": { "append-transform": "^1.0.0" + }, + "engines": { + "node": ">=6" } }, - "istanbul-lib-instrument": { + "node_modules/istanbul-lib-instrument": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, - "requires": { + "dependencies": { "@babel/generator": "^7.4.0", "@babel/parser": "^7.4.3", "@babel/template": "^7.4.0", @@ -1057,333 +1615,406 @@ "istanbul-lib-coverage": "^2.0.5", "semver": "^6.0.0" }, - "dependencies": { - "semver": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", - "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", - "dev": true - } + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", + "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "dev": true, + "bin": { + "semver": "bin/semver" } }, - "istanbul-lib-report": { + "node_modules/istanbul-lib-report": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, - "requires": { + "dependencies": { "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" }, + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "istanbul-lib-source-maps": { + "node_modules/istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, - "requires": { + "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" }, - "dependencies": { - "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 - } + "engines": { + "node": ">=6" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/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, + "engines": { + "node": ">=0.10.0" } }, - "istanbul-reports": { + "node_modules/istanbul-reports": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", "dev": true, - "requires": { + "dependencies": { "handlebars": "^4.1.2" + }, + "engines": { + "node": ">=6" } }, - "jmespath": { - "version": "0.15.0", - "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz", - "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=" + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "engines": { + "node": ">= 0.6.0" + } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "js-yaml": { + "node_modules/js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, - "requires": { + "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "jsbn": { + "node_modules/jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, - "jsesc": { + "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } }, - "json-parse-better-errors": { + "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, - "json-schema": { + "node_modules/json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, - "json-schema-traverse": { + "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, - "json-stringify-safe": { + "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, - "jsprim": { + "node_modules/jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" } }, - "just-extend": { + "node_modules/just-extend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", "dev": true }, - "lcid": { + "node_modules/lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, - "requires": { + "dependencies": { "invert-kv": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "lcov-parse": { + "node_modules/lcov-parse": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", "dev": true }, - "load-json-file": { + "node_modules/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": { + "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "engines": { + "node": ">=4" } }, - "locate-path": { + "node_modules/load-json-file/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, - "requires": { + "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "lodash": { + "node_modules/lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, - "lodash.flattendeep": { + "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, - "lodash.get": { + "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", "dev": true }, - "lolex": { + "node_modules/lolex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.0.0.tgz", "integrity": "sha512-hcnW80h3j2lbUfFdMArd5UPA/vxZJ+G8vobd+wg3nVEQA0EigStbYcrG030FJxL6xiDDPEkoMatV9xIh5OecQQ==", "dev": true }, - "lru-cache": { + "node_modules/lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, - "requires": { + "dependencies": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, - "make-dir": { + "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, - "requires": { + "dependencies": { "pify": "^4.0.1", "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" } }, - "make-error": { + "node_modules/make-error": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true }, - "map-age-cleaner": { + "node_modules/map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, - "requires": { + "dependencies": { "p-defer": "^1.0.0" + }, + "engines": { + "node": ">=6" } }, - "mem": { + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mem": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, - "requires": { + "dependencies": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^2.0.0", "p-is-promise": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "merge-source-map": { + "node_modules/merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, - "requires": { - "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 - } + "source-map": "^0.6.1" + } + }, + "node_modules/merge-source-map/node_modules/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, + "engines": { + "node": ">=0.10.0" } }, - "mime-db": { + "node_modules/mime-db": { "version": "1.37.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", - "dev": true + "dev": true, + "engines": { + "node": ">= 0.6" + } }, - "mime-types": { + "node_modules/mime-types": { "version": "2.1.21", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "dev": true, - "requires": { + "dependencies": { "mime-db": "~1.37.0" + }, + "engines": { + "node": ">= 0.6" } }, - "mimic-fn": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "minimatch": { + "node_modules/minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, - "requires": { + "dependencies": { "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "minimist": { + "node_modules/minimist": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", "dev": true }, - "mkdirp": { + "node_modules/mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", "dev": true, - "requires": { + "dependencies": { "minimist": "0.0.8" }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } + "bin": { + "mkdirp": "bin/cmd.js" } }, - "mocha": { + "node_modules/mkdirp/node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "node_modules/mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", "dev": true, - "requires": { + "dependencies": { "browser-stdout": "1.3.1", "commander": "2.15.1", "debug": "3.1.0", @@ -1396,124 +2027,137 @@ "mkdirp": "0.5.1", "supports-color": "5.4.0" }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/mocha/node_modules/commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, "dependencies": { - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "ms": "2.0.0" } }, - "ms": { + "node_modules/mocha/node_modules/glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" }, - "neo-async": { + "node_modules/neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, - "nested-error-stacks": { + "node_modules/nested-error-stacks": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, - "nice-try": { + "node_modules/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": { + "node_modules/nise": { "version": "1.4.8", "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", "dev": true, - "requires": { + "dependencies": { "@sinonjs/formatio": "^3.1.0", "just-extend": "^4.0.2", "lolex": "^2.3.2", "path-to-regexp": "^1.7.0", "text-encoding": "^0.6.4" - }, - "dependencies": { - "lolex": { - "version": "2.7.5", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", - "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", - "dev": true - } } }, - "normalize-package-data": { + "node_modules/nise/node_modules/lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + }, + "node_modules/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": { + "dependencies": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, - "npm-run-path": { + "node_modules/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": { + "dependencies": { "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" } }, - "nyc": { + "node_modules/nyc": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, - "requires": { + "dependencies": { "archy": "^1.0.0", "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", @@ -1539,303 +2183,396 @@ "uuid": "^3.3.2", "yargs": "^13.2.2", "yargs-parser": "^13.0.0" + }, + "bin": { + "nyc": "bin/nyc.js" + }, + "engines": { + "node": ">=6" } }, - "oauth-sign": { + "node_modules/oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "once": { + "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "requires": { + "dependencies": { "wrappy": "1" } }, - "optimist": { + "node_modules/optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, - "requires": { + "dependencies": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" } }, - "os-homedir": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "os-locale": { + "node_modules/os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, - "requires": { + "dependencies": { "execa": "^1.0.0", "lcid": "^2.0.0", "mem": "^4.0.0" + }, + "engines": { + "node": ">=6" } }, - "p-defer": { + "node_modules/p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-event": { + "node_modules/p-event": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.2.0.tgz", "integrity": "sha512-Myi71SifcJ94wsMgTqK3MGIVrIN3+AXU0BgUBrp9z4RqeiKw8ouXPApPe3n58a8Ea4fs37i2RuH5P7y8fPrFaQ==", "dev": true, - "requires": { + "dependencies": { "p-timeout": "^2.0.1" + }, + "engines": { + "node": ">=6" } }, - "p-finally": { + "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "p-is-promise": { + "node_modules/p-is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "p-limit": { + "node_modules/p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, - "requires": { + "dependencies": { "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "p-locate": { + "node_modules/p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, - "requires": { + "dependencies": { "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "p-timeout": { + "node_modules/p-timeout": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", "dev": true, - "requires": { + "dependencies": { "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" } }, - "p-try": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=6" + } }, - "package-hash": { + "node_modules/package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.15", "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" + }, + "engines": { + "node": ">=6" } }, - "parse-json": { + "node_modules/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": { + "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" } }, - "parse-passwd": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-exists": { + "node_modules/path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "path-key": { + "node_modules/path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "path-parse": { + "node_modules/path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "path-to-regexp": { + "node_modules/path-to-regexp": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", "dev": true, - "requires": { - "isarray": "0.0.1" - }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } + "isarray": "0.0.1" } }, - "path-type": { + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/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": { + "dependencies": { "pify": "^3.0.0" }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } + "engines": { + "node": ">=4" + } + }, + "node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" } }, - "pathval": { + "node_modules/pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true + "dev": true, + "engines": { + "node": "*" + } }, - "performance-now": { + "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "pify": { + "node_modules/pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true + "dev": true, + "engines": { + "node": ">=6" + } }, - "pkg-dir": { + "node_modules/pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, - "requires": { + "dependencies": { "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "engines": { + "node": ">= 0.4" } }, - "pseudomap": { + "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, - "psl": { + "node_modules/psl": { "version": "1.1.31", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", "dev": true }, - "pump": { + "node_modules/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": { + "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, - "punycode": { + "node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" }, - "qs": { + "node_modules/qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true + "dev": true, + "engines": { + "node": ">=0.6" + } }, - "querystring": { + "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } }, - "read-pkg": { + "node_modules/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": { + "dependencies": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "read-pkg-up": { + "node_modules/read-pkg-up": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, - "requires": { + "dependencies": { "find-up": "^3.0.0", "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "reflect-metadata": { + "node_modules/reflect-metadata": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", "dev": true }, - "release-zalgo": { + "node_modules/release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, - "requires": { + "dependencies": { "es6-error": "^4.0.1" + }, + "engines": { + "node": ">=4" } }, - "request": { + "node_modules/request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, - "requires": { + "dependencies": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", @@ -1856,100 +2593,155 @@ "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 4" } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "require-main-filename": { + "node_modules/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 }, - "resolve": { + "node_modules/resolve": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", "dev": true, - "requires": { + "dependencies": { "path-parse": "^1.0.6" } }, - "resolve-from": { + "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "rimraf": { + "node_modules/rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, - "requires": { + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "safe-buffer": { + "node_modules/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 }, - "safer-buffer": { + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sax": { + "node_modules/sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", - "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" }, - "semver": { + "node_modules/semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", - "dev": true + "dev": true, + "bin": { + "semver": "bin/semver" + } }, - "set-blocking": { + "node_modules/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 }, - "shebang-command": { + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "requires": { + "dependencies": { "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "shebang-regex": { + "node_modules/shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "signal-exit": { + "node_modules/signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, - "sinon": { + "node_modules/sinon": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", "integrity": "sha512-i6j7sqcLEqTYqUcMV327waI745VASvYuSuQMCjbAwlpAeuCgKZ3LtrjDxAbu+GjNQR0FEDpywtwGCIh8GicNyg==", + "deprecated": "16.1.1", "dev": true, - "requires": { + "dependencies": { "@sinonjs/commons": "^1.3.0", "@sinonjs/formatio": "^3.1.0", "@sinonjs/samsam": "^3.0.2", @@ -1959,27 +2751,30 @@ "supports-color": "^5.5.0" } }, - "source-map": { + "node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "source-map-support": { + "node_modules/source-map-support": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, - "requires": { + "dependencies": { "source-map": "^0.5.6" } }, - "spawn-wrap": { + "node_modules/spawn-wrap": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", "dev": true, - "requires": { + "dependencies": { "foreground-child": "^1.5.6", "mkdirp": "^0.5.0", "os-homedir": "^1.0.1", @@ -1988,50 +2783,50 @@ "which": "^1.3.0" } }, - "spdx-correct": { + "node_modules/spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, - "requires": { + "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-exceptions": { + "node_modules/spdx-exceptions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", "dev": true }, - "spdx-expression-parse": { + "node_modules/spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, - "requires": { + "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, - "spdx-license-ids": { + "node_modules/spdx-license-ids": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", "dev": true }, - "sprintf-js": { + "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "sshpk": { + "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, - "requires": { + "dependencies": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", @@ -2041,109 +2836,146 @@ "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" } }, - "string-width": { + "node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, - "requires": { + "dependencies": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" } }, - "strip-ansi": { + "node_modules/strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "requires": { + "dependencies": { "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } }, - "strip-bom": { + "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "strip-eof": { + "node_modules/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 + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "strip-json-comments": { + "node_modules/strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "supports-color": { + "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { + "dependencies": { "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "test-exclude": { + "node_modules/test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, - "requires": { + "dependencies": { "glob": "^7.1.3", "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", "require-main-filename": "^2.0.0" + }, + "engines": { + "node": ">=6" } }, - "text-encoding": { + "node_modules/text-encoding": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "deprecated": "no longer maintained", "dev": true }, - "to-fast-properties": { + "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "tough-cookie": { + "node_modules/tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, - "requires": { + "dependencies": { "psl": "^1.1.24", "punycode": "^1.4.1" }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "engines": { + "node": ">=0.8" } }, - "trim-right": { + "node_modules/tough-cookie/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "node_modules/trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "ts-node": { + "node_modules/ts-node": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-3.3.0.tgz", "integrity": "sha1-wTxqMCTjC+EYDdUwOPwgkonUv2k=", "dev": true, - "requires": { + "dependencies": { "arrify": "^1.0.0", "chalk": "^2.0.0", "diff": "^3.1.0", @@ -2155,37 +2987,42 @@ "v8flags": "^3.0.0", "yn": "^2.0.0" }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "bin": { + "_ts-node": "dist/_bin.js", + "ts-node": "dist/bin.js" + }, + "engines": { + "node": ">=4.2.0" } }, - "tsconfig": { + "node_modules/ts-node/node_modules/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "node_modules/tsconfig": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-6.0.0.tgz", "integrity": "sha1-aw6DdgA9evGGT434+J3QBZ/80DI=", "dev": true, - "requires": { + "dependencies": { "strip-bom": "^3.0.0", "strip-json-comments": "^2.0.0" } }, - "tslib": { + "node_modules/tslib": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", "dev": true }, - "tslint": { + "node_modules/tslint": { "version": "5.17.0", "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz", "integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==", "dev": true, - "requires": { + "dependencies": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", @@ -2200,290 +3037,399 @@ "tslib": "^1.8.0", "tsutils": "^2.29.0" }, - "dependencies": { - "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 - } + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" } }, - "tslint-config-airbnb": { + "node_modules/tslint-config-airbnb": { "version": "5.11.1", "resolved": "https://registry.npmjs.org/tslint-config-airbnb/-/tslint-config-airbnb-5.11.1.tgz", "integrity": "sha512-hkaittm2607vVMe8eotANGN1CimD5tor7uoY3ypg2VTtEcDB/KGWYbJOz58t8LI4cWSyWtgqYQ5F0HwKxxhlkQ==", "dev": true, - "requires": { + "dependencies": { "tslint-consistent-codestyle": "^1.14.1", "tslint-eslint-rules": "^5.4.0", "tslint-microsoft-contrib": "~5.2.1" + }, + "peerDependencies": { + "tslint": "^5.11.0" } }, - "tslint-consistent-codestyle": { + "node_modules/tslint-consistent-codestyle": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/tslint-consistent-codestyle/-/tslint-consistent-codestyle-1.15.0.tgz", "integrity": "sha512-6BNDBbZh2K0ibRXe70Mkl9gfVttxQ3t3hqV1BRDfpIcjrUoOgD946iH4SrXp+IggDgeMs3dJORjD5tqL5j4jXg==", "dev": true, - "requires": { + "dependencies": { "@fimbul/bifrost": "^0.17.0", "tslib": "^1.7.1", "tsutils": "^2.29.0" + }, + "peerDependencies": { + "tslint": "^5.0.0", + "typescript": ">=2.1.4 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >=3.1.0-dev || >=3.2.0-dev || >=3.3.0-dev || >=3.4.0-dev" } }, - "tslint-eslint-rules": { + "node_modules/tslint-eslint-rules": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.4.0.tgz", "integrity": "sha512-WlSXE+J2vY/VPgIcqQuijMQiel+UtmXS+4nvK4ZzlDiqBfXse8FAvkNnTcYhnQyOTW5KFM+uRRGXxYhFpuBc6w==", "dev": true, - "requires": { + "dependencies": { "doctrine": "0.7.2", "tslib": "1.9.0", "tsutils": "^3.0.0" }, + "peerDependencies": { + "tslint": "^5.0.0", + "typescript": "^2.2.0 || ^3.0.0" + } + }, + "node_modules/tslint-eslint-rules/node_modules/tslib": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", + "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", + "dev": true + }, + "node_modules/tslint-eslint-rules/node_modules/tsutils": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.8.0.tgz", + "integrity": "sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA==", + "dev": true, "dependencies": { - "tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", - "dev": true - }, - "tsutils": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.8.0.tgz", - "integrity": "sha512-XQdPhgcoTbCD8baXC38PQ0vpTZ8T3YrE+vR66YIj/xvDt1//8iAhafpIT/4DmvzzC1QFapEImERu48Pa01dIUA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev" } }, - "tslint-microsoft-contrib": { + "node_modules/tslint-microsoft-contrib": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/tslint-microsoft-contrib/-/tslint-microsoft-contrib-5.2.1.tgz", "integrity": "sha512-PDYjvpo0gN9IfMULwKk0KpVOPMhU6cNoT9VwCOLeDl/QS8v8W2yspRpFFuUS7/c5EIH/n8ApMi8TxJAz1tfFUA==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", "dev": true, - "requires": { + "dependencies": { "tsutils": "^2.27.2 <2.29.0" }, + "peerDependencies": { + "tslint": "^5.1.0", + "typescript": "^2.1.0 || ^3.0.0" + } + }, + "node_modules/tslint-microsoft-contrib/node_modules/tsutils": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", + "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", + "dev": true, "dependencies": { - "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - } + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, - "tsutils": { + "node_modules/tslint/node_modules/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 + }, + "node_modules/tsutils": { "version": "2.29.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, - "requires": { + "dependencies": { "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, - "tunnel-agent": { + "node_modules/tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, - "requires": { + "dependencies": { "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" } }, - "tweetnacl": { + "node_modules/tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } }, - "typescript": { + "node_modules/typescript": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", - "dev": true + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } }, - "uglify-js": { + "node_modules/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==", "dev": true, "optional": true, - "requires": { + "dependencies": { "commander": "~2.20.0", "source-map": "~0.6.1" }, - "dependencies": { - "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 - }, - "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 - } + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uglify-js/node_modules/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 + }, + "node_modules/uglify-js/node_modules/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, + "engines": { + "node": ">=0.10.0" } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, - "requires": { - "punycode": "^2.1.0" - }, "dependencies": { - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - } + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" } }, - "url": { + "node_modules/url": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", - "requires": { + "dependencies": { "punycode": "1.3.2", "querystring": "0.2.0" } }, - "uuid": { + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } }, - "v8flags": { + "node_modules/v8flags": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.2.tgz", "integrity": "sha512-MtivA7GF24yMPte9Rp/BWGCYQNaUj86zeYxV/x2RRJMKagImbbv3u8iJC57lNhWLPcGLJmHcHmFWkNsplbbLWw==", "dev": true, - "requires": { + "dependencies": { "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" } }, - "validate-npm-package-license": { + "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "verror": { + "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, - "requires": { + "engines": [ + "node >=0.6.0" + ], + "dependencies": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, - "which": { + "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, - "requires": { + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" } }, - "which-module": { + "node_modules/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 }, - "wordwrap": { + "node_modules/which-typed-array": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", + "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "wrap-ansi": { + "node_modules/wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, - "requires": { + "dependencies": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write-file-atomic": { + "node_modules/write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, - "requires": { + "dependencies": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "signal-exit": "^3.0.2" } }, - "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", - "requires": { + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { "sax": ">=0.6.0", - "xmlbuilder": "~9.0.1" + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" } }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } }, - "y18n": { + "node_modules/y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, - "yallist": { + "node_modules/yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true }, - "yargs": { + "node_modules/yargs": { "version": "13.2.4", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", "dev": true, - "requires": { + "dependencies": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", @@ -2497,21 +3443,24 @@ "yargs-parser": "^13.1.0" } }, - "yargs-parser": { + "node_modules/yargs-parser": { "version": "13.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.0.tgz", "integrity": "sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA==", "dev": true, - "requires": { + "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, - "yn": { + "node_modules/yn": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true + "dev": true, + "engines": { + "node": ">=4" + } } } } diff --git a/src/consumer.ts b/src/consumer.ts index 2c0973f3..861924f8 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -205,6 +205,7 @@ export class Consumer extends EventEmitter { this.concurrencyLimit = newConcurrencyLimit; this.freeConcurrentSlots = newFreeConcurrentSlots; + this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots); } public setPollingWaitTimeMs(newPollingWaitTimeMs: number): void { @@ -215,6 +216,7 @@ export class Consumer extends EventEmitter { debug('Message from batch has finished'); this.freeConcurrentSlots++; + this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots); try { if (error) throw error; @@ -229,6 +231,7 @@ export class Consumer extends EventEmitter { private reportNumberOfMessagesReceived(numberOfMessages: number): void { debug('Reducing number of messages received from freeConcurrentSlots'); this.freeConcurrentSlots = this.freeConcurrentSlots - numberOfMessages; + this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots); } private async handleSqsResponse(response: ReceieveMessageResponse): Promise { From 1e262ffc63f7eb3286afd6dd791c5306f114b294 Mon Sep 17 00:00:00 2001 From: Shai Katz Date: Sun, 26 Jan 2025 16:25:46 +0200 Subject: [PATCH 36/40] add queue url --- src/consumer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/consumer.ts b/src/consumer.ts index 861924f8..8c5d5e8e 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -205,7 +205,7 @@ export class Consumer extends EventEmitter { this.concurrencyLimit = newConcurrencyLimit; this.freeConcurrentSlots = newFreeConcurrentSlots; - this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots); + this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots, this.queueUrl); } public setPollingWaitTimeMs(newPollingWaitTimeMs: number): void { @@ -216,7 +216,7 @@ export class Consumer extends EventEmitter { debug('Message from batch has finished'); this.freeConcurrentSlots++; - this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots); + this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots, this.queueUrl); try { if (error) throw error; @@ -231,7 +231,7 @@ export class Consumer extends EventEmitter { private reportNumberOfMessagesReceived(numberOfMessages: number): void { debug('Reducing number of messages received from freeConcurrentSlots'); this.freeConcurrentSlots = this.freeConcurrentSlots - numberOfMessages; - this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots); + this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots, this.queueUrl); } private async handleSqsResponse(response: ReceieveMessageResponse): Promise { From 278bddf7c464515f505870bcdd993e977940beb5 Mon Sep 17 00:00:00 2001 From: Shai Katz Date: Sun, 26 Jan 2025 16:26:31 +0200 Subject: [PATCH 37/40] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b7e8e705..bd3497ff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sqs-consumer", - "version": "6.2.0", + "version": "6.3.0", "description": "Build SQS-based Node applications without the boilerplate", "main": "dist/index.js", "types": "dist/index.d.ts", From 74ff7426e3bfa068b4ec10396345f5aaef263f2e Mon Sep 17 00:00:00 2001 From: Shai Katz Date: Sun, 26 Jan 2025 16:51:08 +0200 Subject: [PATCH 38/40] use precentage --- src/consumer.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/consumer.ts b/src/consumer.ts index 8c5d5e8e..8f30bccb 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -205,7 +205,7 @@ export class Consumer extends EventEmitter { this.concurrencyLimit = newConcurrencyLimit; this.freeConcurrentSlots = newFreeConcurrentSlots; - this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots, this.queueUrl); + this.reportConcurrencyUsage(this.freeConcurrentSlots); } public setPollingWaitTimeMs(newPollingWaitTimeMs: number): void { @@ -216,7 +216,7 @@ export class Consumer extends EventEmitter { debug('Message from batch has finished'); this.freeConcurrentSlots++; - this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots, this.queueUrl); + this.reportConcurrencyUsage(this.freeConcurrentSlots); try { if (error) throw error; @@ -231,7 +231,7 @@ export class Consumer extends EventEmitter { private reportNumberOfMessagesReceived(numberOfMessages: number): void { debug('Reducing number of messages received from freeConcurrentSlots'); this.freeConcurrentSlots = this.freeConcurrentSlots - numberOfMessages; - this.emit('free_concurrent_slots_updated', this.freeConcurrentSlots, this.queueUrl); + this.reportConcurrencyUsage(this.freeConcurrentSlots); } private async handleSqsResponse(response: ReceieveMessageResponse): Promise { @@ -450,4 +450,9 @@ export class Consumer extends EventEmitter { } }); } + + private reportConcurrencyUsage(currentFreeConcurrencySlots): void { + const precentageUsage = (currentFreeConcurrencySlots / this.concurrencyLimit) * 100; + this.emit('concurrency_usage_updated', precentageUsage, this.queueUrl); + } } From df99e034406e0a0c30d1087b6c72fbe0d3b69641 Mon Sep 17 00:00:00 2001 From: Shai Katz Date: Sun, 26 Jan 2025 17:42:26 +0200 Subject: [PATCH 39/40] add more data to event --- src/consumer.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/consumer.ts b/src/consumer.ts index 8f30bccb..9259f144 100644 --- a/src/consumer.ts +++ b/src/consumer.ts @@ -452,7 +452,6 @@ export class Consumer extends EventEmitter { } private reportConcurrencyUsage(currentFreeConcurrencySlots): void { - const precentageUsage = (currentFreeConcurrencySlots / this.concurrencyLimit) * 100; - this.emit('concurrency_usage_updated', precentageUsage, this.queueUrl); + this.emit('concurrency_usage_updated', currentFreeConcurrencySlots, this.concurrencyLimit, this.queueUrl); } } From b13620c033d896693fe4c3015ea7ea653eaef58d Mon Sep 17 00:00:00 2001 From: Shai Katz Date: Mon, 27 Jan 2025 14:35:25 +0200 Subject: [PATCH 40/40] Build dist for new release --- dist/consumer.d.ts | 1 + dist/consumer.js | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/dist/consumer.d.ts b/dist/consumer.d.ts index 838233ef..1db39b8c 100644 --- a/dist/consumer.d.ts +++ b/dist/consumer.d.ts @@ -67,5 +67,6 @@ export declare class Consumer extends EventEmitter { private emitError; private poll; private processMessageBatch; + private reportConcurrencyUsage; } export {}; diff --git a/dist/consumer.js b/dist/consumer.js index b7dfe4eb..00128cc0 100644 --- a/dist/consumer.js +++ b/dist/consumer.js @@ -125,6 +125,7 @@ class Consumer extends events_1.EventEmitter { const newFreeConcurrentSlots = Math.max(0, this.freeConcurrentSlots + concurrencyLimitDiff); this.concurrencyLimit = newConcurrencyLimit; this.freeConcurrentSlots = newFreeConcurrentSlots; + this.reportConcurrencyUsage(this.freeConcurrentSlots); } setPollingWaitTimeMs(newPollingWaitTimeMs) { this.pollingWaitTimeMs = newPollingWaitTimeMs; @@ -132,6 +133,7 @@ class Consumer extends events_1.EventEmitter { async reportMessageFromBatchFinished(message, error) { debug('Message from batch has finished'); this.freeConcurrentSlots++; + this.reportConcurrencyUsage(this.freeConcurrentSlots); try { if (error) throw error; @@ -145,6 +147,7 @@ class Consumer extends events_1.EventEmitter { reportNumberOfMessagesReceived(numberOfMessages) { debug('Reducing number of messages received from freeConcurrentSlots'); this.freeConcurrentSlots = this.freeConcurrentSlots - numberOfMessages; + this.reportConcurrencyUsage(this.freeConcurrentSlots); } async handleSqsResponse(response) { debug('Received SQS response'); @@ -351,5 +354,8 @@ class Consumer extends events_1.EventEmitter { } }); } + reportConcurrencyUsage(currentFreeConcurrencySlots) { + this.emit('concurrency_usage_updated', currentFreeConcurrencySlots, this.concurrencyLimit, this.queueUrl); + } } exports.Consumer = Consumer;