From aa6ea15b68c162ec775bd420ee1a5c62da0190a4 Mon Sep 17 00:00:00 2001 From: Rohit Gohri Date: Fri, 13 Sep 2024 10:44:17 +0200 Subject: [PATCH] PUB-93 - Add support for labelling on all resources (#130) --- .changeset/wicked-geckos-shake.md | 5 + .changeset/wild-bees-crash.md | 5 + .changeset/yellow-tables-battle.md | 5 + .vscode/settings.json | 13 +- __tests__/pubsub.service.test.ts | 2 +- ...bscription.with-custom-credentials.test.ts | 41 +- __tests__/topic.test.ts | 35 +- .../topic.with-custom-credentials.test.ts | 30 +- jest.config.js | 4 + src/cli/commands/list.ts | 3 +- src/client/googlePubSub/deadLetter.ts | 143 ++ src/client/googlePubSub/index.ts | 398 ++-- src/client/googlePubSub/subscriptions.ts | 12 +- src/index.ts | 1 + src/interface/GooglePubSubProject.ts | 2 +- src/interface/publishOptions.ts | 6 +- src/service/logger.ts | 32 + src/service/pubsub.ts | 27 +- src/service/subscription.ts | 6 +- src/subscriber/subscriberV2.ts | 28 +- src/topic/index.ts | 98 +- src/utils.ts | 40 + tsconfig.build.json | 15 +- tsconfig.json | 20 +- yarn.lock | 1594 +++++++++++------ 25 files changed, 1585 insertions(+), 980 deletions(-) create mode 100644 .changeset/wicked-geckos-shake.md create mode 100644 .changeset/wild-bees-crash.md create mode 100644 .changeset/yellow-tables-battle.md create mode 100644 src/client/googlePubSub/deadLetter.ts create mode 100644 src/utils.ts diff --git a/.changeset/wicked-geckos-shake.md b/.changeset/wicked-geckos-shake.md new file mode 100644 index 00000000..12f5c2bc --- /dev/null +++ b/.changeset/wicked-geckos-shake.md @@ -0,0 +1,5 @@ +--- +'@honestfoodcompany/pubsub': patch +--- + +Fix topic options default retry config not being applied if custom options provided diff --git a/.changeset/wild-bees-crash.md b/.changeset/wild-bees-crash.md new file mode 100644 index 00000000..5a4b84c3 --- /dev/null +++ b/.changeset/wild-bees-crash.md @@ -0,0 +1,5 @@ +--- +'@honestfoodcompany/pubsub': minor +--- + +Set labels for subscriptions, dlq on update too and support for labels to topics - PUB-93 diff --git a/.changeset/yellow-tables-battle.md b/.changeset/yellow-tables-battle.md new file mode 100644 index 00000000..3c0c5d62 --- /dev/null +++ b/.changeset/yellow-tables-battle.md @@ -0,0 +1,5 @@ +--- +'@honestfoodcompany/pubsub': patch +--- + +Update logging to be more structured - PUB-87 diff --git a/.vscode/settings.json b/.vscode/settings.json index 5f012b0e..11609757 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,32 +13,29 @@ "[javascript]": { "editor.formatOnSave": false, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" } }, "[javascriptreact]": { "editor.formatOnSave": false, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" } }, "[typescript]": { "editor.formatOnSave": false, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" } }, "[typescriptreact]": { "editor.formatOnSave": false, "editor.codeActionsOnSave": { - "source.fixAll": true + "source.fixAll": "explicit" } }, "editor.tabCompletion": "on", "editor.tabSize": 2, - "editor.rulers": [ - 80, - 120 - ], + "editor.rulers": [80, 120], "jest.jestCommandLine": "yarn test" } diff --git a/__tests__/pubsub.service.test.ts b/__tests__/pubsub.service.test.ts index 7a84ecee..b9e485f9 100644 --- a/__tests__/pubsub.service.test.ts +++ b/__tests__/pubsub.service.test.ts @@ -26,7 +26,7 @@ describe('@PubSub Service Init', () => { }); it('should call init', () => { - expect(SubService.init).toBeCalled(); + expect(SubService.init).toHaveBeenCalled(); }); it('should override closeAll method', () => { diff --git a/__tests__/subscription.with-custom-credentials.test.ts b/__tests__/subscription.with-custom-credentials.test.ts index 15a0529d..124afaed 100644 --- a/__tests__/subscription.with-custom-credentials.test.ts +++ b/__tests__/subscription.with-custom-credentials.test.ts @@ -1,5 +1,4 @@ import { PubSubService, SubscriptionService } from '@honestfoodcompany/pubsub'; -import { mocked } from 'ts-jest/utils'; import { SubscriberTuple } from '../src/subscriber'; import GooglePubSubAdapter from '../src/client/googlePubSub'; import { createProject } from '../src/client/googlePubSub/project'; @@ -15,18 +14,7 @@ jest.mock('../src/client/googlePubSub/project', () => { }; }); -const mockPublish = jest.fn(); const mockSubscribe = jest.fn(); -const mockGet = jest.fn(() => { - return new Promise((resolve) => { - resolve([ - { - publish: mockPublish, - }, - ]); - }); -}); - const mockConstructor = jest.fn(); const mockClose = jest.fn(); const mockRemoveListeners = jest.fn(); @@ -47,9 +35,18 @@ jest.mock('@google-cloud/pubsub', () => { return { subscription: mockSubscription, subscribe: mockSubscribe(config), - topic: jest.fn(() => ({ - get: mockGet, - getSubscriptions: jest.fn(() => ['dummySub']), + topic: jest.fn((topicName) => ({ + get: jest.fn(() => { + return new Promise((resolve) => { + resolve([ + { + name: topicName, + publish: jest.fn(), + getSubscriptions: jest.fn(() => ['dummySub']), + }, + ]); + }); + }), })), }; }), @@ -91,9 +88,9 @@ describe('With Project Credentials', (): void => { const getProject = jest.spyOn(GooglePubSubAdapter.prototype, 'getProject'); await PubSubService.getInstance().subscribe(subscription); - expect(subscribe).toBeCalled(); - expect(getProject).toBeCalledWith(subscription[1].options); - expect(mocked(createProject).mock.calls[1]).toEqual([ + expect(subscribe).toHaveBeenCalled(); + expect(getProject).toHaveBeenCalledWith(subscription[1].options); + expect(jest.mocked(createProject).mock.calls[1]).toEqual([ 'google-pubsub-project-id', { credentials: { @@ -111,13 +108,13 @@ describe('With Project Credentials', (): void => { projectId: 'google-pubsub-project-id', }, ]); - expect(mockSubscription).toBeCalledTimes(1); + expect(mockSubscription).toHaveBeenCalledTimes(1); }); it('should close existing subscription and skip not subscribed topics', async (): Promise => { await PubSubService.getInstance().closeAll(); - expect(mockSubscription).toBeCalledTimes(1); - expect(mockClose).toBeCalledTimes(1); - expect(mockRemoveListeners).toBeCalledTimes(1); + expect(mockSubscription).toHaveBeenCalledTimes(1); + expect(mockClose).toHaveBeenCalledTimes(1); + expect(mockRemoveListeners).toHaveBeenCalledTimes(1); }); }); diff --git a/__tests__/topic.test.ts b/__tests__/topic.test.ts index ad07f197..e192f697 100644 --- a/__tests__/topic.test.ts +++ b/__tests__/topic.test.ts @@ -1,4 +1,5 @@ import PubSubService from '../src/service/pubsub'; +import { defaultOptions } from '../src/topic'; import TestTopic from './pubsub/topics/test-topic'; import TestTopicNoTimeStamp from './pubsub/topics/test-topic.no.timestamp'; @@ -18,18 +19,7 @@ jest.mock('../src/service/pubsub', () => ({ describe('topics', (): void => { const defaultRetrySettings = { - retryConfig: { - backoffSettings: { - initialRetryDelayMillis: 100, - initialRpcTimeoutMillis: 5000, - maxRetryDelayMillis: 60000, - maxRpcTimeoutMillis: 600000, - retryDelayMultiplier: 1.3, - rpcTimeoutMultiplier: 1, - totalTimeoutMillis: 600000, - }, - retryCodes: [10, 1, 4, 13, 8, 14, 2], - }, + retryConfig: defaultOptions.retryConfig, }; beforeEach(() => { @@ -40,17 +30,17 @@ describe('topics', (): void => { const spy = jest.spyOn(PubSubService, 'getInstance'); const topic = new TestTopic(); await topic.publish({ data: 'test' }); - expect(spy).toBeCalledTimes(1); - expect(mockPublish).toBeCalledTimes(1); + expect(spy).toHaveBeenCalledTimes(1); + expect(mockPublish).toHaveBeenCalledTimes(1); }); it('Expect publish to return a string with the messageId', async (): Promise => { const spy = jest.spyOn(PubSubService, 'getInstance'); const topic = new TestTopic(); const data = await topic.publish({ data: 'test' }); - expect(spy).toBeCalledTimes(1); + expect(spy).toHaveBeenCalledTimes(1); expect(data).toBe('testid'); - expect(mockPublish).toBeCalledTimes(1); + expect(mockPublish).toHaveBeenCalledTimes(1); }); it('Should test retry config to be the default one', async (): Promise => { @@ -58,7 +48,7 @@ describe('topics', (): void => { const topic = new TestTopic(); const data = await topic.publish({ data: 'test' }); expect(data).toBe('testid'); - expect(spy).toBeCalledWith( + expect(spy).toHaveBeenCalledWith( TestTopic, expect.objectContaining({ _timestamp: expect.stringContaining(':'), @@ -74,12 +64,15 @@ describe('topics', (): void => { const topic = new TestTopicNoTimeStamp(); const data = await topic.publish({ data: 'test' }); expect(data).toBe('testid'); - expect(spy).toBeCalledWith( + expect(spy).toHaveBeenCalledWith( TestTopicNoTimeStamp, expect.not.objectContaining({ _timestamp: expect.stringContaining(':'), }), - {}, + expect.objectContaining({ + ...defaultOptions, + addTimeStamp: false, + }), ); }); @@ -95,7 +88,7 @@ describe('topics', (): void => { }, ); expect(data).toBe('testid'); - expect(spy).toBeCalledWith( + expect(spy).toHaveBeenCalledWith( TestTopic, expect.any(Object), expect.objectContaining({ @@ -123,7 +116,7 @@ describe('topics', (): void => { { attributes: { test: 'filter' } }, ); expect(data).toBe('testid'); - expect(spy).toBeCalledWith( + expect(spy).toHaveBeenCalledWith( TestTopic, expect.any(Object), expect.objectContaining({ diff --git a/__tests__/topic.with-custom-credentials.test.ts b/__tests__/topic.with-custom-credentials.test.ts index 299d1be6..859a325a 100644 --- a/__tests__/topic.with-custom-credentials.test.ts +++ b/__tests__/topic.with-custom-credentials.test.ts @@ -5,16 +5,6 @@ import TestTopicWithProjectCredentials from './pubsub/topics/test-topic.with-cus process.env.PUBSUB_DRIVER = 'google'; const mockPublish = jest.fn(); -const mockGet = jest.fn(() => { - return new Promise((resolve) => { - resolve([ - { - publish: mockPublish, - publishJSON: mockPublish, - }, - ]); - }); -}); const mockConstructor = jest.fn(); jest.mock('@google-cloud/pubsub', () => { @@ -28,8 +18,18 @@ jest.mock('@google-cloud/pubsub', () => { exists: jest.fn(() => true), })), subscribe: jest.fn(), - topic: jest.fn(() => ({ - get: mockGet, + topic: jest.fn((topicName) => ({ + get: jest.fn(() => { + return new Promise((resolve) => { + resolve([ + { + name: topicName, + publish: mockPublish, + publishJSON: mockPublish, + }, + ]); + }); + }), })), }; }), @@ -41,20 +41,20 @@ describe('With Custom Credentials', (): void => { const spy = jest.spyOn(PubSubService.prototype, 'publish'); const topic = new TestTopicWithProjectCredentials(); await topic.publish({ data: 'test' }); - expect(spy).toBeCalled(); + expect(spy).toHaveBeenCalled(); }); it('should call Google Driver publish method', async (): Promise => { const spy = jest.spyOn(GooglePubSubAdapter.prototype, 'publish'); const topic = new TestTopicWithProjectCredentials(); await topic.publish({ data: 'test' }); - expect(spy).toBeCalled(); + expect(spy).toHaveBeenCalled(); }); it('should call GooglePubSub publish method', async (): Promise => { const topic = new TestTopicWithProjectCredentials(); await topic.publish({ data: 'test' }); - expect(mockPublish).toBeCalled(); + expect(mockPublish).toHaveBeenCalled(); }); it('should have the project defined in projects', async () => { diff --git a/jest.config.js b/jest.config.js index 554bffda..64c049ba 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,6 +2,9 @@ process.env.PUBSUB_ROOT_DIR = './__tests__/pubsub'; process.env.PUBSUB_HEALTH_SERVER = 'false'; const TEST_REGEX = '/__tests__/.*.test.(js|ts)?$'; +/** + * @type {import('@jest/types').Config.InitialOptions} + */ module.exports = { // FIXME: Automatically clear mock calls and instances between every test // clearMocks: true, @@ -13,6 +16,7 @@ module.exports = { 'src/**/*.{js,ts}', '!**/*.{generated,interface,test,data,enums}.{ts}', '!**/*.d.ts', + '!src/interface/**', '!src/__tests__/**', '!**/node_modules/**', ], diff --git a/src/cli/commands/list.ts b/src/cli/commands/list.ts index 2409bec3..bef4d061 100644 --- a/src/cli/commands/list.ts +++ b/src/cli/commands/list.ts @@ -18,7 +18,7 @@ export default { Logger.Instance.warn(chalk.white.bold('\n No subscriptions found')); } else { const table = new Table({ - head: ['Topic Name', 'Subscription Name', 'Description'], + head: ['Topic Name', 'Subscription Name', 'DLQ', 'Description'], }); table.push( ...PubSubService.getInstance() @@ -26,6 +26,7 @@ export default { .map((row: SubscriberTuple) => [ row[1].topicName, row[1].subscriptionName, + row[1].options?.deadLetterPolicy?.deadLetterTopic ?? 'N/A', wrapAnsi(row[1].description || '', 100), ]), ); diff --git a/src/client/googlePubSub/deadLetter.ts b/src/client/googlePubSub/deadLetter.ts new file mode 100644 index 00000000..1846eb5f --- /dev/null +++ b/src/client/googlePubSub/deadLetter.ts @@ -0,0 +1,143 @@ +import { Topic } from '@google-cloud/pubsub'; +import { Logger } from '../../service/logger'; +import { SubscriberMetadata } from '../../subscriber'; +import { getNameFromResourceName } from '../../utils'; +import { getProjectNumber, Project } from './project'; + +export async function bindPolicyToSubscriber( + metadata: SubscriberMetadata, + project: Project, +): Promise { + const { topicName: subscriptionTopicName, subscriptionName } = metadata; + const projectNumber = await getProjectNumber(project); + + if (!projectNumber) { + Logger.Instance.warn( + Logger.getInfo(metadata), + ` ❌ Could not bind policy for subscriber due to no project number`, + ); + return; + } + + try { + const pubSubTopic = project.client.topic(subscriptionTopicName); + const myPolicy = { + bindings: [ + { + role: 'roles/pubsub.subscriber', + members: [ + `serviceAccount:service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`, + ], + }, + ], + }; + await pubSubTopic.subscription(subscriptionName).iam.setPolicy(myPolicy); + } catch (err) { + Logger.Instance.error( + { ...Logger.getInfo(metadata), err }, + ` ❌ Error while binding policy for subscription`, + ); + } +} + +export async function bindPolicyToDeadLetterTopic( + dlqTopic: Topic, + metadata: SubscriberMetadata, + project: Project, +): Promise { + const dlqTopicName = getNameFromResourceName(dlqTopic.name); + const projectNumber = await getProjectNumber(project); + if (!projectNumber) { + Logger.Instance.warn( + Logger.getInfo(metadata), + ` ❌ Could not bind policy for DLQ topic due to no project number, "${dlqTopicName}"`, + ); + return; + } + + try { + const myPolicy = { + bindings: [ + { + role: 'roles/pubsub.publisher', + members: [ + `serviceAccount:service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`, + ], + }, + ], + }; + await dlqTopic.iam.setPolicy(myPolicy); + } catch (err) { + Logger.Instance.error( + { ...Logger.getInfo(metadata), err }, + ` ❌ Error while binding policy for DLQ topic, "${dlqTopicName}"`, + ); + } +} + +export async function checkDeadLetterConfiguration( + dlqTopic: Topic, + metadata: SubscriberMetadata, +): Promise { + const [subscriptions] = await dlqTopic.getSubscriptions(); + + if (subscriptions.length === 0) { + Logger.Instance.warn( + Logger.getInfo(metadata), + `Please set 'createDefaultSubscription: true' in deadLetterPolicy to create default subscriber for dead letter topic (${getNameFromResourceName( + dlqTopic.name, + )}) of ${ + metadata.subscriptionName + }. Ignore if already added subscription for it.`, + ); + } +} + +export async function createDeadLetterDefaultSubscriber( + dlqTopic: Topic, + metadata: SubscriberMetadata, + project: Project, +): Promise { + try { + const { client } = project; + const defaultSubscriberName = + getNameFromResourceName(dlqTopic.name) + '.default'; + const defaultSubscription = client.subscription(defaultSubscriberName); + const [defaultSubscriberExists] = await defaultSubscription.exists(); + // DLQ subs's labels are same as subscription + const labelsToSet = metadata.options.labels ?? {}; + + if (defaultSubscriberExists) { + if (Object.keys(labelsToSet).length === 0) { + return; + } + const existingLabels = + (await defaultSubscription.getMetadata())[0].labels ?? {}; + const diff = Object.entries(labelsToSet).filter(([k, v]) => { + if (!existingLabels[k] || existingLabels[k] !== v) { + return true; + } + return false; + }); + if (diff.length === 0) { + return; + } + await defaultSubscription.setMetadata({ + labels: labelsToSet, + }); + return; + } + + await dlqTopic.createSubscription(defaultSubscriberName, { + labels: labelsToSet, + expirationPolicy: { + ttl: null, + }, + }); + } catch (err) { + Logger.Instance.error( + { ...Logger.getInfo(metadata), err }, + ` ❌ Error while creating default deadLetter subscription`, + ); + } +} diff --git a/src/client/googlePubSub/index.ts b/src/client/googlePubSub/index.ts index 5df4673a..4b6dabdd 100644 --- a/src/client/googlePubSub/index.ts +++ b/src/client/googlePubSub/index.ts @@ -6,29 +6,31 @@ import { } from '@google-cloud/pubsub'; import Bluebird from 'bluebird'; import chalk from 'chalk'; - import Pako from 'pako'; + import { TopicProperties } from '../../topic'; -import { PublishOptions } from '../../interface/publishOptions'; +import { GooglePubSubProject, PublishOptions } from '../../interface'; import { AllSubscriptions, IsOpenTuple, PubSubClientV2, } from '../../interface/pubSubClient'; -import { - SubscriberMetadata, - SubscriberOptions, -} from '../../subscriber/subscriberV2'; import { SubscriberTuple } from '../../subscriber'; import Message from '../../message'; -import { GooglePubSubProject } from '../../interface/GooglePubSubProject'; import { Logger } from '../../service/logger'; -import { Project, Projects, createProject, getProjectNumber } from './project'; +import { getNameFromResourceName } from '../../utils'; +import { createProject, Project, Projects } from './project'; import { closeSubscription, getAllSubscriptions, getSubscription, } from './subscriptions'; +import { + bindPolicyToDeadLetterTopic, + bindPolicyToSubscriber, + checkDeadLetterConfiguration, + createDeadLetterDefaultSubscriber, +} from './deadLetter'; const DEFAULT_PROJECT = '__default__'; @@ -48,7 +50,6 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { this.projects[DEFAULT_PROJECT] = createProject( getDefaultProjectFromEnvVar(), ); - this.createOrGetSubscription = this.createOrGetSubscription.bind(this); } static getInstance(): GooglePubSubAdapter { @@ -58,17 +59,17 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { return GooglePubSubAdapter.instance; } - private getProject(options?: { project?: GooglePubSubProject }): Project { - if (!options?.project?.id) { + private getProject({ project }: { project?: GooglePubSubProject }): Project { + if (!project?.id) { return this.projects[DEFAULT_PROJECT]; } - if (this.projects[options.project.id]) { - return this.projects[options.project.id]; + if (this.projects[project.id]) { + return this.projects[project.id]; } - this.projects[options.project.id] = createProject(options.project.id, { - credentials: options.project.credentials, + this.projects[project.id] = createProject(project.id, { + credentials: project.credentials, }); - return this.projects[options.project.id]; + return this.projects[project.id]; } public async publish( @@ -78,6 +79,8 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { ): Promise { const pubSubTopic = await this.createOrGetTopic(topic.topicName, { project: topic.project, + // Publish sets canonical labels for Topics + labels: options?.labels, }); if (options?.enableGZipCompression) { @@ -99,11 +102,14 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { public async subscribe(subscriber: SubscriberTuple): Promise { const [, metadata] = subscriber; const subscription = await this.createOrGetSubscription(subscriber); - await this.handleDeadLetterPolicyConfigurations(subscriber); + const dlqTopic = await this.handleDeadLetterPolicyConfigurations( + subscriber, + ); + await this.updateMetaData(subscriber, dlqTopic); await this.addHandler(subscriber, subscription); - this.log( - ` 📭 ${metadata.subscriptionName} is ready to receive messages at a controlled volume of ${metadata.options?.flowControl?.maxMessages} messages.`, - metadata, + Logger.Instance.info( + Logger.getInfo(metadata), + ` 📭 Subscription ready to receive messages at a controlled volume of ${metadata.options.flowControl?.maxMessages} messages`, ); } @@ -112,14 +118,14 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { const project = this.getProject(metadata.options); if (await closeSubscription(project, subscriber)) { - this.log( - ` 📪 ${metadata.subscriptionName} is closed now`, - metadata, + Logger.Instance.info( + Logger.getInfo(metadata), + ` 📪 Subscription closed now`, ); } else { - this.log( - ` 📪 ${metadata.subscriptionName} wasn't started at all`, - metadata, + Logger.Instance.info( + Logger.getInfo(metadata), + ` 📪 Subscription wasn't started at all`, ); } } @@ -128,37 +134,48 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { subscriber: SubscriberTuple, subscription: GoogleCloudSubscription, ): Promise { - const [subscriberInstance] = subscriber; + const [subscriberInstance, metadata] = subscriber; await subscriberInstance.init(); - subscription.on('message', (message: GoogleCloudMessage): void => { - subscriberInstance - .handleMessage(Message.fromGCloud(message)) - .catch((error) => { - Logger.Instance.error( - { error }, - 'Unexpected error while processing message', - ); - message.nack(); - }); + subscription.on('message', (gCloudMessage: GoogleCloudMessage): void => { + const message = Message.fromGCloud(gCloudMessage); + subscriberInstance.handleMessage(message).catch((err) => { + Logger.Instance.error( + { err, ...Logger.getInfo(metadata, message) }, + 'Unexpected error while processing message', + ); + message.nack(); + }); }); subscription.on('error', (error) => subscriberInstance.handleError(error)); } - private log(message: string, metadata?: SubscriberTuple[1]): void { - Logger.Instance.info({ metadata }, chalk.green.bold(message)); - } - - private async updateMetaData(subscriber: SubscriberTuple) { - const { ackDeadlineSeconds, retryPolicy, deadLetterPolicy, labels } = - await this.getMergedSubscriptionOptions(subscriber); + private async updateMetaData( + subscriber: SubscriberTuple, + dlqTopic: GoogleCloudTopic | undefined, + ) { + const [, metadata] = subscriber; + const { ackDeadline, retryPolicy, deadLetterPolicy, labels } = + metadata.options; const toUpdateOptions: GoogleSubscriptionMetadata = { labels, - ackDeadlineSeconds, retryPolicy, - deadLetterPolicy, + // This is different because GCP's api has different properties when creating/updating subscriptions + ackDeadlineSeconds: ackDeadline, + ...(deadLetterPolicy && dlqTopic + ? { + deadLetterPolicy: { + ...deadLetterPolicy, + deadLetterTopic: dlqTopic.name, + }, + } + : undefined), }; await this.getSubscription(subscriber).setMetadata(toUpdateOptions); + Logger.Instance.info( + Logger.getInfo(metadata), + ' 🔄 Updated subscription metadata', + ); } /** @@ -168,153 +185,43 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { subscriber: SubscriberTuple, ): Promise { const [, metadata] = subscriber; + const subscription = this.getSubscription(subscriber); - if (await this.subscriptionExists(subscriber)) { + const [subscriptionExists] = await subscription.exists(); + if (subscriptionExists) { Logger.Instance.info( - { metadata }, - chalk.gray(` ✔️ ${metadata.subscriptionName} already exists.`), + Logger.getInfo(metadata), + chalk.gray(` ✔️ Subscription already exists`), ); - await this.updateMetaData(subscriber); - } else { - const topic = await this.createOrGetTopic( - metadata.topicName, - metadata.options, - ); - await this.createSubscription(topic, subscriber); + return subscription; } - return this.getSubscription(subscriber); - } - - private async createDeadLetterDefaultSubscriber( - subscriber: SubscriberTuple, - ): Promise { - const [, metadata] = subscriber; - try { - const { client } = this.getProject(metadata.options); - const deadLetterPolicy = metadata.options?.deadLetterPolicy; - - if (!deadLetterPolicy?.deadLetterTopic) return; - - const defaultSubscriberName = - deadLetterPolicy?.deadLetterTopic + '.default'; - const [defaultSubscriberExists] = await client - .subscription(defaultSubscriberName) - .exists(); - - if (defaultSubscriberExists) return; - - const topic = await this.createOrGetTopic( - deadLetterPolicy?.deadLetterTopic, - {}, - ); - - await topic.createSubscription(defaultSubscriberName, { - expirationPolicy: { - ttl: null, - }, - }); - } catch (err) { - Logger.Instance.error( - { metadata, err }, - `Error while creating default deadLetter subscription for ${metadata.subscriptionName}`, - ); - } - } - private async getMergedSubscriptionOptions( - subscriber: SubscriberTuple, - ): Promise { - const subscriberOptions = subscriber[1].options; - const ackDeadlineSeconds = subscriberOptions?.ackDeadline; - const labels = subscriberOptions?.labels || {}; - try { - const labelsStringified = - process.env.GOOGLE_CLOUD_LABELS || process.env.PUBSUB_LABELS; - if (labelsStringified) { - const parsedLabels = JSON.parse(labelsStringified); - Object.entries(parsedLabels).forEach(([key, val]) => { - if (labels[key] == null) { - labels[key] = val as string; - } - }); - } - } catch (err) { - this.log('Invalid GOOGLE_CLOUD_LABELS'); - } - return { - ...subscriberOptions, - labels, - ackDeadlineSeconds, - ...(await this.mergeDeadLetterPolicy(subscriber[1].options)), - }; - } + const topic = await this.createOrGetTopic(metadata.topicName, { + ...metadata.options, + // Subscriptions shouldn't apply any labels to topics + labels: undefined, + }); - private async createSubscription( - topic: GoogleCloudTopic, - subscriber: SubscriberTuple, - ): Promise { - const [, metadata] = subscriber; try { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { deadLetterPolicy, ...optionsWithoutDlq } = metadata.options; await topic.createSubscription( metadata.subscriptionName, - await this.getMergedSubscriptionOptions(subscriber), + // Don't assign dlq until we create DLQ topic and assign roles later + optionsWithoutDlq, ); Logger.Instance.info( - { metadata }, - chalk.gray(` ✔️ ${metadata.subscriptionName} created.`), + Logger.getInfo(metadata), + chalk.gray(` ✔️ Subscription created`), ); } catch (err) { Logger.Instance.error( - { metadata, err }, - ` ❌ There was an error creating "${metadata.subscriptionName}" subscription.`, + { err, ...Logger.getInfo(metadata) }, + ` ❌ Error creating subscription`, ); throw err; } - } - - private async mergeDeadLetterPolicy( - options: SubscriberOptions | undefined, - ): Promise { - if (!options?.deadLetterPolicy) return; - return { - ...options, - deadLetterPolicy: { - ...options.deadLetterPolicy, - deadLetterTopic: await this.createDeadLetterTopic( - options.deadLetterPolicy, - options, - ), - }, - }; - } - - private async createDeadLetterTopic( - policy: NonNullable, - options?: SubscriberOptions, - ): Promise { - const topic = await this.createOrGetTopic(policy.deadLetterTopic, options); - return topic.name; - } - - private async checkDeadLetterConfiguration(subscriber: SubscriberTuple) { - const [, metadata] = subscriber; - const { options } = metadata; - const { client } = this.getProject(options); - const deadLetterTopic = options?.deadLetterPolicy?.deadLetterTopic; - if (!deadLetterTopic) { - return; - } - - const [subscriptions] = await client - .topic(deadLetterTopic) - .getSubscriptions(); - - if (subscriptions.length === 0) { - Logger.Instance.warn( - { metadata }, - `Please set createDefaultSubscription: true in deadLetterPolicy to create default subscriber for dead letter topic of ${metadata.subscriptionName}. Ignore if already added subscription for it.`, - ); - } + return subscription; } private async handleDeadLetterPolicyConfigurations( @@ -322,96 +229,25 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { ) { const [, metadata] = subscriber; const { options } = metadata; - if (!options?.deadLetterPolicy) { + if (!options.deadLetterPolicy) { return; } - await this.bindPolicyToSubscriber(metadata); - await this.bindPolicyToDeadLetterTopic( - options.deadLetterPolicy.deadLetterTopic, - options, - metadata, - ); - if (options?.deadLetterPolicy?.createDefaultSubscription) { - await this.createDeadLetterDefaultSubscriber(subscriber); - } else { - await this.checkDeadLetterConfiguration(subscriber); - } - } - - private async bindPolicyToSubscriber( - metadata: SubscriberMetadata, - ): Promise { - const { - topicName: subscriptionTopicName, - subscriptionName, - options, - } = metadata; const project = this.getProject(options); - const projectNumber = await getProjectNumber(project); - - if (!projectNumber) { - Logger.Instance.warn( - { metadata }, - ` ❌ Could not bind policy for "${subscriptionName}" subscriber due to no project number`, - ); - return; - } - - try { - const pubSubTopic = project.client.topic(subscriptionTopicName); - const myPolicy = { - bindings: [ - { - role: 'roles/pubsub.subscriber', - members: [ - `serviceAccount:service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`, - ], - }, - ], - }; - await pubSubTopic.subscription(subscriptionName).iam.setPolicy(myPolicy); - } catch (err) { - Logger.Instance.error( - { metadata, err }, - ` ❌ Error while binding policy for "${subscriptionName}" subscription.`, - ); - } - } - - private async bindPolicyToDeadLetterTopic( - deadLetterTopicName: string, - options: { project?: GooglePubSubProject }, - metadata: SubscriberMetadata, - ): Promise { - const project = this.getProject(options); - const projectNumber = await getProjectNumber(project); - if (!projectNumber) { - Logger.Instance.warn( - { metadata }, - ` ❌ Could not bind policy for "${deadLetterTopicName}" DLQ topic due to no project number`, - ); - return; - } + const dlqTopicName = options.deadLetterPolicy.deadLetterTopic; + const dlqTopic = await this.createOrGetTopic(dlqTopicName, { + project: options.project, + // DLQ topic's labels are same as subscription + labels: options.labels, + }); - try { - const pubSubTopic = project.client.topic(deadLetterTopicName); - const myPolicy = { - bindings: [ - { - role: 'roles/pubsub.publisher', - members: [ - `serviceAccount:service-${projectNumber}@gcp-sa-pubsub.iam.gserviceaccount.com`, - ], - }, - ], - }; - await pubSubTopic.iam.setPolicy(myPolicy); - } catch (err) { - Logger.Instance.error( - { metadata, err }, - ` ❌ Error while binding policy for "${deadLetterTopicName}" DLQ topic.`, - ); + await bindPolicyToSubscriber(metadata, project); + await bindPolicyToDeadLetterTopic(dlqTopic, metadata, project); + if (options.deadLetterPolicy?.createDefaultSubscription) { + await createDeadLetterDefaultSubscriber(dlqTopic, metadata, project); + } else { + await checkDeadLetterConfiguration(dlqTopic, metadata); } + return dlqTopic; } private getSubscription( @@ -421,18 +257,12 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { return getSubscription(this.getProject(metadata.options), subscriber); } - private async subscriptionExists( - subscriber: SubscriberTuple, - ): Promise { - const [subscriptionExists] = await this.getSubscription( - subscriber, - ).exists(); - return subscriptionExists; - } - protected async createOrGetTopic( topicName: string, - options?: { project?: GooglePubSubProject }, + options: { + project?: GooglePubSubProject; + labels?: GoogleSubscriptionMetadata['labels']; + } = {}, ): Promise { const project = this.getProject(options); const cachedTopic = project.topics.get(topicName); @@ -443,6 +273,22 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { const pubSubTopic = project.client.topic(topicName); const [topic] = await pubSubTopic.get({ autoCreate: true }); + + const labelsToSet = options.labels ?? {}; + if (Object.keys(labelsToSet).length > 0) { + const existingLabels = (await topic.getMetadata())[0].labels ?? {}; + const diff = Object.entries(labelsToSet).filter(([k, v]) => { + if (!existingLabels[k] || existingLabels[k] !== v) { + return true; + } + return false; + }); + if (diff.length > 0) { + await topic.setMetadata({ + labels: options.labels, + }); + } + } project.topics.set(topicName, topic); return topic; } @@ -452,10 +298,10 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { Object.values(this.projects), async (project) => { const projectSubs = getAllSubscriptions(project); - return projectSubs.map(({ metadata }) => { + return projectSubs.map(({ name, metadata }) => { return { - topicName: metadata?.topic, - subscriptionName: metadata?.name || '', + topicName: getNameFromResourceName(metadata?.topic ?? ''), + subscriptionName: getNameFromResourceName(name), }; }); }, @@ -467,8 +313,8 @@ export default class GooglePubSubAdapter implements PubSubClientV2 { const subscriptions = Object.values(this.projects).map((project) => { const projectSubs = getAllSubscriptions(project); return projectSubs.map( - ({ isOpen, metadata }) => - [metadata?.name?.split('/')?.slice(-1)[0], isOpen] as IsOpenTuple, + ({ isOpen, name }) => + [getNameFromResourceName(name), isOpen] as IsOpenTuple, ); }); diff --git a/src/client/googlePubSub/subscriptions.ts b/src/client/googlePubSub/subscriptions.ts index 04b2bc31..4bfc4602 100644 --- a/src/client/googlePubSub/subscriptions.ts +++ b/src/client/googlePubSub/subscriptions.ts @@ -17,7 +17,17 @@ export function getSubscription( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return subscriptions.get(metadata.subscriptionName)!; } - // NOTE: Each client can handle a max of 20 subs, but limiting to 15 https://jira.deliveryhero.com/browse/PUB-72 + /** + * NOTE: Each client can handle a max of 20 subs, but limiting to 15 + * @see https://jira.deliveryhero.com/browse/PUB-72 + * + * > By default each PubSub instance can handle 100 open streams, + * > with default options this translates to less than 20 Subscriptions per PubSub instance. + * If you wish to create more Subscriptions than that, + * you can either create multiple PubSub instances or + * lower the options.streamingOptions.maxStreams value on each Subscription object + * @see https://googleapis.dev/nodejs/pubsub/latest/Subscription.html + */ const isNewClientNeeded = Math.floor(subscriptions.size / 15) > _clients.length - 1; diff --git a/src/index.ts b/src/index.ts index a858669b..180f28b5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,4 @@ +// TODO: Remove this in next major version require('dotenv').config({ path: require('find-config')('.env') }); import Topic, { Payload, TopicOptions } from './topic'; import { diff --git a/src/interface/GooglePubSubProject.ts b/src/interface/GooglePubSubProject.ts index e5db8e9b..0055295a 100644 --- a/src/interface/GooglePubSubProject.ts +++ b/src/interface/GooglePubSubProject.ts @@ -2,7 +2,7 @@ import { CredentialBody } from 'google-auth-library'; export interface GooglePubSubProject { id: string; - credentials: CredentialBody; + credentials?: CredentialBody; } export default GooglePubSubProject; diff --git a/src/interface/publishOptions.ts b/src/interface/publishOptions.ts index 3f7c568a..763f8bb3 100644 --- a/src/interface/publishOptions.ts +++ b/src/interface/publishOptions.ts @@ -1,4 +1,4 @@ -import type { Attributes } from '@google-cloud/pubsub'; +import type { Attributes, TopicMetadata } from '@google-cloud/pubsub'; type RecursivePartial = { [P in keyof T]?: RecursivePartial; }; @@ -61,9 +61,9 @@ export interface TopicPublishOptions { * This is the the actual type for use in the driver */ export interface PublishOptions { - retryConfig?: RetryConfig; attributes?: Attributes; - + retryConfig?: RetryConfig; + labels?: TopicMetadata['labels']; /** * If true msg will be gzip compressed before being published */ diff --git a/src/service/logger.ts b/src/service/logger.ts index 7b3ed4a3..d5e41235 100644 --- a/src/service/logger.ts +++ b/src/service/logger.ts @@ -1,9 +1,13 @@ +import type { SubscriberMetadata } from '../subscriber'; +import type { default as Message } from '../message'; + export interface LoggerOptions { info: (...args: any[]) => void; debug?: (...args: any[]) => void; error: (...args: any[]) => void; warn: (...args: any[]) => void; } + export class Logger { private static logger: LoggerOptions; public static set Instance(logger: LoggerOptions) { @@ -12,7 +16,35 @@ export class Logger { public static get Instance(): LoggerOptions { return Logger.logger ?? console; } + + public static getInfo( + metadata: SubscriberMetadata, + message?: Message, + ): { + pubsub: Record; + } { + const { topicName, subscriptionName } = metadata ?? {}; + + let pubsub: Record = { + topicName, + subscriptionName, + }; + + if (message?.gCloudMessage) { + pubsub = { + ...pubsub, + messageId: message.gCloudMessage.id, + publishTime: message.gCloudMessage.publishTime, + deliveryAttempt: message.gCloudMessage.deliveryAttempt, + }; + } + + return { + pubsub, + }; + } } + export const setLogger = (logger: LoggerOptions): void => { Logger.Instance = logger; }; diff --git a/src/service/pubsub.ts b/src/service/pubsub.ts index 662a9114..4ba6d499 100644 --- a/src/service/pubsub.ts +++ b/src/service/pubsub.ts @@ -20,14 +20,13 @@ export default class PubSubService { this.initDriver(); this.initClient(); this.startServer(); - this.bind(this); } private startServer(): void { if (process.env.PUBSUB_HEALTH_SERVER !== 'true') return; if (this.server) return; - const port = process.env.PUBSUB_SERVER_PORT || 8080; + const port = process.env.PUBSUB_SERVER_PORT || process.env.PORT || 8080; //create a server object: this.server = http .createServer(function (_req, res) { @@ -70,11 +69,6 @@ export default class PubSubService { return !(notOpenSubs.length || subsState.length !== allSubs.length); } - private bind(instance: PubSubService): void { - this.subscribe = this.subscribe.bind(instance); - this.publish = this.publish.bind(instance); - } - private initDriver(): void { if (this.syncDriverIsEnabled()) { PubSubService.driver = 'synchronous'; @@ -131,6 +125,7 @@ export default class PubSubService { for (const subscription of subscribers) { await PubSubService.client.close(subscription); } + Logger.Instance.info(` ❎ All subscriptions closed successfully.`); PubSubService.status = 'closed'; if (this.server) { await new Promise((resolve, reject) => { @@ -138,7 +133,8 @@ export default class PubSubService { if (err) { reject(err); } else { - resolve(this.server); + this.server = undefined; + resolve(null); } }); }); @@ -174,15 +170,14 @@ export default class PubSubService { } catch (err) { const [, metadata] = subscription; Logger.Instance.error( - { metadata, err }, - ` ❌ Error while initializing "${metadata.subscriptionName}" subscription.`, + { ...Logger.getInfo(metadata), err }, + ` ❌ Error while initializing subscription, "${metadata.subscriptionName}"`, + ); + const error = Object.assign( + new Error('Error while initializing subscription'), + Logger.getInfo(metadata), + { cause: err }, ); - const error: Error & { - originalError?: Error; - metadata?: typeof metadata; - } = new Error('Error while initializing subscription.'); - error.originalError = err as Error; - error.metadata = metadata; throw error; } }, diff --git a/src/service/subscription.ts b/src/service/subscription.ts index adf610da..3c050851 100644 --- a/src/service/subscription.ts +++ b/src/service/subscription.ts @@ -48,14 +48,14 @@ export default class SubscriptionService { * Applications should override this with custom error handling: log error, cleanup resources and exit the process. * Default logs the error and **rethrows** */ - public static handleError(error: Error, metadata: SubscriberMetadata): void { + public static handleError(err: Error, metadata: SubscriberMetadata): void { // default error handling logic Logger.Instance.error( - { error, metadata }, + { err, ...Logger.getInfo(metadata) }, 'Received unexpected error in subscription', ); // To keep backwards compatibility with no error handler - throw error; + throw err; } /** diff --git a/src/subscriber/subscriberV2.ts b/src/subscriber/subscriberV2.ts index 4e45d30d..977febd1 100644 --- a/src/subscriber/subscriberV2.ts +++ b/src/subscriber/subscriberV2.ts @@ -2,6 +2,7 @@ import { SubscriberOptions as GoogleCloudSubscriberOptions, SubscriptionMetadata as GoogleSubscriptionMetadata, } from '@google-cloud/pubsub'; +import { getMergedLabels } from '../utils'; import { GooglePubSubProject } from '../interface/GooglePubSubProject'; import SubscriptionService from '../service/subscription'; import Message from '../message'; @@ -22,7 +23,7 @@ export default class SubscriberV2 { this.metadata = { topicName, subscriptionName, - options, + options: options ?? {}, }; } public async init(): Promise { @@ -30,8 +31,7 @@ export default class SubscriberV2 { } public async handleMessage(message: Message): Promise { - this.subscriberObject?.handleMessage && - this.subscriberObject?.handleMessage(message); + return this.subscriberObject?.handleMessage?.(message); } public handleError(error: Error): void { @@ -53,15 +53,17 @@ export default class SubscriberV2 { subscriptionServiceDefaultOptions: SubscriberOptions, ): SubscriberV2 { const subscriberObject: SubscriberObject = { ...subscriber }; + const labels = getMergedLabels({ + ...subscriptionServiceDefaultOptions?.labels, + ...subscriberObject.options?.labels, + }); + // TODO: Use deepmerge instead subscriberObject.options = { ...defaultSubscriberOptions, ...subscriptionServiceDefaultOptions, ...subscriberObject.options, - labels: { - ...subscriptionServiceDefaultOptions?.labels, - ...subscriberObject.options?.labels, - }, + labels, }; return new SubscriberV2(subscriberObject); } @@ -107,11 +109,11 @@ export interface SubscriberOptions extends GoogleCloudSubscriberOptions { export interface SubscriberMetadata { topicName: string; subscriptionName: string; + options: SubscriberOptions; description?: string; - options?: SubscriberOptions; } -export interface MessageHandler { +interface MessageHandler { /** * will run every time a message is received */ @@ -128,12 +130,14 @@ export interface MessageHandler { handleError?: (error: Error) => void; } -export interface FlexibleObject { +interface FlexibleObject { // eslint-disable-next-line @typescript-eslint/no-explicit-any [key: string]: any; } export interface SubscriberObject - extends SubscriberMetadata, + extends Omit, MessageHandler, - FlexibleObject {} + FlexibleObject { + options?: SubscriberOptions; +} diff --git a/src/topic/index.ts b/src/topic/index.ts index 5cf5b6ab..dbb8995d 100644 --- a/src/topic/index.ts +++ b/src/topic/index.ts @@ -1,3 +1,5 @@ +import { TopicMetadata } from '@google-cloud/pubsub'; +import { getMergedLabels } from '../utils'; import PubSubService from '../service/pubsub'; import { PublishOptions, @@ -26,6 +28,7 @@ export interface Payload { type PayloadInput

= Omit; export interface TopicOptions { addTimeStamp?: boolean; + labels?: TopicMetadata['labels']; retryConfig?: RetryConfig; enableGZipCompression?: boolean; } @@ -35,25 +38,39 @@ export interface TopicProperties { project?: GooglePubSubProject; } +export const defaultOptions: Omit = { + // TODO: Disable this in next major version + addTimeStamp: true, + retryConfig: { + retryCodes: [ + 10, // 'ABORTED' + 1, // 'CANCELLED', + 4, // 'DEADLINE_EXCEEDED' + 13, // 'INTERNAL' + 8, // 'RESOURCE_EXHAUSTED' + 14, // 'UNAVAILABLE' + 2, // 'UNKNOWN' + ], + backoffSettings: { + initialRetryDelayMillis: 100, + retryDelayMultiplier: 1.3, + maxRetryDelayMillis: 60000, + initialRpcTimeoutMillis: 5000, + rpcTimeoutMultiplier: 1.0, + maxRpcTimeoutMillis: 600000, + totalTimeoutMillis: 600000, + }, + }, +}; + export default class Topic

{ public static readonly topicName: string; public static project?: GooglePubSubProject; - public options: TopicOptions = { - addTimeStamp: true, - retryConfig: { - retryCodes: [10, 1, 4, 13, 8, 14, 2], - backoffSettings: { - initialRetryDelayMillis: 100, - retryDelayMultiplier: 1.3, - maxRetryDelayMillis: 60000, - initialRpcTimeoutMillis: 5000, - rpcTimeoutMultiplier: 1.0, - maxRpcTimeoutMillis: 600000, - totalTimeoutMillis: 600000, - }, - }, - }; + private _finalOptions: (PublishOptions & TopicOptions) | undefined; + + // TODO: Make options static in next major version to so it's easy to merge + public options: TopicOptions = defaultOptions; private mq: PubSubService; public constructor() { @@ -61,6 +78,7 @@ export default class Topic

{ (this.constructor as typeof Topic).validateTopic( (this.constructor as typeof Topic).topicName, ); + this.options.labels = getMergedLabels(this.options); } /** @@ -82,39 +100,61 @@ export default class Topic

{ message; } + private getFinalOptions(): PublishOptions & TopicOptions { + if (this._finalOptions) { + return this._finalOptions; + } + const base: PublishOptions & TopicOptions = { + ...defaultOptions, + ...this.options, + labels: getMergedLabels(this.options), + }; + + if (this.options.retryConfig) { + base.retryConfig = { + ...base.retryConfig, + ...this.options.retryConfig, + backoffSettings: { + ...base.retryConfig?.backoffSettings, + ...this.options.retryConfig?.backoffSettings, + }, + }; + } + this._finalOptions = base; + return base; + } + public async publish( message: PayloadInput

, options?: TopicPublishOptions, ): Promise { this.validateMessage(message); - let publishOptions = { ...options }; - if (this.options.enableGZipCompression) { - publishOptions.enableGZipCompression = true; - } - if (this.options.retryConfig) { - publishOptions = { - ...publishOptions, + let finalOptions = this.getFinalOptions(); + if (options) { + finalOptions = { + ...finalOptions, + ...options, retryConfig: { - ...this.options?.retryConfig, - ...publishOptions?.retryConfig, + ...finalOptions.retryConfig, + ...options.retryConfig, backoffSettings: { - ...this.options?.retryConfig?.backoffSettings, - ...publishOptions?.retryConfig?.backoffSettings, + ...finalOptions.retryConfig?.backoffSettings, + ...options.retryConfig?.backoffSettings, }, }, - }; + } as PublishOptions; } return this.mq.publish( this.constructor as typeof Topic, - this.options?.addTimeStamp !== false + finalOptions.addTimeStamp !== false ? { ...message, _timestamp: new Date().toISOString(), } : message, - publishOptions as PublishOptions, + finalOptions, ); } } diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 00000000..f1476d88 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,40 @@ +import { SubscriptionMetadata } from '@google-cloud/pubsub'; +import { Logger } from './service/logger'; + +export function getMergedLabels(options?: { + labels?: SubscriptionMetadata['labels']; +}): Record | undefined { + const labels = options?.labels || {}; + try { + const labelsStringified = + process.env.GOOGLE_CLOUD_LABELS || process.env.PUBSUB_LABELS; + if (labelsStringified) { + const parsedLabels = JSON.parse(labelsStringified); + Object.entries(parsedLabels).forEach(([key, val]) => { + // Env var is only set if the label doesn't exist in options + if (labels[key] == null) { + labels[key] = String(val); + } + }); + } + } catch (err) { + Logger.Instance.warn( + { err }, + `Invalid ${ + process.env.GOOGLE_CLOUD_LABELS + ? 'GOOGLE_CLOUD_LABELS' + : 'PUBSUB_LABELS' + }, ignoring env var.`, + ); + } + + if (Object.keys(labels).length === 0) { + // Don't reset existing labels if no labels are set in options/env var + return undefined; + } + return labels; +} + +export function getNameFromResourceName(resourceName: string): string { + return resourceName.split('/')?.slice(-1)[0]; +} diff --git a/tsconfig.build.json b/tsconfig.build.json index bb493326..ffd71086 100644 --- a/tsconfig.build.json +++ b/tsconfig.build.json @@ -1,12 +1,21 @@ { - "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./dist/", + "rootDir": "./src", "declaration": true, "sourceMap": true, "declarationMap": true, - "removeComments": true, - "noEmit": false + "noEmit": false, + "esModuleInterop": true, + "module": "commonjs", + "moduleResolution": "node", + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noUnusedParameters": true, + "forceConsistentCasingInFileNames": true, + "strict": true, + "target": "es2019", + "lib": ["es2019"] }, "exclude": [ "node_modules", diff --git a/tsconfig.json b/tsconfig.json index 192ae0bb..b3135d3a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,29 +1,21 @@ { + "extends": "./tsconfig.build.json", "compilerOptions": { "allowJs": true, "checkJs": true, - "esModuleInterop": true, - "module": "commonjs", - "moduleResolution": "node", - "noFallthroughCasesInSwitch": true, - "noImplicitReturns": true, - "noUnusedParameters": true, - "forceConsistentCasingInFileNames": true, "noEmit": true, - "outDir": "./dist/", - "removeComments": true, - "strict": true, - "target": "es2019", - "baseUrl": "./src", + "baseUrl": "./", + "rootDir": "./", "paths": { - "@honestfoodcompany/pubsub": ["./index.ts"], - "@deliveryhero/pubsub": ["./index.ts"] + "@honestfoodcompany/pubsub": ["./src/index.ts"], + "@deliveryhero/pubsub": ["./src/index.ts"] } }, "exclude": ["node_modules", "dist/**/*"], "include": [ "src/**/*", "scripts/**/*", + "src/__tests__/**/*", "__tests__/**/*", "examples/**/*", "jest.config.js", diff --git a/yarn.lock b/yarn.lock index 8aa678eb..f3b24f26 100644 --- a/yarn.lock +++ b/yarn.lock @@ -165,6 +165,16 @@ __metadata: languageName: node linkType: hard +"@ampproject/remapping@npm:^2.2.0": + version: 2.3.0 + resolution: "@ampproject/remapping@npm:2.3.0" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: d3ad7b89d973df059c4e8e6d7c972cbeb1bb2f18f002a3bd04ae0707da214cb06cc06929b65aa2313b9347463df2914772298bae8b1d7973f246bb3f2ab3e8f0 + languageName: node + linkType: hard + "@babel/code-frame@npm:7.10.4": version: 7.10.4 resolution: "@babel/code-frame@npm:7.10.4" @@ -202,6 +212,16 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/code-frame@npm:7.24.7" + dependencies: + "@babel/highlight": ^7.24.7 + picocolors: ^1.0.0 + checksum: 830e62cd38775fdf84d612544251ce773d544a8e63df667728cc9e0126eeef14c6ebda79be0f0bc307e8318316b7f58c27ce86702e0a1f5c321d842eb38ffda4 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.13.11, @babel/compat-data@npm:^7.16.0": version: 7.16.0 resolution: "@babel/compat-data@npm:7.16.0" @@ -209,6 +229,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.25.2": + version: 7.25.4 + resolution: "@babel/compat-data@npm:7.25.4" + checksum: b12a91d27c3731a4b0bdc9312a50b1911f41f7f728aaf0d4b32486e2257fd2cb2d3ea1a295e98449600c48f2c7883a3196ca77cda1cef7d97a10c2e83d037974 + languageName: node + linkType: hard + "@babel/core@npm:7.12.9": version: 7.12.9 resolution: "@babel/core@npm:7.12.9" @@ -233,7 +260,30 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.1.0, @babel/core@npm:^7.12.16, @babel/core@npm:^7.12.3, @babel/core@npm:^7.7.2, @babel/core@npm:^7.7.5": +"@babel/core@npm:^7.1.0, @babel/core@npm:^7.7.2, @babel/core@npm:^7.8.0": + version: 7.25.2 + resolution: "@babel/core@npm:7.25.2" + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.0 + "@babel/helper-compilation-targets": ^7.25.2 + "@babel/helper-module-transforms": ^7.25.2 + "@babel/helpers": ^7.25.0 + "@babel/parser": ^7.25.0 + "@babel/template": ^7.25.0 + "@babel/traverse": ^7.25.2 + "@babel/types": ^7.25.2 + convert-source-map: ^2.0.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.3 + semver: ^6.3.1 + checksum: 9a1ef604a7eb62195f70f9370cec45472a08114e3934e3eaaedee8fd754edf0730e62347c7b4b5e67d743ce57b5bb8cf3b92459482ca94d06e06246ef021390a + languageName: node + linkType: hard + +"@babel/core@npm:^7.12.16, @babel/core@npm:^7.12.3": version: 7.16.0 resolution: "@babel/core@npm:7.16.0" dependencies: @@ -279,6 +329,30 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/generator@npm:7.24.7" + dependencies: + "@babel/types": ^7.24.7 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^2.5.1 + checksum: 0ff31a73b15429f1287e4d57b439bba4a266f8c673bb445fe313b82f6d110f586776997eb723a777cd7adad9d340edd162aea4973a90112c5d0cfcaf6686844b + languageName: node + linkType: hard + +"@babel/generator@npm:^7.25.0, @babel/generator@npm:^7.25.4": + version: 7.25.5 + resolution: "@babel/generator@npm:7.25.5" + dependencies: + "@babel/types": ^7.25.4 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^2.5.1 + checksum: d7713f02536a8144eca810e9b13ae854b05fec462348eaf52e7b50df2c0a312bc43bfff0e8e10d6dd982e8986d61175ac8e67d7358a8b4dad9db4d6733bf0c9c + languageName: node + linkType: hard + "@babel/helper-annotate-as-pure@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-annotate-as-pure@npm:7.16.0" @@ -312,6 +386,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-compilation-targets@npm:7.25.2" + dependencies: + "@babel/compat-data": ^7.25.2 + "@babel/helper-validator-option": ^7.24.8 + browserslist: ^4.23.1 + lru-cache: ^5.1.1 + semver: ^6.3.1 + checksum: aed33c5496cb9db4b5e2d44e26bf8bc474074cc7f7bb5ebe1d4a20fdeb362cb3ba9e1596ca18c7484bcd6e5c3a155ab975e420d520c0ae60df81f9de04d0fd16 + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-create-class-features-plugin@npm:7.16.0" @@ -365,6 +452,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-environment-visitor@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-environment-visitor@npm:7.24.7" + dependencies: + "@babel/types": ^7.24.7 + checksum: 079d86e65701b29ebc10baf6ed548d17c19b808a07aa6885cc141b690a78581b180ee92b580d755361dc3b16adf975b2d2058b8ce6c86675fcaf43cf22f2f7c6 + languageName: node + linkType: hard + "@babel/helper-explode-assignable-expression@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-explode-assignable-expression@npm:7.16.0" @@ -395,6 +491,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-function-name@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-function-name@npm:7.24.7" + dependencies: + "@babel/template": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 142ee08922074dfdc0ff358e09ef9f07adf3671ab6eef4fca74dcf7a551f1a43717e7efa358c9e28d7eea84c28d7f177b7a58c70452fc312ae3b1893c5dab2a4 + languageName: node + linkType: hard + "@babel/helper-get-function-arity@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-get-function-arity@npm:7.16.0" @@ -422,6 +528,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-hoist-variables@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-hoist-variables@npm:7.24.7" + dependencies: + "@babel/types": ^7.24.7 + checksum: 6cfdcf2289cd12185dcdbdf2435fa8d3447b797ac75851166de9fc8503e2fd0021db6baf8dfbecad3753e582c08e6a3f805c8d00cbed756060a877d705bd8d8d + languageName: node + linkType: hard + "@babel/helper-member-expression-to-functions@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-member-expression-to-functions@npm:7.16.0" @@ -440,6 +555,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-module-imports@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: 8ac15d96d262b8940bc469052a048e06430bba1296369be695fabdf6799f201dd0b00151762b56012a218464e706bc033f27c07f6cec20c6f8f5fd6543c67054 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-module-transforms@npm:7.16.0" @@ -456,6 +581,20 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.25.2": + version: 7.25.2 + resolution: "@babel/helper-module-transforms@npm:7.25.2" + dependencies: + "@babel/helper-module-imports": ^7.24.7 + "@babel/helper-simple-access": ^7.24.7 + "@babel/helper-validator-identifier": ^7.24.7 + "@babel/traverse": ^7.25.2 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 282d4e3308df6746289e46e9c39a0870819630af5f84d632559171e4fae6045684d771a65f62df3d569e88ccf81dc2def78b8338a449ae3a94bb421aa14fc367 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-optimise-call-expression@npm:7.16.0" @@ -511,6 +650,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-simple-access@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-simple-access@npm:7.24.7" + dependencies: + "@babel/traverse": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: ddbf55f9dea1900213f2a1a8500fabfd21c5a20f44dcfa957e4b0d8638c730f88751c77f678644f754f1a1dc73f4eb8b766c300deb45a9daad000e4247957819 + languageName: node + linkType: hard + "@babel/helper-skip-transparent-expression-wrappers@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.16.0" @@ -538,6 +687,15 @@ __metadata: languageName: node linkType: hard +"@babel/helper-split-export-declaration@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-split-export-declaration@npm:7.24.7" + dependencies: + "@babel/types": ^7.24.7 + checksum: e3ddc91273e5da67c6953f4aa34154d005a00791dc7afa6f41894e768748540f6ebcac5d16e72541aea0c89bee4b89b4da6a3d65972a0ea8bfd2352eda5b7e22 + languageName: node + linkType: hard + "@babel/helper-string-parser@npm:^7.23.4": version: 7.23.4 resolution: "@babel/helper-string-parser@npm:7.23.4" @@ -545,6 +703,20 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-string-parser@npm:7.24.7" + checksum: 09568193044a578743dd44bf7397940c27ea693f9812d24acb700890636b376847a611cdd0393a928544e79d7ad5b8b916bd8e6e772bc8a10c48a647a96e7b1a + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-string-parser@npm:7.24.8" + checksum: 39b03c5119216883878655b149148dc4d2e284791e969b19467a9411fccaa33f7a713add98f4db5ed519535f70ad273cdadfd2eb54d47ebbdeac5083351328ce + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.15.7": version: 7.15.7 resolution: "@babel/helper-validator-identifier@npm:7.15.7" @@ -559,6 +731,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/helper-validator-identifier@npm:7.24.7" + checksum: 6799ab117cefc0ecd35cd0b40ead320c621a298ecac88686a14cffceaac89d80cdb3c178f969861bf5fa5e4f766648f9161ea0752ecfe080d8e89e3147270257 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-validator-option@npm:7.14.5" @@ -566,6 +745,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.24.8": + version: 7.24.8 + resolution: "@babel/helper-validator-option@npm:7.24.8" + checksum: a52442dfa74be6719c0608fee3225bd0493c4057459f3014681ea1a4643cd38b68ff477fe867c4b356da7330d085f247f0724d300582fa4ab9a02efaf34d107c + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.16.0": version: 7.16.0 resolution: "@babel/helper-wrap-function@npm:7.16.0" @@ -589,6 +775,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/helpers@npm:7.25.0" + dependencies: + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 739e3704ff41a30f5eaac469b553f4d3ab02be6ced083f5925851532dfbd9efc5c347728e77b754ed0b262a4e5e384e60932a62c192d338db7e4b7f3adf9f4a7 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.16.0": version: 7.16.0 resolution: "@babel/highlight@npm:7.16.0" @@ -611,7 +807,19 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.16, @babel/parser@npm:^7.12.7, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.16.0, @babel/parser@npm:^7.7.2": +"@babel/highlight@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/highlight@npm:7.24.7" + dependencies: + "@babel/helper-validator-identifier": ^7.24.7 + chalk: ^2.4.2 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: 5cd3a89f143671c4ac129960024ba678b669e6fc673ce078030f5175002d1d3d52bc10b22c5b916a6faf644b5028e9a4bd2bb264d053d9b05b6a98690f1d46f1 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.12.16, @babel/parser@npm:^7.12.7, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.16.0": version: 7.16.0 resolution: "@babel/parser@npm:7.16.0" bin: @@ -620,6 +828,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.20.7, @babel/parser@npm:^7.25.0, @babel/parser@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/parser@npm:7.25.4" + dependencies: + "@babel/types": ^7.25.4 + bin: + parser: ./bin/babel-parser.js + checksum: fe4f083d4ad34f019dd7fad672cd007003004fb0a3df9b7315a5da9a5e8e56c1fed95acab6862e7d76cfccb2e8e364bcc307e9117718e6bb6dfb2e87ad065abf + languageName: node + linkType: hard + "@babel/parser@npm:^7.23.9": version: 7.23.9 resolution: "@babel/parser@npm:7.23.9" @@ -629,6 +848,15 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/parser@npm:7.24.7" + bin: + parser: ./bin/babel-parser.js + checksum: fc9d2c4c8712f89672edc55c0dc5cf640dcec715b56480f111f85c2bc1d507e251596e4110d65796690a96ac37a4b60432af90b3e97bb47e69d4ef83872dbbd6 + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.16.0": version: 7.16.0 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.16.0" @@ -1697,7 +1925,29 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.13, @babel/traverse@npm:^7.12.9, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.16.0, @babel/traverse@npm:^7.7.2": +"@babel/template@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/template@npm:7.24.7" + dependencies: + "@babel/code-frame": ^7.24.7 + "@babel/parser": ^7.24.7 + "@babel/types": ^7.24.7 + checksum: ea90792fae708ddf1632e54c25fe1a86643d8c0132311f81265d2bdbdd42f9f4fac65457056c1b6ca87f7aa0d6a795b549566774bba064bdcea2034ab3960ee9 + languageName: node + linkType: hard + +"@babel/template@npm:^7.25.0": + version: 7.25.0 + resolution: "@babel/template@npm:7.25.0" + dependencies: + "@babel/code-frame": ^7.24.7 + "@babel/parser": ^7.25.0 + "@babel/types": ^7.25.0 + checksum: 3f2db568718756d0daf2a16927b78f00c425046b654cd30b450006f2e84bdccaf0cbe6dc04994aa1f5f6a4398da2f11f3640a4d3ee31722e43539c4c919c817b + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.12.13, @babel/traverse@npm:^7.12.9, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.16.0": version: 7.23.9 resolution: "@babel/traverse@npm:7.23.9" dependencies: @@ -1715,6 +1965,39 @@ __metadata: languageName: node linkType: hard +"@babel/traverse@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/traverse@npm:7.24.7" + dependencies: + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.24.7 + "@babel/helper-environment-visitor": ^7.24.7 + "@babel/helper-function-name": ^7.24.7 + "@babel/helper-hoist-variables": ^7.24.7 + "@babel/helper-split-export-declaration": ^7.24.7 + "@babel/parser": ^7.24.7 + "@babel/types": ^7.24.7 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: 7cd366afe9e7ee77e493779fdf24f67bf5595247289364f4689e29688572505eaeb886d7a8f20ebb9c29fc2de7d0895e4ff9e203e78e39ac67239724d45aa83b + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.25.2, @babel/traverse@npm:^7.7.2": + version: 7.25.4 + resolution: "@babel/traverse@npm:7.25.4" + dependencies: + "@babel/code-frame": ^7.24.7 + "@babel/generator": ^7.25.4 + "@babel/parser": ^7.25.4 + "@babel/template": ^7.25.0 + "@babel/types": ^7.25.4 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: 3b6d879b9d843b119501585269b3599f047011ae21eb7820d00aef62fc3a2bcdaf6f4cdf2679795a2d7c0b6b5d218974916e422f08dea08613dc42188ef21e4b + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.12.6, @babel/types@npm:^7.12.7, @babel/types@npm:^7.16.0, @babel/types@npm:^7.3.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": version: 7.16.0 resolution: "@babel/types@npm:7.16.0" @@ -1725,6 +2008,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.20.7, @babel/types@npm:^7.25.0, @babel/types@npm:^7.25.2, @babel/types@npm:^7.25.4": + version: 7.25.4 + resolution: "@babel/types@npm:7.25.4" + dependencies: + "@babel/helper-string-parser": ^7.24.8 + "@babel/helper-validator-identifier": ^7.24.7 + to-fast-properties: ^2.0.0 + checksum: 497f8b583c54a92a59c3ec542144695064cd5c384fcca46ba1aa301d5e5dd6c1d011f312ca024cb0f9c956da07ae82fb4c348c31a30afa31a074c027720d2aa8 + languageName: node + linkType: hard + "@babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.6, @babel/types@npm:^7.23.9": version: 7.23.9 resolution: "@babel/types@npm:7.23.9" @@ -1736,6 +2030,17 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.24.7": + version: 7.24.7 + resolution: "@babel/types@npm:7.24.7" + dependencies: + "@babel/helper-string-parser": ^7.24.7 + "@babel/helper-validator-identifier": ^7.24.7 + to-fast-properties: ^2.0.0 + checksum: 3e4437fced97e02982972ce5bebd318c47d42c9be2152c0fd28c6f786cc74086cc0a8fb83b602b846e41df37f22c36254338eada1a47ef9d8a1ec92332ca3ea8 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -2673,48 +2978,48 @@ __metadata: languageName: node linkType: hard -"@jest/console@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/console@npm:27.3.1" +"@jest/console@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/console@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 - jest-message-util: ^27.3.1 - jest-util: ^27.3.1 + jest-message-util: ^27.5.1 + jest-util: ^27.5.1 slash: ^3.0.0 - checksum: 80e3d9d3ccadfd83df5ce0ab02348d350c9821beedad080760da484099757eb5fbc6d3dcba417c6a80ddc5776ce3b924bd650041a83ff56773c98b7d965711aa + checksum: 7cb20f06a34b09734c0342685ec53aa4c401fe3757c13a9c58fce76b971a322eb884f6de1068ef96f746e5398e067371b89515a07c268d4440a867c87748a706 languageName: node linkType: hard -"@jest/core@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/core@npm:27.3.1" +"@jest/core@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/core@npm:27.5.1" dependencies: - "@jest/console": ^27.3.1 - "@jest/reporters": ^27.3.1 - "@jest/test-result": ^27.3.1 - "@jest/transform": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/console": ^27.5.1 + "@jest/reporters": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 emittery: ^0.8.1 exit: ^0.1.2 - graceful-fs: ^4.2.4 - jest-changed-files: ^27.3.0 - jest-config: ^27.3.1 - jest-haste-map: ^27.3.1 - jest-message-util: ^27.3.1 - jest-regex-util: ^27.0.6 - jest-resolve: ^27.3.1 - jest-resolve-dependencies: ^27.3.1 - jest-runner: ^27.3.1 - jest-runtime: ^27.3.1 - jest-snapshot: ^27.3.1 - jest-util: ^27.3.1 - jest-validate: ^27.3.1 - jest-watcher: ^27.3.1 + graceful-fs: ^4.2.9 + jest-changed-files: ^27.5.1 + jest-config: ^27.5.1 + jest-haste-map: ^27.5.1 + jest-message-util: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-resolve-dependencies: ^27.5.1 + jest-runner: ^27.5.1 + jest-runtime: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 + jest-watcher: ^27.5.1 micromatch: ^4.0.4 rimraf: ^3.0.0 slash: ^3.0.0 @@ -2724,71 +3029,71 @@ __metadata: peerDependenciesMeta: node-notifier: optional: true - checksum: f21d0d1fe931b4dfa5bcb811b60c8e15345e2d22a60473152903ff2062035d5b7b1039ff8f5c1d0f2c984e91f64ea21142a4e97ec007854708c4b2236d934ad7 + checksum: 904a94ad8f1b43cd6b48de3b0226659bff3696150ff8cf7680fc2faffdc8a115203bb9ab6e817c1f79f9d6a81f67953053cbc64d8a4604f2e0c42a04c28cf126 languageName: node linkType: hard -"@jest/environment@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/environment@npm:27.3.1" +"@jest/environment@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/environment@npm:27.5.1" dependencies: - "@jest/fake-timers": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/fake-timers": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" - jest-mock: ^27.3.0 - checksum: 8eb31d7565d3f04ab77fb26d111b848e82ec64a2eabb064b37f0a1bca92b40e69aec91cbef04994b44af3455f6325b03efe8ad4f1154d2c0e59c6560aa2621b9 + jest-mock: ^27.5.1 + checksum: 2a9e18c35a015508dbec5b90b21c150230fa6c1c8cb8fabe029d46ee2ca4c40eb832fb636157da14c66590d0a4c8a2c053226b041f54a44507d6f6a89abefd66 languageName: node linkType: hard -"@jest/fake-timers@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/fake-timers@npm:27.3.1" +"@jest/fake-timers@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/fake-timers@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 "@sinonjs/fake-timers": ^8.0.1 "@types/node": "*" - jest-message-util: ^27.3.1 - jest-mock: ^27.3.0 - jest-util: ^27.3.1 - checksum: 6ebf8c91c48b5a064bb0596414aa0f2eb240030121683120e05b44acda2777d4ddd2a17fb0a532aa95f724e2b3c0acf149702f8a235b1553b5d8d2316f17a08a + jest-message-util: ^27.5.1 + jest-mock: ^27.5.1 + jest-util: ^27.5.1 + checksum: 02a0561ed2f4586093facd4ae500b74694f187ac24d4a00e949a39a1c5325bca8932b4fcb0388a2c5ed0656506fc1cf51fd3e32cdd48cea7497ad9c6e028aba8 languageName: node linkType: hard -"@jest/globals@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/globals@npm:27.3.1" +"@jest/globals@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/globals@npm:27.5.1" dependencies: - "@jest/environment": ^27.3.1 - "@jest/types": ^27.2.5 - expect: ^27.3.1 - checksum: cefae4249b8b02789b6bd43b003004ab65305ad172dc77aa27cffd84b3d9590ac9592764dd580148f72a49d49446adec44945b901799f4cda7640ca8e8b5e0aa + "@jest/environment": ^27.5.1 + "@jest/types": ^27.5.1 + expect: ^27.5.1 + checksum: 087f97047e9dcf555f76fe2ce54aee681e005eaa837a0c0c2d251df6b6412c892c9df54cb871b180342114389a5ff895a4e52e6e6d3d0015bf83c02a54f64c3c languageName: node linkType: hard -"@jest/reporters@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/reporters@npm:27.3.1" +"@jest/reporters@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/reporters@npm:27.5.1" dependencies: "@bcoe/v8-coverage": ^0.2.3 - "@jest/console": ^27.3.1 - "@jest/test-result": ^27.3.1 - "@jest/transform": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/console": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 collect-v8-coverage: ^1.0.0 exit: ^0.1.2 glob: ^7.1.2 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 istanbul-lib-coverage: ^3.0.0 - istanbul-lib-instrument: ^4.0.3 + istanbul-lib-instrument: ^5.1.0 istanbul-lib-report: ^3.0.0 istanbul-lib-source-maps: ^4.0.0 - istanbul-reports: ^3.0.2 - jest-haste-map: ^27.3.1 - jest-resolve: ^27.3.1 - jest-util: ^27.3.1 - jest-worker: ^27.3.1 + istanbul-reports: ^3.1.3 + jest-haste-map: ^27.5.1 + jest-resolve: ^27.5.1 + jest-util: ^27.5.1 + jest-worker: ^27.5.1 slash: ^3.0.0 source-map: ^0.6.0 string-length: ^4.0.1 @@ -2799,78 +3104,78 @@ __metadata: peerDependenciesMeta: node-notifier: optional: true - checksum: ac095baa19d825149110e61263ec35b4e460358809b6ed08dedb0a257672725affcb5f26a2cd0dc515a62648beaa0febe615ac9507b30c9c54117a486ce47875 + checksum: faba5eafb86e62b62e152cafc8812d56308f9d1e8b77f3a7dcae4a8803a20a60a0909cc43ed73363ef649bf558e4fb181c7a336d144c89f7998279d1882bb69e languageName: node linkType: hard -"@jest/source-map@npm:^27.0.6": - version: 27.0.6 - resolution: "@jest/source-map@npm:27.0.6" +"@jest/source-map@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/source-map@npm:27.5.1" dependencies: callsites: ^3.0.0 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 source-map: ^0.6.0 - checksum: b4c09a0392e58a970b1bede96cd995279d95254efc997acff7fb44ad52fd4e4a372ce955c32777d1eac2006c3869b7d97227126d45a28612a40815823e3cbdb0 + checksum: 4fb1e743b602841babf7e22bd84eca34676cb05d4eb3b604cae57fc59e406099f5ac759ac1a0d04d901237d143f0f4f234417306e823bde732a1d19982230862 languageName: node linkType: hard -"@jest/test-result@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/test-result@npm:27.3.1" +"@jest/test-result@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/test-result@npm:27.5.1" dependencies: - "@jest/console": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/console": ^27.5.1 + "@jest/types": ^27.5.1 "@types/istanbul-lib-coverage": ^2.0.0 collect-v8-coverage: ^1.0.0 - checksum: 228976bf1a08ba6047f7b4a92c4f55c1e039d35e6d349c952e63d54a76c32b5d87a24cae85a778c7e9321573f9c47266dbb0c34cffe9762fb80a1307f2960461 + checksum: 338f7c509d6a3bc6d7dd7388c8f6f548b87638e171dc1fddfedcacb4e8950583288832223ba688058cbcf874b937d22bdc0fa88f79f5fc666f77957e465c06a5 languageName: node linkType: hard -"@jest/test-sequencer@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/test-sequencer@npm:27.3.1" +"@jest/test-sequencer@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/test-sequencer@npm:27.5.1" dependencies: - "@jest/test-result": ^27.3.1 - graceful-fs: ^4.2.4 - jest-haste-map: ^27.3.1 - jest-runtime: ^27.3.1 - checksum: 385f020770010222954a658fdc104df2116c9ed65f5010cd17a5934382f89791ab5238d76b0bc28d6d69c965e0e1a2742d7313bf9bfc704a80eb66fdafacc2a5 + "@jest/test-result": ^27.5.1 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 + jest-runtime: ^27.5.1 + checksum: f21f9c8bb746847f7f89accfd29d6046eec1446f0b54e4694444feaa4df379791f76ef0f5a4360aafcbc73b50bc979f68b8a7620de404019d3de166be6720cb0 languageName: node linkType: hard -"@jest/transform@npm:^27.3.1": - version: 27.3.1 - resolution: "@jest/transform@npm:27.3.1" +"@jest/transform@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/transform@npm:27.5.1" dependencies: "@babel/core": ^7.1.0 - "@jest/types": ^27.2.5 - babel-plugin-istanbul: ^6.0.0 + "@jest/types": ^27.5.1 + babel-plugin-istanbul: ^6.1.1 chalk: ^4.0.0 convert-source-map: ^1.4.0 fast-json-stable-stringify: ^2.0.0 - graceful-fs: ^4.2.4 - jest-haste-map: ^27.3.1 - jest-regex-util: ^27.0.6 - jest-util: ^27.3.1 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-util: ^27.5.1 micromatch: ^4.0.4 - pirates: ^4.0.1 + pirates: ^4.0.4 slash: ^3.0.0 source-map: ^0.6.1 write-file-atomic: ^3.0.0 - checksum: e72afd601122f9013386bfa4e56c753cb55a4eb1e3e1de17bc115bf70a4051dd9640b942ed92a7cf87a3a5ef5c744a12ec40f1c72a96a231c3c2582ae9109287 + checksum: a22079121aedea0f20a03a9c026be971f7b92adbfb4d5fd1fb67be315741deac4f056936d7c72a53b24aa5a1071bc942c003925fd453bf3f6a0ae5da6384e137 languageName: node linkType: hard -"@jest/types@npm:^27.2.5": - version: 27.2.5 - resolution: "@jest/types@npm:27.2.5" +"@jest/types@npm:^27.5.1": + version: 27.5.1 + resolution: "@jest/types@npm:27.5.1" dependencies: "@types/istanbul-lib-coverage": ^2.0.0 "@types/istanbul-reports": ^3.0.0 "@types/node": "*" "@types/yargs": ^16.0.0 chalk: ^4.0.0 - checksum: 322603c24354a5333b5b7a670464422a46e0244a5a96a35552a7018eb4ac2e84c3b7657336b0ea6aa114963f9b6d0da8b8f6f963cb044fea9e7bc04d464b0ab1 + checksum: d1f43cc946d87543ddd79d49547aab2399481d34025d5c5f2025d3d99c573e1d9832fa83cef25e9d9b07a8583500229d15bbb07b8e233d127d911d133e2f14b1 languageName: node linkType: hard @@ -2885,6 +3190,17 @@ __metadata: languageName: node linkType: hard +"@jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.5 + resolution: "@jridgewell/gen-mapping@npm:0.3.5" + dependencies: + "@jridgewell/set-array": ^1.2.1 + "@jridgewell/sourcemap-codec": ^1.4.10 + "@jridgewell/trace-mapping": ^0.3.24 + checksum: ff7a1764ebd76a5e129c8890aa3e2f46045109dabde62b0b6c6a250152227647178ff2069ea234753a690d8f3c4ac8b5e7b267bbee272bffb7f3b0a370ab6e52 + languageName: node + linkType: hard + "@jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.1 resolution: "@jridgewell/resolve-uri@npm:3.1.1" @@ -2899,6 +3215,13 @@ __metadata: languageName: node linkType: hard +"@jridgewell/set-array@npm:^1.2.1": + version: 1.2.1 + resolution: "@jridgewell/set-array@npm:1.2.1" + checksum: 832e513a85a588f8ed4f27d1279420d8547743cc37fcad5a5a76fc74bb895b013dfe614d0eed9cb860048e6546b798f8f2652020b4b2ba0561b05caa8c654b10 + languageName: node + linkType: hard + "@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": version: 1.4.15 resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" @@ -2916,6 +3239,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" + dependencies: + "@jridgewell/resolve-uri": ^3.1.0 + "@jridgewell/sourcemap-codec": ^1.4.14 + checksum: 9d3c40d225e139987b50c48988f8717a54a8c994d8a948ee42e1412e08988761d0754d7d10b803061cc3aebf35f92a5dbbab493bd0e1a9ef9e89a2130e83ba34 + languageName: node + linkType: hard + "@manypkg/find-root@npm:^1.1.0": version: 1.1.0 resolution: "@manypkg/find-root@npm:1.1.0" @@ -3157,20 +3490,20 @@ __metadata: linkType: hard "@sinonjs/commons@npm:^1.7.0": - version: 1.8.3 - resolution: "@sinonjs/commons@npm:1.8.3" + version: 1.8.6 + resolution: "@sinonjs/commons@npm:1.8.6" dependencies: type-detect: 4.0.8 - checksum: 6159726db5ce6bf9f2297f8427f7ca5b3dff45b31e5cee23496f1fa6ef0bb4eab878b23fb2c5e6446381f6a66aba4968ef2fc255c1180d753d4b8c271636a2e5 + checksum: 7d3f8c1e85f30cd4e83594fc19b7a657f14d49eb8d95a30095631ce15e906c869e0eff96c5b93dffea7490c00418b07f54582ba49c6560feb2a8c34c0b16832d languageName: node linkType: hard "@sinonjs/fake-timers@npm:^8.0.1": - version: 8.0.1 - resolution: "@sinonjs/fake-timers@npm:8.0.1" + version: 8.1.0 + resolution: "@sinonjs/fake-timers@npm:8.1.0" dependencies: "@sinonjs/commons": ^1.7.0 - checksum: 97a78e6f83dd420d73b155a0438cd0fd3392e706b8314530db3d99354689cc714eb3d18540be2aedcd3a3d6070e14f509dce7c6cc817701e9538b3b8ac423eaa + checksum: 09b5a158ce013a6c37613258bad79ca4efeb99b1f59c41c73cca36cac00b258aefcf46eeea970fccf06b989414d86fe9f54c1102272c0c3bdd51a313cea80949 languageName: node linkType: hard @@ -3363,7 +3696,20 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.14": +"@types/babel__core@npm:^7.0.0": + version: 7.20.5 + resolution: "@types/babel__core@npm:7.20.5" + dependencies: + "@babel/parser": ^7.20.7 + "@babel/types": ^7.20.7 + "@types/babel__generator": "*" + "@types/babel__template": "*" + "@types/babel__traverse": "*" + checksum: a3226f7930b635ee7a5e72c8d51a357e799d19cbf9d445710fa39ab13804f79ab1a54b72ea7d8e504659c7dfc50675db974b526142c754398d7413aa4bc30845 + languageName: node + linkType: hard + +"@types/babel__core@npm:^7.1.14": version: 7.1.16 resolution: "@types/babel__core@npm:7.1.16" dependencies: @@ -3395,7 +3741,7 @@ __metadata: languageName: node linkType: hard -"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.4, @types/babel__traverse@npm:^7.0.6": +"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.6": version: 7.14.2 resolution: "@types/babel__traverse@npm:7.14.2" dependencies: @@ -3404,6 +3750,15 @@ __metadata: languageName: node linkType: hard +"@types/babel__traverse@npm:^7.0.4": + version: 7.20.6 + resolution: "@types/babel__traverse@npm:7.20.6" + dependencies: + "@babel/types": ^7.20.7 + checksum: 2bdc65eb62232c2d5c1086adeb0c31e7980e6fd7e50a3483b4a724a1a1029c84d9cb59749cf8de612f9afa2bc14c85b8f50e64e21f8a4398fa77eb9059a4283c + languageName: node + linkType: hard + "@types/bluebird@npm:^3.5.36": version: 3.5.36 resolution: "@types/bluebird@npm:3.5.36" @@ -3479,11 +3834,11 @@ __metadata: linkType: hard "@types/graceful-fs@npm:^4.1.2": - version: 4.1.5 - resolution: "@types/graceful-fs@npm:4.1.5" + version: 4.1.9 + resolution: "@types/graceful-fs@npm:4.1.9" dependencies: "@types/node": "*" - checksum: d076bb61f45d0fc42dee496ef8b1c2f8742e15d5e47e90e20d0243386e426c04d4efd408a48875ab432f7960b4ce3414db20ed0fbbfc7bcc89d84e574f6e045a + checksum: 79d746a8f053954bba36bd3d94a90c78de995d126289d656fb3271dd9f1229d33f678da04d10bce6be440494a5a73438e2e363e92802d16b8315b051036c5256 languageName: node linkType: hard @@ -3529,12 +3884,12 @@ __metadata: linkType: hard "@types/jest@npm:^27.0.2": - version: 27.0.2 - resolution: "@types/jest@npm:27.0.2" + version: 27.5.2 + resolution: "@types/jest@npm:27.5.2" dependencies: - jest-diff: ^27.0.0 + jest-matcher-utils: ^27.0.0 pretty-format: ^27.0.0 - checksum: 814ad5f5d2f277849f47e52906da4b745758e555630fc8cb46a071bde648eefeffb1b35710c530a8cea7fc4ea7c1d813812c120484bf7902ab6c5e473cdd49c9 + checksum: 7e11c6826aa429ad990dc262e4e4b54aa36573287fddf15773e4137f07d11d3105f0dd9f1baff73252160a057df23f5529bb83b1bf83cd3f45f9460a5ca5c22e languageName: node linkType: hard @@ -3641,9 +3996,9 @@ __metadata: linkType: hard "@types/prettier@npm:^2.1.5": - version: 2.4.1 - resolution: "@types/prettier@npm:2.4.1" - checksum: df330c2d6fe7c282839b0f17701e069a9c6c96d2ff54704e933a1b3c1b98844d963a7cb00c5629d173604892ceee802312bbaeb8a97f5da21e13db8f653b519e + version: 2.7.3 + resolution: "@types/prettier@npm:2.7.3" + checksum: 705384209cea6d1433ff6c187c80dcc0b95d99d5c5ce21a46a9a58060c527973506822e428789d842761e0280d25e3359300f017fbe77b9755bc772ab3dc2f83 languageName: node linkType: hard @@ -3733,11 +4088,11 @@ __metadata: linkType: hard "@types/yargs@npm:^16.0.0": - version: 16.0.4 - resolution: "@types/yargs@npm:16.0.4" + version: 16.0.9 + resolution: "@types/yargs@npm:16.0.9" dependencies: "@types/yargs-parser": "*" - checksum: caa21d2c957592fe2184a8368c8cbe5a82a6c2e2f2893722e489f842dc5963293d2f3120bc06fe3933d60a3a0d1e2eb269649fd6b1947fe1820f8841ba611dd9 + checksum: 00d9276ed4e0f17a78c1ed57f644a8c14061959bd5bfab113d57f082ea4b663ba97f71b89371304a34a2dba5061e9ae4523e357e577ba61834d661f82c223bf8 languageName: node linkType: hard @@ -4016,9 +4371,9 @@ __metadata: linkType: hard "abab@npm:^2.0.3, abab@npm:^2.0.5": - version: 2.0.5 - resolution: "abab@npm:2.0.5" - checksum: 0ec951b46d5418c2c2f923021ec193eaebdb4e802ffd5506286781b454be722a13a8430f98085cd3e204918401d9130ec6cc8f5ae19be315b3a0e857d83196e1 + version: 2.0.6 + resolution: "abab@npm:2.0.6" + checksum: 6ffc1af4ff315066c62600123990d87551ceb0aafa01e6539da77b0f5987ac7019466780bf480f1787576d4385e3690c81ccc37cfda12819bf510b8ab47e5a3e languageName: node linkType: hard @@ -4109,7 +4464,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.4, acorn@npm:^8.2.4, acorn@npm:^8.4.1": +"acorn@npm:^8.0.4, acorn@npm:^8.4.1": version: 8.5.0 resolution: "acorn@npm:8.5.0" bin: @@ -4118,6 +4473,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.2.4": + version: 8.12.1 + resolution: "acorn@npm:8.12.1" + bin: + acorn: bin/acorn + checksum: 677880034aee5bdf7434cc2d25b641d7bedb0b5ef47868a78dadabedccf58e1c5457526d9d8249cd253f2df087e081c3fe7d903b448d8e19e5131a3065b83c07 + languageName: node + linkType: hard + "acorn@npm:^8.7.1": version: 8.8.2 resolution: "acorn@npm:8.8.2" @@ -4606,21 +4970,21 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^27.3.1": - version: 27.3.1 - resolution: "babel-jest@npm:27.3.1" +"babel-jest@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-jest@npm:27.5.1" dependencies: - "@jest/transform": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 "@types/babel__core": ^7.1.14 - babel-plugin-istanbul: ^6.0.0 - babel-preset-jest: ^27.2.0 + babel-plugin-istanbul: ^6.1.1 + babel-preset-jest: ^27.5.1 chalk: ^4.0.0 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 slash: ^3.0.0 peerDependencies: "@babel/core": ^7.8.0 - checksum: b0edc7ee345bb66b8e223f1db78081cc9e4684eee276730f341f7089b20e590e98938f76cfce4a72e3734f0c5cee166745c85aa61eca486a3f78b0e3ba07f82b + checksum: 4e93e6e9fb996cc5f1505e924eb8e8cc7b25c294ba9629762a2715390f48af6a4c14dbb84cd9730013ac0e03267a5a9aa2fb6318c544489cda7f50f4e506def4 languageName: node linkType: hard @@ -4678,7 +5042,7 @@ __metadata: languageName: node linkType: hard -"babel-plugin-istanbul@npm:^6.0.0": +"babel-plugin-istanbul@npm:^6.1.1": version: 6.1.1 resolution: "babel-plugin-istanbul@npm:6.1.1" dependencies: @@ -4691,15 +5055,15 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^27.2.0": - version: 27.2.0 - resolution: "babel-plugin-jest-hoist@npm:27.2.0" +"babel-plugin-jest-hoist@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-plugin-jest-hoist@npm:27.5.1" dependencies: "@babel/template": ^7.3.3 "@babel/types": ^7.3.3 "@types/babel__core": ^7.0.0 "@types/babel__traverse": ^7.0.6 - checksum: de6c19b5469310f14b4e1408032b9bbe86fc1f77e7b804c2b808d738045d3890cd7c55b36c4815b49f732843c472d7a5fe0b733cffd5e2284c11d8f1e2ff677e + checksum: 709c17727aa8fd3be755d256fb514bf945a5c2ea6017f037d80280fc44ae5fe7dfeebf63d8412df53796455c2c216119d628d8cc90b099434fd819005943d058 languageName: node linkType: hard @@ -4761,15 +5125,15 @@ __metadata: languageName: node linkType: hard -"babel-preset-jest@npm:^27.2.0": - version: 27.2.0 - resolution: "babel-preset-jest@npm:27.2.0" +"babel-preset-jest@npm:^27.5.1": + version: 27.5.1 + resolution: "babel-preset-jest@npm:27.5.1" dependencies: - babel-plugin-jest-hoist: ^27.2.0 + babel-plugin-jest-hoist: ^27.5.1 babel-preset-current-node-syntax: ^1.0.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: c484e6e7c61616f4e2b2aeef54a2a48a1c64949cfb1c21884c7595d422997407049a3185f1536a419c344399df1e04f67d5e335f05c720c3b14859db079a674d + checksum: 251bcea11c18fd9672fec104eadb45b43f117ceeb326fa7345ced778d4c1feab29343cd7a87a1dcfae4997d6c851a8b386d7f7213792da6e23b74f4443a8976d languageName: node linkType: hard @@ -5030,6 +5394,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.23.1": + version: 4.23.3 + resolution: "browserslist@npm:4.23.3" + dependencies: + caniuse-lite: ^1.0.30001646 + electron-to-chromium: ^1.5.4 + node-releases: ^2.0.18 + update-browserslist-db: ^1.1.0 + bin: + browserslist: cli.js + checksum: 7906064f9970aeb941310b2fcb8b4ace4a1b50aa657c986677c6f1553a8cabcc94ee9c5922f715baffbedaa0e6cf0831b6fed7b059dde6873a4bfadcbe069c7e + languageName: node + linkType: hard + "bs-logger@npm:0.x": version: 0.2.6 resolution: "bs-logger@npm:0.2.6" @@ -5226,6 +5604,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001646": + version: 1.0.30001653 + resolution: "caniuse-lite@npm:1.0.30001653" + checksum: 289cf06c26a46f3e6460ccd5feffa788ab0ab35d306898c48120c65cfb11959bfa560e9f739393769b4fd01150c69b0747ad3ad5ec3abf3dfafd66df3c59254e + languageName: node + linkType: hard + "ccount@npm:^1.0.0, ccount@npm:^1.0.3": version: 1.1.0 resolution: "ccount@npm:1.1.0" @@ -5823,7 +6208,14 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0": +"convert-source-map@npm:^1.4.0, convert-source-map@npm:^1.6.0": + version: 1.9.0 + resolution: "convert-source-map@npm:1.9.0" + checksum: dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8 + languageName: node + linkType: hard + +"convert-source-map@npm:^1.7.0": version: 1.8.0 resolution: "convert-source-map@npm:1.8.0" dependencies: @@ -5832,6 +6224,13 @@ __metadata: languageName: node linkType: hard +"convert-source-map@npm:^2.0.0": + version: 2.0.0 + resolution: "convert-source-map@npm:2.0.0" + checksum: 63ae9933be5a2b8d4509daca5124e20c14d023c820258e484e32dc324d34c2754e71297c94a05784064ad27615037ef677e3f0c00469fb55f409d2bb21261035 + languageName: node + linkType: hard + "cookie-signature@npm:1.0.6": version: 1.0.6 resolution: "cookie-signature@npm:1.0.6" @@ -6349,9 +6748,9 @@ __metadata: linkType: hard "decimal.js@npm:^10.2.1": - version: 10.3.1 - resolution: "decimal.js@npm:10.3.1" - checksum: 0351ac9f05fe050f23227aa6a4573bee2d58fa7378fcf28d969a8c789525032effb488a90320fd3fe86a66e17b4bc507d811b15eada5b7f0e7ec5d2af4c24a59 + version: 10.4.3 + resolution: "decimal.js@npm:10.4.3" + checksum: 796404dcfa9d1dbfdc48870229d57f788b48c21c603c3f6554a1c17c10195fc1024de338b0cf9e1efe0c7c167eeb18f04548979bcc5fdfabebb7cc0ae3287bae languageName: node linkType: hard @@ -6399,7 +6798,7 @@ __metadata: languageName: node linkType: hard -"deep-is@npm:^0.1.3, deep-is@npm:~0.1.3": +"deep-is@npm:^0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" checksum: edb65dd0d7d1b9c40b2f50219aef30e116cedd6fc79290e740972c132c09106d2e80aa0bc8826673dd5a00222d4179c84b36a790eef63a4c4bca75a37ef90804 @@ -6598,10 +6997,10 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^27.0.6": - version: 27.0.6 - resolution: "diff-sequences@npm:27.0.6" - checksum: f35ad024d426cd1026d6c98a1f604c41966a0e89712b05a38812fc11e645ff0e915ec17bc8f4b6910fed6df0b309b255aa6c7c77728be452c6dbbfa30aa2067b +"diff-sequences@npm:^27.5.1": + version: 27.5.1 + resolution: "diff-sequences@npm:27.5.1" + checksum: a00db5554c9da7da225db2d2638d85f8e41124eccbd56cbaefb3b276dcbb1c1c2ad851c32defe2055a54a4806f030656cbf6638105fd6ce97bb87b90b32a33ca languageName: node linkType: hard @@ -6862,6 +7261,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.4": + version: 1.5.13 + resolution: "electron-to-chromium@npm:1.5.13" + checksum: f18ac84dd3bf9a200654a6a9292b9ec4bced0cf9bd26cec9941b775f4470c581c9d043e70b37a124d9752dcc0f47fc96613d52b2defd8e59632852730cb418b9 + languageName: node + linkType: hard + "emittery@npm:^0.8.1": version: 0.8.1 resolution: "emittery@npm:0.8.1" @@ -7049,6 +7455,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.1.2": + version: 3.1.2 + resolution: "escalade@npm:3.1.2" + checksum: 1ec0977aa2772075493002bdbd549d595ff6e9393b1cb0d7d6fcaf78c750da0c158f180938365486f75cb69fba20294351caddfce1b46552a7b6c3cde52eaa02 + languageName: node + linkType: hard + "escape-goat@npm:^2.0.0": version: 2.1.1 resolution: "escape-goat@npm:2.1.1" @@ -7085,13 +7498,12 @@ __metadata: linkType: hard "escodegen@npm:^2.0.0": - version: 2.0.0 - resolution: "escodegen@npm:2.0.0" + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" dependencies: esprima: ^4.0.1 estraverse: ^5.2.0 esutils: ^2.0.2 - optionator: ^0.8.1 source-map: ~0.6.1 dependenciesMeta: source-map: @@ -7099,7 +7511,7 @@ __metadata: bin: escodegen: bin/escodegen.js esgenerate: bin/esgenerate.js - checksum: 5aa6b2966fafe0545e4e77936300cc94ad57cfe4dc4ebff9950492eaba83eef634503f12d7e3cbd644ecc1bab388ad0e92b06fd32222c9281a75d1cf02ec6cef + checksum: 096696407e161305cd05aebb95134ad176708bc5cb13d0dcc89a5fcbb959b8ed757e7f2591a5f8036f8f4952d4a724de0df14cd419e29212729fa6df5ce16bf6 languageName: node linkType: hard @@ -7471,17 +7883,15 @@ __metadata: languageName: node linkType: hard -"expect@npm:^27.3.1": - version: 27.3.1 - resolution: "expect@npm:27.3.1" +"expect@npm:^27.5.1": + version: 27.5.1 + resolution: "expect@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 - ansi-styles: ^5.0.0 - jest-get-type: ^27.3.1 - jest-matcher-utils: ^27.3.1 - jest-message-util: ^27.3.1 - jest-regex-util: ^27.0.6 - checksum: e7681ecc7ab1006a9311c66729ba7cef598671e89f48e832f319feb9bb0c79a231d30da039c09ad437e5e18d69aced2a66c102ef63eb58a2e4f39a591bba2f60 + "@jest/types": ^27.5.1 + jest-get-type: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + checksum: b2c66beb52de53ef1872165aace40224e722bca3c2274c54cfa74b6d617d55cf0ccdbf36783ccd64dbea501b280098ed33fd0b207d4f15bc03cd3c7a24364a6a languageName: node linkType: hard @@ -7618,7 +8028,7 @@ __metadata: languageName: node linkType: hard -"fast-levenshtein@npm:^2.0.6, fast-levenshtein@npm:~2.0.6": +"fast-levenshtein@npm:^2.0.6": version: 2.0.6 resolution: "fast-levenshtein@npm:2.0.6" checksum: 92cfec0a8dfafd9c7a15fba8f2cc29cd0b62b85f056d99ce448bbcd9f708e18ab2764bda4dd5158364f4145a7c72788538994f0d1787b956ef0d1062b0f7c24c @@ -8221,7 +8631,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.2.0": +"glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.2.0": version: 7.2.0 resolution: "glob@npm:7.2.0" dependencies: @@ -8235,6 +8645,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:^7.1.1, glob@npm:^7.1.2": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.1.1 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 + languageName: node + linkType: hard + "global-dirs@npm:^3.0.0": version: 3.0.0 resolution: "global-dirs@npm:3.0.0" @@ -9806,28 +10230,29 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-instrument@npm:^4.0.3": - version: 4.0.3 - resolution: "istanbul-lib-instrument@npm:4.0.3" +"istanbul-lib-instrument@npm:^5.0.4": + version: 5.1.0 + resolution: "istanbul-lib-instrument@npm:5.1.0" dependencies: - "@babel/core": ^7.7.5 + "@babel/core": ^7.12.3 + "@babel/parser": ^7.14.7 "@istanbuljs/schema": ^0.1.2 - istanbul-lib-coverage: ^3.0.0 + istanbul-lib-coverage: ^3.2.0 semver: ^6.3.0 - checksum: fa1171d3022b1bb8f6a734042620ac5d9ee7dc80f3065a0bb12863e9f0494d0eefa3d86608fcc0254ab2765d29d7dad8bdc42e5f8df2f9a1fbe85ccc59d76cb9 + checksum: 8b82e733c69fe9f94d2e21f3e5760c9bedb110329aa75df4bd40df95f1cac3bf38767e43f35b125cc547ceca7376b72ce7d95cc5238b7e9088345c7b589233d3 languageName: node linkType: hard -"istanbul-lib-instrument@npm:^5.0.4": - version: 5.1.0 - resolution: "istanbul-lib-instrument@npm:5.1.0" +"istanbul-lib-instrument@npm:^5.1.0": + version: 5.2.1 + resolution: "istanbul-lib-instrument@npm:5.2.1" dependencies: "@babel/core": ^7.12.3 "@babel/parser": ^7.14.7 "@istanbuljs/schema": ^0.1.2 istanbul-lib-coverage: ^3.2.0 semver: ^6.3.0 - checksum: 8b82e733c69fe9f94d2e21f3e5760c9bedb110329aa75df4bd40df95f1cac3bf38767e43f35b125cc547ceca7376b72ce7d95cc5238b7e9088345c7b589233d3 + checksum: bf16f1803ba5e51b28bbd49ed955a736488381e09375d830e42ddeb403855b2006f850711d95ad726f2ba3f1ae8e7366de7e51d2b9ac67dc4d80191ef7ddf272 languageName: node linkType: hard @@ -9853,68 +10278,68 @@ __metadata: languageName: node linkType: hard -"istanbul-reports@npm:^3.0.2": - version: 3.0.5 - resolution: "istanbul-reports@npm:3.0.5" +"istanbul-reports@npm:^3.1.3": + version: 3.1.7 + resolution: "istanbul-reports@npm:3.1.7" dependencies: html-escaper: ^2.0.0 istanbul-lib-report: ^3.0.0 - checksum: b167411c4cd551aec39c8275ef42f25e7083caa5a467c1b35f33b19f37211656ebf03f1cbe5c55d691b44398314dcc73be52dc6b7afb13b7a1a02eb65d702a75 + checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95 languageName: node linkType: hard -"jest-changed-files@npm:^27.3.0": - version: 27.3.0 - resolution: "jest-changed-files@npm:27.3.0" +"jest-changed-files@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-changed-files@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 execa: ^5.0.0 throat: ^6.0.1 - checksum: add4a688ad9be26bc4ae1801737d84f3d57d10d3542b6af67b61ca5cdf1365e08ae4e10b27bf773e41bba29f61f1a0f52b773ec321d0e26e2f7a99cd5f21c551 + checksum: 95e9dc74c3ca688ef85cfeab270f43f8902721a6c8ade6ac2459459a77890c85977f537d6fb809056deaa6d9c3f075fa7d2699ff5f3bf7d3fda17c3760b79b15 languageName: node linkType: hard -"jest-circus@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-circus@npm:27.3.1" +"jest-circus@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-circus@npm:27.5.1" dependencies: - "@jest/environment": ^27.3.1 - "@jest/test-result": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/environment": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 dedent: ^0.7.0 - expect: ^27.3.1 + expect: ^27.5.1 is-generator-fn: ^2.0.0 - jest-each: ^27.3.1 - jest-matcher-utils: ^27.3.1 - jest-message-util: ^27.3.1 - jest-runtime: ^27.3.1 - jest-snapshot: ^27.3.1 - jest-util: ^27.3.1 - pretty-format: ^27.3.1 + jest-each: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + jest-runtime: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 + pretty-format: ^27.5.1 slash: ^3.0.0 stack-utils: ^2.0.3 throat: ^6.0.1 - checksum: f3fc8ba6ae2623770c6d1c4808e215569c4c9b0483a8e4e8779deb98e803ea3d543c18e096a952bcc2103191dd10bf779f87594652e346209b4f26bde6acd45b + checksum: 6192dccbccb3a6acfa361cbb97bdbabe94864ccf3d885932cfd41f19534329d40698078cf9be1489415e8234255d6ea9f9aff5396b79ad842a6fca6e6fc08fd0 languageName: node linkType: hard -"jest-cli@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-cli@npm:27.3.1" +"jest-cli@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-cli@npm:27.5.1" dependencies: - "@jest/core": ^27.3.1 - "@jest/test-result": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/core": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 chalk: ^4.0.0 exit: ^0.1.2 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 import-local: ^3.0.2 - jest-config: ^27.3.1 - jest-util: ^27.3.1 - jest-validate: ^27.3.1 + jest-config: ^27.5.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 prompts: ^2.0.1 yargs: ^16.2.0 peerDependencies: @@ -9924,210 +10349,212 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: e27187aa304503c9f45b4f338dba7df5ea35f2406d615b91c611206a18d7db94e6eba3997f9b57651281b9f0ace84b132267e0803c30b05b555f1f6043c1bc47 + checksum: 6c0a69fb48e500241409e09ff743ed72bc6578d7769e2c994724e7ef1e5587f6c1f85dc429e93b98ae38a365222993ee70f0acc2199358992120900984f349e5 languageName: node linkType: hard -"jest-config@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-config@npm:27.3.1" +"jest-config@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-config@npm:27.5.1" dependencies: - "@babel/core": ^7.1.0 - "@jest/test-sequencer": ^27.3.1 - "@jest/types": ^27.2.5 - babel-jest: ^27.3.1 + "@babel/core": ^7.8.0 + "@jest/test-sequencer": ^27.5.1 + "@jest/types": ^27.5.1 + babel-jest: ^27.5.1 chalk: ^4.0.0 ci-info: ^3.2.0 deepmerge: ^4.2.2 glob: ^7.1.1 - graceful-fs: ^4.2.4 - jest-circus: ^27.3.1 - jest-environment-jsdom: ^27.3.1 - jest-environment-node: ^27.3.1 - jest-get-type: ^27.3.1 - jest-jasmine2: ^27.3.1 - jest-regex-util: ^27.0.6 - jest-resolve: ^27.3.1 - jest-runner: ^27.3.1 - jest-util: ^27.3.1 - jest-validate: ^27.3.1 + graceful-fs: ^4.2.9 + jest-circus: ^27.5.1 + jest-environment-jsdom: ^27.5.1 + jest-environment-node: ^27.5.1 + jest-get-type: ^27.5.1 + jest-jasmine2: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-runner: ^27.5.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 micromatch: ^4.0.4 - pretty-format: ^27.3.1 + parse-json: ^5.2.0 + pretty-format: ^27.5.1 + slash: ^3.0.0 + strip-json-comments: ^3.1.1 peerDependencies: ts-node: ">=9.0.0" peerDependenciesMeta: ts-node: optional: true - checksum: 1a86b03456795012cb0da16e5342bd67a6caa4f8e62f6afb82268e7da185efd16823e25e5049441b2a41b100c557950db2df52e8f5b8d23d6699923e49b7585d + checksum: 1188fd46c0ed78cbe3175eb9ad6712ccf74a74be33d9f0d748e147c107f0889f8b701fbff1567f31836ae18597dacdc43d6a8fc30dd34ade6c9229cc6c7cb82d languageName: node linkType: hard -"jest-diff@npm:^27.0.0, jest-diff@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-diff@npm:27.3.1" +"jest-diff@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-diff@npm:27.5.1" dependencies: chalk: ^4.0.0 - diff-sequences: ^27.0.6 - jest-get-type: ^27.3.1 - pretty-format: ^27.3.1 - checksum: 49231a4ac4bed1cce8f5135db2a26a83673d5cbe5716bca29900a45ae0ddf237099d9091acac436b9c60ab933b0e7ca086ce8cb71f44411b572b69adbe96128d + diff-sequences: ^27.5.1 + jest-get-type: ^27.5.1 + pretty-format: ^27.5.1 + checksum: 8be27c1e1ee57b2bb2bef9c0b233c19621b4c43d53a3c26e2c00a4e805eb4ea11fe1694a06a9fb0e80ffdcfdc0d2b1cb0b85920b3f5c892327ecd1e7bd96b865 languageName: node linkType: hard -"jest-docblock@npm:^27.0.6": - version: 27.0.6 - resolution: "jest-docblock@npm:27.0.6" +"jest-docblock@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-docblock@npm:27.5.1" dependencies: detect-newline: ^3.0.0 - checksum: 6d68b9f2bef76e0bde06a8e6d13a7e1d2fc67f61a8fa8a089727198e565510aef852a0a089c3c4157b00a82597f792fa83c8480499203978ef38d8cd6578bea0 + checksum: c0fed6d55b229d8bffdd8d03f121dd1a3be77c88f50552d374f9e1ea3bde57bf6bea017a0add04628d98abcb1bfb48b456438eeca8a74ef0053f4dae3b95d29c languageName: node linkType: hard -"jest-each@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-each@npm:27.3.1" +"jest-each@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-each@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 chalk: ^4.0.0 - jest-get-type: ^27.3.1 - jest-util: ^27.3.1 - pretty-format: ^27.3.1 - checksum: 61bbe4f5ab691049668dcc519c92f4c4ea57a279d51dd124b1e196c4bd63f7a2d81146d3bdec7dc6d5115999b74bf1a68938575bb5e051d41f499f92e2d4e715 + jest-get-type: ^27.5.1 + jest-util: ^27.5.1 + pretty-format: ^27.5.1 + checksum: b5a6d8730fd938982569c9e0b42bdf3c242f97b957ed8155a6473b5f7b540970f8685524e7f53963dc1805319f4b6602abfc56605590ca19d55bd7a87e467e63 languageName: node linkType: hard -"jest-environment-jsdom@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-environment-jsdom@npm:27.3.1" +"jest-environment-jsdom@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-environment-jsdom@npm:27.5.1" dependencies: - "@jest/environment": ^27.3.1 - "@jest/fake-timers": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/environment": ^27.5.1 + "@jest/fake-timers": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" - jest-mock: ^27.3.0 - jest-util: ^27.3.1 + jest-mock: ^27.5.1 + jest-util: ^27.5.1 jsdom: ^16.6.0 - checksum: 669c4f417a62d30ae7942c988a6bf3a224dbc1ccdca3355f0fd51523d60bad7395db31589a95f34d27eaf422f642cd308a78c34f32aa078084fa799fd50ccf8b + checksum: bc104aef7d7530d0740402aa84ac812138b6d1e51fe58adecce679f82b99340ddab73e5ec68fa079f33f50c9ddec9728fc9f0ddcca2ad6f0b351eed2762cc555 languageName: node linkType: hard -"jest-environment-node@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-environment-node@npm:27.3.1" +"jest-environment-node@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-environment-node@npm:27.5.1" dependencies: - "@jest/environment": ^27.3.1 - "@jest/fake-timers": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/environment": ^27.5.1 + "@jest/fake-timers": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" - jest-mock: ^27.3.0 - jest-util: ^27.3.1 - checksum: 40bab41957a253525b394055489568e748bea478f5b3903ff5c4e59c373adf4257788c28303dfd08e414271a3ff57cec74848a435066dcb8504865ed594e98c0 + jest-mock: ^27.5.1 + jest-util: ^27.5.1 + checksum: 0f988330c4f3eec092e3fb37ea753b0c6f702e83cd8f4d770af9c2bf964a70bc45fbd34ec6fdb6d71ce98a778d9f54afd673e63f222e4667fff289e8069dba39 languageName: node linkType: hard -"jest-get-type@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-get-type@npm:27.3.1" - checksum: b0b8db1d770c6332b4189bbf4073184489acbb1095410cf53add033daf911577ee6bd1c4f8d747dd2f3d63de42f7eb15c5527fc7288a2855a046f4a8957cd902 +"jest-get-type@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-get-type@npm:27.5.1" + checksum: 63064ab70195c21007d897c1157bf88ff94a790824a10f8c890392e7d17eda9c3900513cb291ca1c8d5722cad79169764e9a1279f7c8a9c4cd6e9109ff04bbc0 languageName: node linkType: hard -"jest-haste-map@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-haste-map@npm:27.3.1" +"jest-haste-map@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-haste-map@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 "@types/graceful-fs": ^4.1.2 "@types/node": "*" anymatch: ^3.0.3 fb-watchman: ^2.0.0 fsevents: ^2.3.2 - graceful-fs: ^4.2.4 - jest-regex-util: ^27.0.6 - jest-serializer: ^27.0.6 - jest-util: ^27.3.1 - jest-worker: ^27.3.1 + graceful-fs: ^4.2.9 + jest-regex-util: ^27.5.1 + jest-serializer: ^27.5.1 + jest-util: ^27.5.1 + jest-worker: ^27.5.1 micromatch: ^4.0.4 walker: ^1.0.7 dependenciesMeta: fsevents: optional: true - checksum: 43e1afa266121d0d76433e0758d82256ef47cef9599f70a74fbb74acd7e9f2d9269536f5a03691c65a62a0175fd0780ed44ce11880a2f8a2c926a6240af88d45 + checksum: e092a1412829a9254b4725531ee72926de530f77fda7b0d9ea18008fb7623c16f72e772d8e93be71cac9e591b2c6843a669610887dd2c89bd9eb528856e3ab47 languageName: node linkType: hard -"jest-jasmine2@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-jasmine2@npm:27.3.1" +"jest-jasmine2@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-jasmine2@npm:27.5.1" dependencies: - "@babel/traverse": ^7.1.0 - "@jest/environment": ^27.3.1 - "@jest/source-map": ^27.0.6 - "@jest/test-result": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/environment": ^27.5.1 + "@jest/source-map": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 co: ^4.6.0 - expect: ^27.3.1 + expect: ^27.5.1 is-generator-fn: ^2.0.0 - jest-each: ^27.3.1 - jest-matcher-utils: ^27.3.1 - jest-message-util: ^27.3.1 - jest-runtime: ^27.3.1 - jest-snapshot: ^27.3.1 - jest-util: ^27.3.1 - pretty-format: ^27.3.1 + jest-each: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + jest-runtime: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 + pretty-format: ^27.5.1 throat: ^6.0.1 - checksum: 6ad4e3115b0e67f4e3923a67a0bbd30da2b3f68c2227ce43f9a306f67d4d992e9fa71d39850dfc66239fb95211fe466666c70abd93d2ad59f628cca5d3ddcab7 + checksum: b716adf253ceb73db661936153394ab90d7f3a8ba56d6189b7cd4df8e4e2a4153b4e63ebb5d36e29ceb0f4c211d5a6f36ab7048c6abbd881c8646567e2ab8e6d languageName: node linkType: hard -"jest-leak-detector@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-leak-detector@npm:27.3.1" +"jest-leak-detector@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-leak-detector@npm:27.5.1" dependencies: - jest-get-type: ^27.3.1 - pretty-format: ^27.3.1 - checksum: ff3ca19d42408cb135069928e1b79d68accd62acb77a36ab9a56ae9de3d20cd0a6c1c98469eda617127d2e780a6a7e5a4e3b9c804c1d6b67afdd65d7270adae4 + jest-get-type: ^27.5.1 + pretty-format: ^27.5.1 + checksum: 5c9689060960567ddaf16c570d87afa760a461885765d2c71ef4f4857bbc3af1482c34e3cce88e50beefde1bf35e33530b020480752057a7e3dbb1ca0bae359f languageName: node linkType: hard -"jest-matcher-utils@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-matcher-utils@npm:27.3.1" +"jest-matcher-utils@npm:^27.0.0, jest-matcher-utils@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-matcher-utils@npm:27.5.1" dependencies: chalk: ^4.0.0 - jest-diff: ^27.3.1 - jest-get-type: ^27.3.1 - pretty-format: ^27.3.1 - checksum: 118c428b5509c767596a785697f8bedf90eb06278ffb76ecd57eb8eebc7c66a17dabb5960e100e7b1a91fb2638722bfec0152a3deb1162049eeb98ebe40f6caa + jest-diff: ^27.5.1 + jest-get-type: ^27.5.1 + pretty-format: ^27.5.1 + checksum: bb2135fc48889ff3fe73888f6cc7168ddab9de28b51b3148f820c89fdfd2effdcad005f18be67d0b9be80eda208ad47290f62f03d0a33f848db2dd0273c8217a languageName: node linkType: hard -"jest-message-util@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-message-util@npm:27.3.1" +"jest-message-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-message-util@npm:27.5.1" dependencies: "@babel/code-frame": ^7.12.13 - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 "@types/stack-utils": ^2.0.0 chalk: ^4.0.0 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 micromatch: ^4.0.4 - pretty-format: ^27.3.1 + pretty-format: ^27.5.1 slash: ^3.0.0 stack-utils: ^2.0.3 - checksum: 2d10734765e3e965f92b7cf009206a702e644228114bda3e20c40f59fe603422a55aa6632b4413e030bf352a03f362d321c0d881908c1d24b05e097da3ee3c4a + checksum: eb6d637d1411c71646de578c49826b6da8e33dd293e501967011de9d1916d53d845afbfb52a5b661ff1c495be7c13f751c48c7f30781fd94fbd64842e8195796 languageName: node linkType: hard -"jest-mock@npm:^27.3.0": - version: 27.3.0 - resolution: "jest-mock@npm:27.3.0" +"jest-mock@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-mock@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 "@types/node": "*" - checksum: 904b9116e03cbcd3baba08a18be88e29749c5b715ec7659665079b4aa9f54b7b87c4c7e7bf5b99fb966fefa08a25b3886e15ad31ba453104e681075ec9d8418c + checksum: f5b5904bb1741b4a1687a5f492535b7b1758dc26534c72a5423305f8711292e96a601dec966df81bb313269fb52d47227e29f9c2e08324d79529172f67311be0 languageName: node linkType: hard @@ -10143,188 +10570,181 @@ __metadata: languageName: node linkType: hard -"jest-regex-util@npm:^27.0.6": - version: 27.0.6 - resolution: "jest-regex-util@npm:27.0.6" - checksum: 4d613b00f2076560e9d5e5674ec63a4130d7b1584dbbf25d84d3a455b0ff7a12d8f94eaa00facd7934d285330d370c270ca093667d537a5842e95457e8e1ecf4 +"jest-regex-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-regex-util@npm:27.5.1" + checksum: d45ca7a9543616a34f7f3079337439cf07566e677a096472baa2810e274b9808b76767c97b0a4029b8a5b82b9d256dee28ef9ad4138b2b9e5933f6fac106c418 languageName: node linkType: hard -"jest-resolve-dependencies@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-resolve-dependencies@npm:27.3.1" +"jest-resolve-dependencies@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-resolve-dependencies@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 - jest-regex-util: ^27.0.6 - jest-snapshot: ^27.3.1 - checksum: 33b215313b3dbd8d7e772adb6a8a52f38f8ea7394b3cc2799695f8eeaf32a79235d3c325f9533344cceb7f34acee0e3927230e31678e4c927f221fe76ede748d + "@jest/types": ^27.5.1 + jest-regex-util: ^27.5.1 + jest-snapshot: ^27.5.1 + checksum: c67af97afad1da88f5530317c732bbd1262d1225f6cd7f4e4740a5db48f90ab0bd8564738ac70d1a43934894f9aef62205c1b8f8ee89e5c7a737e6a121ee4c25 languageName: node linkType: hard -"jest-resolve@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-resolve@npm:27.3.1" +"jest-resolve@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-resolve@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 chalk: ^4.0.0 - graceful-fs: ^4.2.4 - jest-haste-map: ^27.3.1 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 jest-pnp-resolver: ^1.2.2 - jest-util: ^27.3.1 - jest-validate: ^27.3.1 + jest-util: ^27.5.1 + jest-validate: ^27.5.1 resolve: ^1.20.0 resolve.exports: ^1.1.0 slash: ^3.0.0 - checksum: c3910965375050bf46bdfbfa7ad073ab8f001651db6cee610479e2e40d9adec6ae95831a3e22e26ebf09b2e50febf6a7d37a36ed866e72d69e24e29d40ec8528 + checksum: 735830e7265b20a348029738680bb2f6e37f80ecea86cda869a4c318ba3a45d39c7a3a873a22f7f746d86258c50ead6e7f501de043e201c095d7ba628a1c440f languageName: node linkType: hard -"jest-runner@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-runner@npm:27.3.1" +"jest-runner@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-runner@npm:27.5.1" dependencies: - "@jest/console": ^27.3.1 - "@jest/environment": ^27.3.1 - "@jest/test-result": ^27.3.1 - "@jest/transform": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/console": ^27.5.1 + "@jest/environment": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 emittery: ^0.8.1 - exit: ^0.1.2 - graceful-fs: ^4.2.4 - jest-docblock: ^27.0.6 - jest-environment-jsdom: ^27.3.1 - jest-environment-node: ^27.3.1 - jest-haste-map: ^27.3.1 - jest-leak-detector: ^27.3.1 - jest-message-util: ^27.3.1 - jest-resolve: ^27.3.1 - jest-runtime: ^27.3.1 - jest-util: ^27.3.1 - jest-worker: ^27.3.1 + graceful-fs: ^4.2.9 + jest-docblock: ^27.5.1 + jest-environment-jsdom: ^27.5.1 + jest-environment-node: ^27.5.1 + jest-haste-map: ^27.5.1 + jest-leak-detector: ^27.5.1 + jest-message-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-runtime: ^27.5.1 + jest-util: ^27.5.1 + jest-worker: ^27.5.1 source-map-support: ^0.5.6 throat: ^6.0.1 - checksum: 6fe50206fd190124d03a7692e282746702a1f2572df260c39b9e71a4dba2ae4bcf54e6ccc6f653e92c35289d063f6aa08f1c021a95cdfaa628c221e7cdab301b + checksum: 5bbe6cf847dd322b3332ec9d6977b54f91bd5f72ff620bc1a0192f0f129deda8aa7ca74c98922187a7aa87d8e0ce4f6c50e99a7ccb2a310bf4d94be2e0c3ce8e languageName: node linkType: hard -"jest-runtime@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-runtime@npm:27.3.1" - dependencies: - "@jest/console": ^27.3.1 - "@jest/environment": ^27.3.1 - "@jest/globals": ^27.3.1 - "@jest/source-map": ^27.0.6 - "@jest/test-result": ^27.3.1 - "@jest/transform": ^27.3.1 - "@jest/types": ^27.2.5 - "@types/yargs": ^16.0.0 +"jest-runtime@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-runtime@npm:27.5.1" + dependencies: + "@jest/environment": ^27.5.1 + "@jest/fake-timers": ^27.5.1 + "@jest/globals": ^27.5.1 + "@jest/source-map": ^27.5.1 + "@jest/test-result": ^27.5.1 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 chalk: ^4.0.0 cjs-module-lexer: ^1.0.0 collect-v8-coverage: ^1.0.0 execa: ^5.0.0 - exit: ^0.1.2 glob: ^7.1.3 - graceful-fs: ^4.2.4 - jest-haste-map: ^27.3.1 - jest-message-util: ^27.3.1 - jest-mock: ^27.3.0 - jest-regex-util: ^27.0.6 - jest-resolve: ^27.3.1 - jest-snapshot: ^27.3.1 - jest-util: ^27.3.1 - jest-validate: ^27.3.1 + graceful-fs: ^4.2.9 + jest-haste-map: ^27.5.1 + jest-message-util: ^27.5.1 + jest-mock: ^27.5.1 + jest-regex-util: ^27.5.1 + jest-resolve: ^27.5.1 + jest-snapshot: ^27.5.1 + jest-util: ^27.5.1 slash: ^3.0.0 strip-bom: ^4.0.0 - yargs: ^16.2.0 - checksum: b86c8c48126bbc04c8c6c7a05948237be6ec9e5d1bea9aeef62a7720d5d11236008137bd40e099c8359ac6d4b1fd6f6430e8329cc54fe896438f75f3c232ee27 + checksum: 929e3df0c53dab43f831f2af4e2996b22aa8cb2d6d483919d6b0426cbc100098fd5b777b998c6568b77f8c4d860b2e83127514292ff61416064f5ef926492386 languageName: node linkType: hard -"jest-serializer@npm:^27.0.6": - version: 27.0.6 - resolution: "jest-serializer@npm:27.0.6" +"jest-serializer@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-serializer@npm:27.5.1" dependencies: "@types/node": "*" - graceful-fs: ^4.2.4 - checksum: b0b8d97cb17ad4d1414769e4c81441c608cdfb7e3519afdcddc0f660dae4950cb30aad75a414dde97499c4830d961e8dff09d8683911295e299f0d86a104abdc + graceful-fs: ^4.2.9 + checksum: 803e03a552278610edc6753c0dd9fa5bb5cd3ca47414a7b2918106efb62b79fd5e9ae785d0a21f12a299fa599fea8acc1fa6dd41283328cee43962cf7df9bb44 languageName: node linkType: hard -"jest-snapshot@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-snapshot@npm:27.3.1" +"jest-snapshot@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-snapshot@npm:27.5.1" dependencies: "@babel/core": ^7.7.2 "@babel/generator": ^7.7.2 - "@babel/parser": ^7.7.2 "@babel/plugin-syntax-typescript": ^7.7.2 "@babel/traverse": ^7.7.2 "@babel/types": ^7.0.0 - "@jest/transform": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/transform": ^27.5.1 + "@jest/types": ^27.5.1 "@types/babel__traverse": ^7.0.4 "@types/prettier": ^2.1.5 babel-preset-current-node-syntax: ^1.0.0 chalk: ^4.0.0 - expect: ^27.3.1 - graceful-fs: ^4.2.4 - jest-diff: ^27.3.1 - jest-get-type: ^27.3.1 - jest-haste-map: ^27.3.1 - jest-matcher-utils: ^27.3.1 - jest-message-util: ^27.3.1 - jest-resolve: ^27.3.1 - jest-util: ^27.3.1 + expect: ^27.5.1 + graceful-fs: ^4.2.9 + jest-diff: ^27.5.1 + jest-get-type: ^27.5.1 + jest-haste-map: ^27.5.1 + jest-matcher-utils: ^27.5.1 + jest-message-util: ^27.5.1 + jest-util: ^27.5.1 natural-compare: ^1.4.0 - pretty-format: ^27.3.1 + pretty-format: ^27.5.1 semver: ^7.3.2 - checksum: e5607f15210e1428fcbdd350e461506f3e76d717d5d655a66b06fbfda5a60cc91ff50f6c04060bedbf7c93c6ea4a2d3363958c5e79203defe8d440dbb752ecdc + checksum: a5cfadf0d21cd76063925d1434bc076443ed6d87847d0e248f0b245f11db3d98ff13e45cc03b15404027dabecd712d925f47b6eae4f64986f688640a7d362514 languageName: node linkType: hard -"jest-util@npm:^27.0.0, jest-util@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-util@npm:27.3.1" +"jest-util@npm:^27.0.0, jest-util@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-util@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 "@types/node": "*" chalk: ^4.0.0 ci-info: ^3.2.0 - graceful-fs: ^4.2.4 + graceful-fs: ^4.2.9 picomatch: ^2.2.3 - checksum: 6958d418a867e537a7dc377558422879dabb61437eecc28a2fac44a61c14dc58dcf4514fb5bdc1ddaf19c414040243b2e9e740a046190ca7c9df294a3c911dbe + checksum: ac8d122f6daf7a035dcea156641fd3701aeba245417c40836a77e35b3341b9c02ddc5d904cfcd4ddbaa00ab854da76d3b911870cafdcdbaff90ea471de26c7d7 languageName: node linkType: hard -"jest-validate@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-validate@npm:27.3.1" +"jest-validate@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-validate@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 + "@jest/types": ^27.5.1 camelcase: ^6.2.0 chalk: ^4.0.0 - jest-get-type: ^27.3.1 + jest-get-type: ^27.5.1 leven: ^3.1.0 - pretty-format: ^27.3.1 - checksum: 0f402027cb43d2a15fe882578aa446f835688ad216eac6ac1f9795244d8d3da362ff932f34fc97307f6fa11951bf8cf13c8efe88aac6ce3ce66d42d7f2916108 + pretty-format: ^27.5.1 + checksum: 82e870f8ee7e4fb949652711b1567f05ae31c54be346b0899e8353e5c20fad7692b511905b37966945e90af8dc0383eb41a74f3ffefb16140ea4f9164d841412 languageName: node linkType: hard -"jest-watcher@npm:^27.3.1": - version: 27.3.1 - resolution: "jest-watcher@npm:27.3.1" +"jest-watcher@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-watcher@npm:27.5.1" dependencies: - "@jest/test-result": ^27.3.1 - "@jest/types": ^27.2.5 + "@jest/test-result": ^27.5.1 + "@jest/types": ^27.5.1 "@types/node": "*" ansi-escapes: ^4.2.1 chalk: ^4.0.0 - jest-util: ^27.3.1 + jest-util: ^27.5.1 string-length: ^4.0.1 - checksum: c150bb81be3aa41c114fbe283e9826c2675f8df091c18db8c53d575f3444966dd1d135aa5af02772e7a88411ac7e67740409f6a7c098d943b8dc056b4f0a845a + checksum: 191c4e9c278c0902ade1a8a80883ac244963ba3e6e78607a3d5f729ccca9c6e71fb3b316f87883658132641c5d818aa84202585c76752e03c539e6cbecb820bd languageName: node linkType: hard @@ -10339,7 +10759,7 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^27.0.6, jest-worker@npm:^27.3.1": +"jest-worker@npm:^27.0.6": version: 27.3.1 resolution: "jest-worker@npm:27.3.1" dependencies: @@ -10350,13 +10770,24 @@ __metadata: languageName: node linkType: hard +"jest-worker@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-worker@npm:27.5.1" + dependencies: + "@types/node": "*" + merge-stream: ^2.0.0 + supports-color: ^8.0.0 + checksum: 98cd68b696781caed61c983a3ee30bf880b5bd021c01d98f47b143d4362b85d0737f8523761e2713d45e18b4f9a2b98af1eaee77afade4111bb65c77d6f7c980 + languageName: node + linkType: hard + "jest@npm:^27.2.4": - version: 27.3.1 - resolution: "jest@npm:27.3.1" + version: 27.5.1 + resolution: "jest@npm:27.5.1" dependencies: - "@jest/core": ^27.3.1 + "@jest/core": ^27.5.1 import-local: ^3.0.2 - jest-cli: ^27.3.1 + jest-cli: ^27.5.1 peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -10364,7 +10795,7 @@ __metadata: optional: true bin: jest: bin/jest.js - checksum: ae4f0c83fb1c87d7a6f440a8d6288f06a2a2fb1e3539bc048918572cded3e1dc10497ce4362a9a4a91f986eb3438f481e733a65581c5d5b08c00f7b4760ff21d + checksum: 96f1d69042b3c6dfc695f2a4e4b0db38af6fb78582ad1a02beaa57cfcd77cbd31567d7d865c1c85709b7c3e176eefa3b2035ffecd646005f15d8ef528eccf205 languageName: node linkType: hard @@ -10520,14 +10951,12 @@ __metadata: languageName: node linkType: hard -"json5@npm:2.x, json5@npm:^2.1.2": - version: 2.2.0 - resolution: "json5@npm:2.2.0" - dependencies: - minimist: ^1.2.5 +"json5@npm:2.x, json5@npm:^2.2.3": + version: 2.2.3 + resolution: "json5@npm:2.2.3" bin: json5: lib/cli.js - checksum: e88fc5274bb58fc99547baa777886b069d2dd96d9cfc4490b305fd16d711dabd5979e35a4f90873cefbeb552e216b041a304fe56702bedba76e19bc7845f208d + checksum: 2a7436a93393830bce797d4626275152e37e877b265e94ca69c99e3d20c2b9dab021279146a39cdb700e71b2dd32a4cebd1514cd57cee102b1af906ce5040349 languageName: node linkType: hard @@ -10542,6 +10971,17 @@ __metadata: languageName: node linkType: hard +"json5@npm:^2.1.2": + version: 2.2.0 + resolution: "json5@npm:2.2.0" + dependencies: + minimist: ^1.2.5 + bin: + json5: lib/cli.js + checksum: e88fc5274bb58fc99547baa777886b069d2dd96d9cfc4490b305fd16d711dabd5979e35a4f90873cefbeb552e216b041a304fe56702bedba76e19bc7845f208d + languageName: node + linkType: hard + "jsonc-parser@npm:^3.0.0": version: 3.0.0 resolution: "jsonc-parser@npm:3.0.0" @@ -10683,16 +11123,6 @@ __metadata: languageName: node linkType: hard -"levn@npm:~0.3.0": - version: 0.3.0 - resolution: "levn@npm:0.3.0" - dependencies: - prelude-ls: ~1.1.2 - type-check: ~0.3.2 - checksum: 0d084a524231a8246bb10fec48cdbb35282099f6954838604f3c7fc66f2e16fa66fd9cc2f3f20a541a113c4dafdf181e822c887c8a319c9195444e6c64ac395e - languageName: node - linkType: hard - "lilconfig@npm:^2.0.3": version: 2.0.3 resolution: "lilconfig@npm:2.0.3" @@ -11383,16 +11813,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24": - version: 2.1.33 - resolution: "mime-types@npm:2.1.33" - dependencies: - mime-db: 1.50.0 - checksum: 05f2a0b3f169fbc51d79bdc7674ceb379dd07dbeadb0143059a7def865224686ee9f9051aeb340e98b6c11dbc06794ce0122181db4312cb1ad054fd90b0d510e - languageName: node - linkType: hard - -"mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -11401,6 +11822,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^2.1.27, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24": + version: 2.1.33 + resolution: "mime-types@npm:2.1.33" + dependencies: + mime-db: 1.50.0 + checksum: 05f2a0b3f169fbc51d79bdc7674ceb379dd07dbeadb0143059a7def865224686ee9f9051aeb340e98b6c11dbc06794ce0122181db4312cb1ad054fd90b0d510e + languageName: node + linkType: hard + "mime@npm:1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -11482,6 +11912,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^3.1.1": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: ^1.1.7 + checksum: c154e566406683e7bcb746e000b84d74465b3a832c45d59912b9b55cd50dee66e5c4b1e5566dba26154040e51672f9aa450a9aef0c97cfc7336b78b7afb9540a + languageName: node + linkType: hard + "minimist-options@npm:^4.0.2": version: 4.1.0 resolution: "minimist-options@npm:4.1.0" @@ -11809,13 +12248,6 @@ __metadata: languageName: node linkType: hard -"node-modules-regexp@npm:^1.0.0": - version: 1.0.0 - resolution: "node-modules-regexp@npm:1.0.0" - checksum: 99541903536c5ce552786f0fca7f06b88df595e62e423c21fa86a1674ee2363dad1f7482d1bec20b4bd9fa5f262f88e6e5cb788fc56411113f2fe2e97783a3a7 - languageName: node - linkType: hard - "node-releases@npm:^1.1.61": version: 1.1.77 resolution: "node-releases@npm:1.1.77" @@ -11830,6 +12262,13 @@ __metadata: languageName: node linkType: hard +"node-releases@npm:^2.0.18": + version: 2.0.18 + resolution: "node-releases@npm:2.0.18" + checksum: ef55a3d853e1269a6d6279b7692cd6ff3e40bc74947945101138745bfdc9a5edabfe72cb19a31a8e45752e1910c4c65c77d931866af6357f242b172b7283f5b3 + languageName: node + linkType: hard + "nodemon@npm:^2.0.13": version: 2.0.14 resolution: "nodemon@npm:2.0.14" @@ -11984,9 +12423,9 @@ __metadata: linkType: hard "nwsapi@npm:^2.2.0": - version: 2.2.0 - resolution: "nwsapi@npm:2.2.0" - checksum: 5ef4a9bc0c1a5b7f2e014aa6a4b359a257503b796618ed1ef0eb852098f77e772305bb0e92856e4bbfa3e6c75da48c0113505c76f144555ff38867229c2400a7 + version: 2.2.12 + resolution: "nwsapi@npm:2.2.12" + checksum: 4dbce7ecbcf336eef1edcbb5161cbceea95863e63a16d9bcec8e81cbb260bdab3d07e6c7b58354d465dc803eef6d0ea4fb20220a80fa148ae65f18d56df81799 languageName: node linkType: hard @@ -12169,20 +12608,6 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.8.1": - version: 0.8.3 - resolution: "optionator@npm:0.8.3" - dependencies: - deep-is: ~0.1.3 - fast-levenshtein: ~2.0.6 - levn: ~0.3.0 - prelude-ls: ~1.1.2 - type-check: ~0.3.2 - word-wrap: ~1.2.3 - checksum: b8695ddf3d593203e25ab0900e265d860038486c943ff8b774f596a310f8ceebdb30c6832407a8198ba3ec9debe1abe1f51d4aad94843612db3b76d690c61d34 - languageName: node - linkType: hard - "optionator@npm:^0.9.1": version: 0.9.1 resolution: "optionator@npm:0.9.1" @@ -12411,7 +12836,7 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^5.0.0": +"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" dependencies: @@ -12561,6 +12986,13 @@ __metadata: languageName: node linkType: hard +"picocolors@npm:^1.0.1": + version: 1.0.1 + resolution: "picocolors@npm:1.0.1" + checksum: fa68166d1f56009fc02a34cdfd112b0dd3cf1ef57667ac57281f714065558c01828cdf4f18600ad6851cbe0093952ed0660b1e0156bddf2184b6aaf5817553a5 + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3": version: 2.3.0 resolution: "picomatch@npm:2.3.0" @@ -12598,12 +13030,10 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1": - version: 4.0.1 - resolution: "pirates@npm:4.0.1" - dependencies: - node-modules-regexp: ^1.0.0 - checksum: 091e232aac19f0049a681838fa9fcb4af824b5b1eb0e9325aa07b9d13245bfe3e4fa57a7766b9fdcd19cb89f2c15c688b46023be3047cb288023a0c079d3b2a3 +"pirates@npm:^4.0.4": + version: 4.0.6 + resolution: "pirates@npm:4.0.6" + checksum: 46a65fefaf19c6f57460388a5af9ab81e3d7fd0e7bc44ca59d753cb5c4d0df97c6c6e583674869762101836d68675f027d60f841c105d72734df9dfca97cbcc6 languageName: node linkType: hard @@ -13145,13 +13575,6 @@ __metadata: languageName: node linkType: hard -"prelude-ls@npm:~1.1.2": - version: 1.1.2 - resolution: "prelude-ls@npm:1.1.2" - checksum: c4867c87488e4a0c233e158e4d0d5565b609b105d75e4c05dc760840475f06b731332eb93cc8c9cecb840aa8ec323ca3c9a56ad7820ad2e63f0261dadcb154e4 - languageName: node - linkType: hard - "prepend-http@npm:^2.0.0": version: 2.0.0 resolution: "prepend-http@npm:2.0.0" @@ -13196,15 +13619,14 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^27.0.0, pretty-format@npm:^27.3.1": - version: 27.3.1 - resolution: "pretty-format@npm:27.3.1" +"pretty-format@npm:^27.0.0, pretty-format@npm:^27.5.1": + version: 27.5.1 + resolution: "pretty-format@npm:27.5.1" dependencies: - "@jest/types": ^27.2.5 ansi-regex: ^5.0.1 ansi-styles: ^5.0.0 react-is: ^17.0.1 - checksum: 2979eae85a4f7ba1c3946faa8f5c6497cc80dc64ba499ccd5fdada267f82dc664f315a4c1cdd4c0b4b97edbae399a7bf0a957cc1b87feb91cd95f1e436834fed + checksum: cf610cffcb793885d16f184a62162f2dd0df31642d9a18edf4ca298e909a8fe80bdbf556d5c9573992c102ce8bf948691da91bf9739bee0ffb6e79c8a8a6e088 languageName: node linkType: hard @@ -13367,9 +13789,9 @@ __metadata: linkType: hard "psl@npm:^1.1.33": - version: 1.8.0 - resolution: "psl@npm:1.8.0" - checksum: 6150048ed2da3f919478bee8a82f3828303bc0fc730fb015a48f83c9977682c7b28c60ab01425a72d82a2891a1681627aa530a991d50c086b48a3be27744bde7 + version: 1.9.0 + resolution: "psl@npm:1.9.0" + checksum: 20c4277f640c93d393130673f392618e9a8044c6c7bf61c53917a0fddb4952790f5f362c6c730a9c32b124813e173733f9895add8d26f566ed0ea0654b2e711d languageName: node linkType: hard @@ -13404,13 +13826,20 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0, punycode@npm:^2.1.1": +"punycode@npm:^2.1.0": version: 2.1.1 resolution: "punycode@npm:2.1.1" checksum: 823bf443c6dd14f669984dea25757b37993f67e8d94698996064035edd43bed8a5a17a9f12e439c2b35df1078c6bec05a6c86e336209eb1061e8025c481168e8 languageName: node linkType: hard +"punycode@npm:^2.1.1": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: bb0a0ceedca4c3c57a9b981b90601579058903c62be23c5e8e843d2c2d4148a3ecf029d5133486fb0e1822b098ba8bba09e89d6b21742d02fa26bda6441a6fb2 + languageName: node + linkType: hard + "pupa@npm:^2.1.1": version: 2.1.1 resolution: "pupa@npm:2.1.1" @@ -14189,9 +14618,9 @@ __metadata: linkType: hard "resolve.exports@npm:^1.1.0": - version: 1.1.0 - resolution: "resolve.exports@npm:1.1.0" - checksum: 52865af8edb088f6c7759a328584a5de6b226754f004b742523adcfe398cfbc4559515104bc2ae87b8e78b1e4de46c9baec400b3fb1f7d517b86d2d48a098a2d + version: 1.1.1 + resolution: "resolve.exports@npm:1.1.1" + checksum: 485aa10082eb388a569d696e17ad7b16f4186efc97dd34eadd029d95b811f21ffee13b1b733198bb4584dbb3cb296aa6f141835221fb7613b9606b84f1386655 languageName: node linkType: hard @@ -14478,14 +14907,12 @@ __metadata: languageName: node linkType: hard -"semver@npm:7.x, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5": - version: 7.3.5 - resolution: "semver@npm:7.3.5" - dependencies: - lru-cache: ^6.0.0 +"semver@npm:7.x, semver@npm:^7.3.2": + version: 7.6.3 + resolution: "semver@npm:7.6.3" bin: semver: bin/semver.js - checksum: 5eafe6102bea2a7439897c1856362e31cc348ccf96efd455c8b5bc2c61e6f7e7b8250dc26b8828c1d76a56f818a7ee907a36ae9fb37a599d3d24609207001d60 + checksum: 4110ec5d015c9438f322257b1c51fe30276e5f766a3f64c09edd1d7ea7118ecbc3f379f3b69032bacf13116dc7abc4ad8ce0d7e2bd642e26b0d271b56b61a7d8 languageName: node linkType: hard @@ -14498,6 +14925,26 @@ __metadata: languageName: node linkType: hard +"semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: ae47d06de28836adb9d3e25f22a92943477371292d9b665fb023fae278d345d508ca1958232af086d85e0155aee22e313e100971898bbb8d5d89b8b1d4054ca2 + languageName: node + linkType: hard + +"semver@npm:^7.2.1, semver@npm:^7.3.4, semver@npm:^7.3.5": + version: 7.3.5 + resolution: "semver@npm:7.3.5" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 5eafe6102bea2a7439897c1856362e31cc348ccf96efd455c8b5bc2c61e6f7e7b8250dc26b8828c1d76a56f818a7ee907a36ae9fb37a599d3d24609207001d60 + languageName: node + linkType: hard + "send@npm:0.18.0": version: 0.18.0 resolution: "send@npm:0.18.0" @@ -14909,7 +15356,17 @@ __metadata: languageName: node linkType: hard -"source-map-support@npm:^0.5.6, source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.20": +"source-map-support@npm:^0.5.6": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: ^1.0.0 + source-map: ^0.6.0 + checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137 + languageName: node + linkType: hard + +"source-map-support@npm:~0.5.12, source-map-support@npm:~0.5.20": version: 0.5.20 resolution: "source-map-support@npm:0.5.20" dependencies: @@ -14940,7 +15397,14 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.7.3, source-map@npm:~0.7.2": +"source-map@npm:^0.7.3": + version: 0.7.4 + resolution: "source-map@npm:0.7.4" + checksum: 01cc5a74b1f0e1d626a58d36ad6898ea820567e87f18dfc9d24a9843a351aaa2ec09b87422589906d6ff1deed29693e176194dc88bcae7c9a852dc74b311dbf5 + languageName: node + linkType: hard + +"source-map@npm:~0.7.2": version: 0.7.3 resolution: "source-map@npm:0.7.3" checksum: cd24efb3b8fa69b64bf28e3c1b1a500de77e84260c5b7f2b873f88284df17974157cc88d386ee9b6d081f08fdd8242f3fc05c953685a6ad81aad94c7393dedea @@ -15408,12 +15872,12 @@ __metadata: linkType: hard "supports-hyperlinks@npm:^2.0.0": - version: 2.2.0 - resolution: "supports-hyperlinks@npm:2.2.0" + version: 2.3.0 + resolution: "supports-hyperlinks@npm:2.3.0" dependencies: has-flag: ^4.0.0 supports-color: ^7.0.0 - checksum: aef04fb41f4a67f1bc128f7c3e88a81b6cf2794c800fccf137006efe5bafde281da3e42e72bf9206c2fcf42e6438f37e3a820a389214d0a88613ca1f2d36076a + checksum: 9ee0de3c8ce919d453511b2b1588a8205bd429d98af94a01df87411391010fe22ca463f268c84b2ce2abad019dfff8452aa02806eeb5c905a8d7ad5c4f4c52b8 languageName: node linkType: hard @@ -15620,9 +16084,9 @@ __metadata: linkType: hard "throat@npm:^6.0.1": - version: 6.0.1 - resolution: "throat@npm:6.0.1" - checksum: 782d4171ee4e3cf947483ed2ff1af3e17cc4354c693b9d339284f61f99fbc401d171e0b0d2db3295bb7d447630333e9319c174ebd7ef315c6fb791db9675369c + version: 6.0.2 + resolution: "throat@npm:6.0.2" + checksum: 463093768d4884772020bb18b0f33d3fec8a2b4173f7da3958dfbe88ff0f1e686ffadf0f87333bf6f6db7306b1450efc7855df69c78bf0bfa61f6d84a3361fe8 languageName: node linkType: hard @@ -15757,14 +16221,14 @@ __metadata: linkType: hard "tough-cookie@npm:^4.0.0": - version: 4.1.3 - resolution: "tough-cookie@npm:4.1.3" + version: 4.1.4 + resolution: "tough-cookie@npm:4.1.4" dependencies: psl: ^1.1.33 punycode: ^2.1.1 universalify: ^0.2.0 url-parse: ^1.5.3 - checksum: c9226afff36492a52118432611af083d1d8493a53ff41ec4ea48e5b583aec744b989e4280bcf476c910ec1525a89a4a0f1cae81c08b18fb2ec3a9b3a72b91dcc + checksum: 5815059f014c31179a303c673f753f7899a6fce94ac93712c88ea5f3c26e0c042b5f0c7a599a00f8e0feeca4615dba75c3dffc54f3c1a489978aa8205e09307c languageName: node linkType: hard @@ -15820,8 +16284,8 @@ __metadata: linkType: hard "ts-jest@npm:^27.0.5": - version: 27.0.7 - resolution: "ts-jest@npm:27.0.7" + version: 27.1.5 + resolution: "ts-jest@npm:27.1.5" dependencies: bs-logger: 0.x fast-json-stable-stringify: 2.x @@ -15844,9 +16308,11 @@ __metadata: optional: true babel-jest: optional: true + esbuild: + optional: true bin: ts-jest: cli.js - checksum: 3711361cb5ae54aac547b00f8ad118ec88333c391af4bff0420497e9faa296eace4e8272c627ecbf4be675af9f68c437e4c2ccc5693c6d744796ec7da6dda131 + checksum: 3ef51c538b82f49b3f529331c1a017871a2f90e7a9a6e69333304755036d121818c6b120e2ce32dd161ff8bb2487efec0c790753ecd39b46a9ed1ce0d241464c languageName: node linkType: hard @@ -15948,15 +16414,6 @@ __metadata: languageName: node linkType: hard -"type-check@npm:~0.3.2": - version: 0.3.2 - resolution: "type-check@npm:0.3.2" - dependencies: - prelude-ls: ~1.1.2 - checksum: dd3b1495642731bc0e1fc40abe5e977e0263005551ac83342ecb6f4f89551d106b368ec32ad3fb2da19b3bd7b2d1f64330da2ea9176d8ddbfe389fb286eb5124 - languageName: node - linkType: hard - "type-detect@npm:4.0.8": version: 4.0.8 resolution: "type-detect@npm:4.0.8" @@ -16343,6 +16800,20 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.1.0": + version: 1.1.0 + resolution: "update-browserslist-db@npm:1.1.0" + dependencies: + escalade: ^3.1.2 + picocolors: ^1.0.1 + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 7b74694d96f0c360f01b702e72353dc5a49df4fe6663d3ee4e5c628f061576cddf56af35a3a886238c01dd3d8f231b7a86a8ceaa31e7a9220ae31c1c1238e562 + languageName: node + linkType: hard + "update-notifier@npm:^5.1.0": version: 5.1.0 resolution: "update-notifier@npm:5.1.0" @@ -16546,13 +17017,13 @@ __metadata: linkType: hard "v8-to-istanbul@npm:^8.1.0": - version: 8.1.0 - resolution: "v8-to-istanbul@npm:8.1.0" + version: 8.1.1 + resolution: "v8-to-istanbul@npm:8.1.1" dependencies: "@types/istanbul-lib-coverage": ^2.0.1 convert-source-map: ^1.6.0 source-map: ^0.7.3 - checksum: c7dabf9567e0c210b24d0720e553803cbe1ff81edb1ec7f2080eb4be01ed081a40286cc9f4aaa86d1bf8d57840cefae8fdf326b7cb8faa316ba50c7b948030d4 + checksum: 54ce92bec2727879626f623d02c8d193f0c7e919941fa373ec135189a8382265117f5316ea317a1e12a5f9c13d84d8449052a731fe3306fa4beaafbfa4cab229 languageName: node linkType: hard @@ -17036,7 +17507,7 @@ __metadata: languageName: node linkType: hard -"word-wrap@npm:^1.2.3, word-wrap@npm:~1.2.3": +"word-wrap@npm:^1.2.3": version: 1.2.4 resolution: "word-wrap@npm:1.2.4" checksum: 8f1f2e0a397c0e074ca225ba9f67baa23f99293bc064e31355d426ae91b8b3f6b5f6c1fc9ae5e9141178bb362d563f55e62fd8d5c31f2a77e3ade56cb3e35bd1 @@ -17120,7 +17591,7 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7.3.1, ws@npm:^7.4.6": +"ws@npm:^7.3.1": version: 7.5.5 resolution: "ws@npm:7.5.5" peerDependencies: @@ -17135,6 +17606,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^7.4.6": + version: 7.5.10 + resolution: "ws@npm:7.5.10" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: f9bb062abf54cc8f02d94ca86dcd349c3945d63851f5d07a3a61c2fcb755b15a88e943a63cf580cbdb5b74436d67ef6b67f745b8f7c0814e411379138e1863cb + languageName: node + linkType: hard + "xdg-basedir@npm:^4.0.0": version: 4.0.0 resolution: "xdg-basedir@npm:4.0.0"