diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index 1b5f27f..98d9dd7 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -19,7 +19,7 @@ A clear and concise description of what you expected to happen.
- [ ] Version: [e.g. v1.0.0]
-To get the version of the solution, you can look at the description of the created CloudFormation stack. For example, "_(SO0108) - AWS Network Firewall Deployment Automations for AWS Transit Gateway. Version **v1.0.0**_".
+To get the version of the solution, you can look at the description of the created CloudFormation stack. For example, "_(SO0108) - Firewall Automation for Network Traffic on AWS. Version **v1.0.0**_".
- [ ] Region: [e.g. us-east-1]
- [ ] Was the solution modified from the version published on this repository?
diff --git a/.gitignore b/.gitignore
index d10dc49..96f7b35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -91,6 +91,7 @@ ENV/
*cdk.out*
*.d.ts
*.js
+!jest.config.js
#ignore these in the deployment folder
*regional-s3-assets*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3fb5969..f506bef 100755
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [1.0.2] - 2022-12-19
+### Updated
+- Name change to Firewall Automation for Network Traffic on AWS
+- Upgrade to CDK v2
+- Fix NPM security warnings
+- Fix SonarQube bugs and increase unit test coverage
+
## [1.0.1] - 2021-04-10
### Updated
- Updated default branch name to 'main'. [Change branch settings in your
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 67f2886..4c46103 100755
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -11,7 +11,7 @@ information to effectively respond to your bug report or contribution.
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
-When filing an issue, please check [existing open](https://github.com/awslabs/network-firewall-automation/issues), or [recently closed](https://github.com/awslabs/network-firewall-automation/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already
+When filing an issue, please check [existing open](https://github.com/aws-solutions/firewall-automation-for-network-traffic-on-aws/issues), or [recently closed](https://github.com/aws-solutions/firewall-automation-for-network-traffic-on-aws/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
* A reproducible test case or series of steps
@@ -42,7 +42,7 @@ GitHub provides additional document on [forking a repository](https://help.githu
## Finding contributions to work on
-Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/awslabs/network-firewall-automation/labels/help%20wanted) issues is a great place to start.
+Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels ((enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/aws-solutions/firewall-automation-for-network-traffic-on-aws/labels/help%20wanted) issues is a great place to start.
## Code of Conduct
@@ -57,6 +57,6 @@ If you discover a potential security issue in this project we ask that you notif
## Licensing
-See the [LICENSE](https://github.com/awslabs/network-firewall-automation/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
+See the [LICENSE](https://github.com/aws-solutions/firewall-automation-for-network-traffic-on-aws/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
diff --git a/NOTICE.txt b/NOTICE.txt
index 68807d3..cb40653 100755
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,10 +1,6 @@
-AWS Network Firewall Automation
-Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-Licensed under the Apache License Version 2.0 (the "License"). You may not use this file except
-in compliance with the License. A copy of the License is located at http://www.apache.org/licenses/
-or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the
-specific language governing permissions and limitations under the License.
+Firewall Automation for Network Traffic on AWS
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
**********************
THIRD PARTY COMPONENTS
@@ -16,5 +12,13 @@ moment under the MIT License
uuid under the MIT License.
AWS SDK under the Apache License Version 2.0
aws-cdk under Apache License 2.0
-
-AWS SDK under the Apache License Version 2.0
+aws-cdk-lib under Apache License 2.0
+@types/jest under the Massachusetts Institute of Technology (MIT) license
+@types/node under the Massachusetts Institute of Technology (MIT) license
+aws-sdk-client-mock under the Massachusetts Institute of Technology (MIT) license
+constructs under Apache License 2.0
+ts-jest under the Massachusetts Institute of Technology (MIT) license
+ts-node under the Massachusetts Institute of Technology (MIT) license
+typescript under Apache License 2.0
+@types/moment under the Massachusetts Institute of Technology (MIT) license
+@types/uuid under the Massachusetts Institute of Technology (MIT) license
diff --git a/README.md b/README.md
index c43417d..70176d8 100755
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-**[AWS Network Firewall Deployment Automations for AWS Transit Gateway](https://aws.amazon.com/solutions/implementations/aws-network-firewall-deployment-automations-for-aws-transit-gateway)** | **[🚧 Feature request](https://github.com/awslabs/aws-network-firewall-deployment-automations-for-aws-transit-gateway/issues/new?assignees=&labels=feature-request%2C+enhancement&template=feature_request.md&title=)** | **[🐛 Bug Report](https://github.com/awslabs/aws-network-firewall-deployment-automations-for-aws-transit-gateway/issues/new?assignees=&labels=bug%2C+triage&template=bug_report.md&title=)**
+**[Firewall Automation for Network Traffic on AWS](https://aws.amazon.com/solutions/implementations/firewall-automation-for-network-traffic-on-aws)** | **[🚧 Feature request](https://github.com/aws-solutions/firewall-automation-for-network-traffic-on-aws/issues/new?assignees=&labels=feature-request%2C+enhancement&template=feature_request.md&title=)** | **[🐛 Bug Report](https://github.com/aws-solutions/firewall-automation-for-network-traffic-on-aws/issues/new?assignees=&labels=bug%2C+triage&template=bug_report.md&title=)**
Note: If you want to use the solution without building from source, navigate to Solution Landing Page
@@ -17,7 +17,7 @@ Note: If you want to use the solution without building from source, navigate to
# Solution Overview
-Solution for AWS Network Firewall Deployment Automations for AWS Transit Gateway.
+Solution for Firewall Automation for Network Traffic on AWS.
# Architecture Diagram
@@ -25,7 +25,7 @@ Solution for AWS Network Firewall Deployment Automations for AWS Transit Gateway
## Prerequisites for Customization
-* Node.js>12
+* Node.js>16
## Build
@@ -68,13 +68,13 @@ Follow the steps for deploying your custom version of the solution.
* Copy the file ./deployment/regional-s3-assets/network-firewall-automation.zip to the location s3://[BUCKET_NAME]-[REGION]/network-firewall-automation/[VERSION_ID]/
* Copy the file ./deployment/regional-s3-assets/network-firewall-configuration.zip to the location s3://[BUCKET_NAME]-[REGION]/network-firewall-automation/latest/
-Once the above steps are completed, use the file ./deployment/global-s3-assets/aws-network-firewall-deployment-automations-for-aws-transit-gateway.template to create a stack in CloudFormation.
+Once the above steps are completed, use the file ./deployment/global-s3-assets/firewall-automation-for-network-traffic-on-aws.template to create a stack in CloudFormation.
# File structure
-aws-network-firewall-deployment-automations-for-aws-transit-gateway consists of:
+firewall-automation-for-network-traffic-on-aws consists of:
- CDK constructs to generate necessary resources
- Microservices used in the solution
@@ -160,24 +160,14 @@ File Structure
-
-
-## Collection of operational metrics
-This solution collects anonymous operational metrics to help AWS improve the quality and features of the solution. For more information, including how to disable this capability, please see the [implementation guide](https://docs.aws.amazon.com/solutions/latest/network-firewall-deployment-automations-for-aws-transit-gateway/collection-of-operational-metrics.html).
-
-
***
-Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Licensed under the Apache License Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
-
- http://www.apache.org/licenses/
-
-or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions and limitations under the License.
-
-See [LICENSE](https://github.com/awslabs/aws-network-firewall-solution-for-aws-transit-gateway/blob/master/LICENSE.txt)
+Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+SPDX-License-Identifier: Apache-2.0
+See [LICENSE](https://github.com/aws-solutions/firewall-automation-for-network-traffic-on-aws/blob/master/LICENSE.txt)
+## Collection of operational metrics
+This solution collects anonymous operational metrics to help AWS improve the quality and features of the solution. For more information, including how to disable this capability, please see the [implementation guide](https://docs.aws.amazon.com/solutions/latest/network-firewall-deployment-automations-for-aws-transit-gateway/collection-of-operational-metrics.html).
diff --git a/deployment/build-s3-dist.sh b/deployment/build-s3-dist.sh
index cdd36f0..088bb6b 100755
--- a/deployment/build-s3-dist.sh
+++ b/deployment/build-s3-dist.sh
@@ -1,19 +1,8 @@
#!/bin/bash
-#
-# Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
-# with the License. A copy of the License is located at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
-# OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
-# and limitations under the License.
-#
-
-# Important: CDK global version number
-cdk_version=1.77.0
+ #
+ # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ # SPDX-License-Identifier: Apache-2.0
+ #
# Check to see if the required parameters have been provided:
if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
@@ -66,15 +55,14 @@ echo "--------------------------------------------------------------------------
# Install the global aws-cdk package
echo "cd $source_dir"
cd $source_dir
-echo "npm install"
-npm install
-echo "npm install aws-cdk@$cdk_version"
-npm install aws-cdk@$cdk_version
+echo "npm ci"
+npm ci
# Run 'cdk synth' to generate raw solution outputs
cd "$source_dir"
-echo "node_modules/aws-cdk/bin/cdk synth --output=$staging_dist_dir"
-npm run build && node_modules/aws-cdk/bin/cdk synth --output=$staging_dist_dir
+echo "npm run cdk -- synth --output=$staging_dist_dir"
+npm run build
+npm run cdk -- synth --output=$staging_dist_dir
# Remove unnecessary output files
echo "cd $staging_dist_dir"
@@ -110,7 +98,7 @@ echo "find $staging_dist_dir -iname "package-lock.json" -type f -exec rm -f "{}"
find $staging_dist_dir -iname "package-lock.json" -type f -exec rm -f "{}" \; 2> /dev/null
echo "------------------------------------------------------------------------------"
-echo "Package Network Firewall Automation node project for Code Build/Deploy stage "
+echo "Package Firewall Automation for Network Traffic on AWS node project for Code Build/Deploy stage "
echo "------------------------------------------------------------------------------"
cd $source_dir/networkFirewallAutomation/
npm install
diff --git a/source/bin/network-firewall-auto-solution.ts b/source/bin/network-firewall-auto-solution.ts
index 68067fa..2b6010f 100755
--- a/source/bin/network-firewall-auto-solution.ts
+++ b/source/bin/network-firewall-auto-solution.ts
@@ -1,17 +1,10 @@
#!/usr/bin/env node
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- */
-import * as cdk from '@aws-cdk/core';
+ /*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { App, DefaultStackSynthesizer } from 'aws-cdk-lib';
import {
NetworkFirewallAutomationStack,
NetworkFirewallAutomationStackProps
@@ -24,17 +17,23 @@ const SOLUTION_BUCKET = process.env['DIST_OUTPUT_BUCKET'];
const SOLUTION_TMN = process.env['SOLUTION_TRADEMARKEDNAME'];
const SOLUTION_PROVIDER = 'AWS Solution Development';
-const app = new cdk.App();
+const app = new App();
let NetworkFirewallAutomationStackProperties: NetworkFirewallAutomationStackProps = {
+ synthesizer: new DefaultStackSynthesizer({
+ generateBootstrapVersionRule: false
+ }),
solutionId: SOLUTION_ID,
solutionTradeMarkName: SOLUTION_TMN,
solutionProvider: SOLUTION_PROVIDER,
solutionBucket: SOLUTION_BUCKET,
solutionName: SOLUTION_NAME,
solutionVersion: SOLUTION_VERSION,
- description: '(' + SOLUTION_ID + ') - The AWS CloudFormation template' +
- ' for deployment of the ' + SOLUTION_NAME + ', Version: ' + SOLUTION_VERSION,
-}
+ description: `(${SOLUTION_ID}) - The AWS CloudFormation template for deployment of the ${SOLUTION_NAME}, Version: ${SOLUTION_VERSION}`
+};
-new NetworkFirewallAutomationStack(app, 'aws-network-firewall-deployment-automations-for-aws-transit-gateway', NetworkFirewallAutomationStackProperties);
+new NetworkFirewallAutomationStack(
+ app,
+ 'firewall-automation-for-network-traffic-on-aws',
+ NetworkFirewallAutomationStackProperties
+);
diff --git a/source/jest.config.js b/source/jest.config.js
old mode 100755
new mode 100644
index ad01282..86a4278
--- a/source/jest.config.js
+++ b/source/jest.config.js
@@ -1,13 +1,36 @@
-module.exports = {
- "roots": [
- "/test"
- ],
- testMatch: [ '**/*.test.ts'],
- "transform": {
- "^.+\\.tsx?$": "ts-jest"
- },
- coverageReporters: [
- "text",
- ["lcov", {"projectRoot": "../"}]
- ]
- }
+'use strict';
+Object.defineProperty(exports, '__esModule', { value: true });
+const config = {
+ clearMocks: false,
+ collectCoverage: true,
+ // The directory where Jest should output its coverage files
+ coverageDirectory: 'coverage',
+ // An array of regexp pattern strings used to skip coverage collection
+ coveragePathIgnorePatterns: ['/node_modules/'],
+ // An array of directory names to be searched recursively up from the requiring module's location
+ moduleDirectories: ['node_modules'],
+ // An array of file extensions your modules use
+ moduleFileExtensions: ['ts', 'json', 'jsx', 'js', 'tsx', 'node'],
+ // Automatically reset mock state between every test
+ resetMocks: false,
+ // The glob patterns Jest uses to detect test files
+ testMatch: ['**/?(*.)+(spec|test).[t]s?(x)'],
+ // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
+ testPathIgnorePatterns: ['/node_modules/', '/networkFirewallAutomation/'],
+ // A map from regular expressions to paths to transformers
+ transform: {
+ '^.+\\.(t)sx?$': 'ts-jest',
+ },
+ // Indicates whether each individual test should be reported during the run
+ verbose: false,
+ // An array of glob patterns indicating a set of files for which coverage information should be collected
+ collectCoverageFrom: [
+ './lib/*.ts',
+ '!**/*.d.ts',
+ '!**/*.spec.ts',
+ ],
+ coverageReporters: [['lcov', { projectRoot: '../' }], 'text'],
+ rootDir: './',
+ testTimeout: 30000,
+};
+exports.default = config;
diff --git a/source/lib/network-firewall-automation-solution-stack.ts b/source/lib/network-firewall-automation-solution-stack.ts
index 1302718..39bda81 100755
--- a/source/lib/network-firewall-automation-solution-stack.ts
+++ b/source/lib/network-firewall-automation-solution-stack.ts
@@ -1,35 +1,49 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import * as cdk from '@aws-cdk/core';
-import { RemovalPolicy } from '@aws-cdk/core';
-import * as ec2 from '@aws-cdk/aws-ec2';
-import * as s3 from '@aws-cdk/aws-s3';
-import * as logs from '@aws-cdk/aws-logs';
-import * as iam from '@aws-cdk/aws-iam';
-import * as kms from '@aws-cdk/aws-kms';
-import * as codecommit from '@aws-cdk/aws-codecommit';
-import * as codepipeline from '@aws-cdk/aws-codepipeline';
-import * as codepipeline_action from '@aws-cdk/aws-codepipeline-actions';
import {
- BuildEnvironmentVariableType,
- BuildSpec,
- LinuxBuildImage,
- PipelineProject
-} from '@aws-cdk/aws-codebuild';
-
-
-export interface NetworkFirewallAutomationStackProps extends cdk.StackProps {
+ Aws,
+ CfnCondition,
+ CfnMapping,
+ CfnOutput,
+ CfnParameter,
+ Duration,
+ Fn,
+ RemovalPolicy,
+ Stack,
+ StackProps,
+} from 'aws-cdk-lib';
+import { BuildEnvironmentVariableType, BuildSpec, LinuxBuildImage, PipelineProject } from 'aws-cdk-lib/aws-codebuild';
+import { CfnRepository, Repository } from 'aws-cdk-lib/aws-codecommit';
+import { Artifact, Pipeline } from 'aws-cdk-lib/aws-codepipeline';
+import { CodeBuildAction, CodeCommitSourceAction } from 'aws-cdk-lib/aws-codepipeline-actions';
+import {
+ CfnFlowLog,
+ CfnRoute,
+ CfnRouteTable,
+ CfnSubnet,
+ CfnSubnetRouteTableAssociation,
+ CfnTransitGatewayAttachment,
+ CfnTransitGatewayRoute,
+ CfnTransitGatewayRouteTableAssociation,
+ CfnVPC,
+} from 'aws-cdk-lib/aws-ec2';
+import { AnyPrincipal, CfnPolicy, Effect, Policy, PolicyStatement, Role, ServicePrincipal } from 'aws-cdk-lib/aws-iam';
+import { CfnAlias, CfnKey, Key } from 'aws-cdk-lib/aws-kms';
+import { CfnLogGroup } from 'aws-cdk-lib/aws-logs';
+import {
+ BlockPublicAccess,
+ Bucket,
+ BucketEncryption,
+ BucketPolicy,
+ CfnBucket,
+ CfnBucketPolicy,
+} from 'aws-cdk-lib/aws-s3';
+import { Construct } from 'constructs';
+
+export interface NetworkFirewallAutomationStackProps extends StackProps {
solutionId: string;
solutionTradeMarkName: string | undefined;
solutionProvider: string | undefined;
@@ -38,66 +52,85 @@ export interface NetworkFirewallAutomationStackProps extends cdk.StackProps {
solutionVersion: string | undefined;
}
-export class NetworkFirewallAutomationStack extends cdk.Stack {
-
- constructor(scope: cdk.Construct, id: string, props: NetworkFirewallAutomationStackProps) {
+export class NetworkFirewallAutomationStack extends Stack {
+ constructor(scope: Construct, id: string, props: NetworkFirewallAutomationStackProps) {
super(scope, id, props);
/**
* Parameters - Values to pass to your template at runtime
*/
- const cidrBlock = new cdk.CfnParameter(this, 'cidrBlock', {
+ const cidrBlock = new CfnParameter(this, 'cidrBlock', {
type: 'String',
default: '192.168.1.0/26',
description: 'CIDR Block for VPC. Must be /26 or larger CIDR block.',
- allowedPattern: '^(?:[0-9]{1,3}\.){3}[0-9]{1,3}[\/]([0-9]?[0-6]?|[1][7-9])$'
- })
-
- const logRetentionPeriod = new cdk.CfnParameter(this, "LogRetentionPeriod", {
- type: "Number",
- description: "Log retention period in days.",
- allowedValues: ["1", "3", "5", "7", "14", "30", "60", "90", "120", "150", "180", "365", "400", "545", "731", "1827", "3653"],
- default: 90
+ allowedPattern: '^(?:[0-9]{1,3}.){3}[0-9]{1,3}[/]([0-9]?[0-6]?|[1][7-9])$',
});
- const existingTransitGatewayId = new cdk.CfnParameter(this, "ExistingTransitGateway", {
+ const logRetentionPeriod = new CfnParameter(this, 'LogRetentionPeriod', {
+ type: 'Number',
+ description: 'Log retention period in days.',
+ allowedValues: [
+ '1',
+ '3',
+ '5',
+ '7',
+ '14',
+ '30',
+ '60',
+ '90',
+ '120',
+ '150',
+ '180',
+ '365',
+ '400',
+ '545',
+ '731',
+ '1827',
+ '3653',
+ ],
+ default: 90,
+ });
+
+ const existingTransitGatewayId = new CfnParameter(this, 'ExistingTransitGateway', {
description: 'Existing AWS Transit Gateway id.',
type: 'String',
- default: ""
- })
+ default: '',
+ });
- const transitGatewayRTIdForAssociation = new cdk.CfnParameter(this, "TransitGatewayRouteTableIdForAssociation", {
- description: 'Existing AWS Transit Gateway route table id. Example:' +
- ' Firewall Route Table. Format: tgw-rtb-0a1b2c3d',
+ const transitGatewayRTIdForAssociation = new CfnParameter(this, 'TransitGatewayRouteTableIdForAssociation', {
+ description:
+ 'Existing AWS Transit Gateway route table id. Example:' + ' Firewall Route Table. Format: tgw-rtb-0a1b2c3d',
type: 'String',
- default: ""
- })
+ default: '',
+ });
- const transitGatewayRTIdForDefaultRoute = new cdk.CfnParameter(this, "TransitGatewayRTIdForDefaultRoute", {
- description: 'Existing AWS Transit Gateway route table id.' +
- ' Example: Spoke VPC Route Table. Format: tgw-rtb-4e5f6g7h',
+ const transitGatewayRTIdForDefaultRoute = new CfnParameter(this, 'TransitGatewayRTIdForDefaultRoute', {
+ description:
+ 'Existing AWS Transit Gateway route table id.' + ' Example: Spoke VPC Route Table. Format: tgw-rtb-4e5f6g7h',
type: 'String',
- default: ""
- })
+ default: '',
+ });
- const logType = new cdk.CfnParameter(this, "logType", {
- type: "String",
- description: 'The type of log to send. Alert logs report traffic that' +
+ const logType = new CfnParameter(this, 'logType', {
+ type: 'String',
+ description:
+ 'The type of log to send. Alert logs report traffic that' +
' matches a StatefulRule with an action setting that sends an alert' +
' log message. Flow logs are standard network traffic flow logs.',
allowedValues: ['ALERT', 'FLOW', 'EnableBoth'],
default: 'FLOW',
- })
+ });
- const logDestinationType = new cdk.CfnParameter(this, "logDestinationType", {
- type: "String",
- description: 'The type of storage destination to send these logs to.' +
+ const logDestinationType = new CfnParameter(this, 'logDestinationType', {
+ type: 'String',
+ description:
+ 'The type of storage destination to send these logs to.' +
' You can send logs to an Amazon S3 bucket ' +
'or a CloudWatch log group.',
allowedValues: ['S3', 'CloudWatchLogs', 'ConfigureManually'],
default: 'CloudWatchLogs',
- })
+ });
/**
* Metadata - Objects that provide additional information about the
@@ -105,56 +138,48 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
*/
this.templateOptions.metadata = {
- "AWS::CloudFormation::Interface": {
+ 'AWS::CloudFormation::Interface': {
ParameterGroups: [
{
- Label: { default: "VPC Configuration" },
- Parameters: [cidrBlock.logicalId]
+ Label: { default: 'VPC Configuration' },
+ Parameters: [cidrBlock.logicalId],
},
{
- Label: { default: "Transit Gateway Configuration" },
+ Label: { default: 'Transit Gateway Configuration' },
Parameters: [
existingTransitGatewayId.logicalId,
transitGatewayRTIdForAssociation.logicalId,
- transitGatewayRTIdForDefaultRoute.logicalId
- ]
+ transitGatewayRTIdForDefaultRoute.logicalId,
+ ],
},
{
- Label: { default: "Firewall Logging Configuration" },
- Parameters: [
- logDestinationType.logicalId,
- logType.logicalId,
- logRetentionPeriod.logicalId
- ]
- }
+ Label: { default: 'Firewall Logging Configuration' },
+ Parameters: [logDestinationType.logicalId, logType.logicalId, logRetentionPeriod.logicalId],
+ },
],
ParameterLabels: {
[cidrBlock.logicalId]: {
- default: "Provide the CIDR block for the Inspection VPC",
+ default: 'Provide the CIDR block for the Inspection VPC',
},
[existingTransitGatewayId.logicalId]: {
- default: "Provide the existing AWS Transit Gateway ID you wish to" +
- " attach to the Inspection VPC",
+ default: 'Provide the existing AWS Transit Gateway ID you wish to attach to the Inspection VPC',
},
[transitGatewayRTIdForAssociation.logicalId]: {
- default: "Provide AWS Transit Gateway Route Table to be" +
- " associated with the Inspection VPC TGW Attachment.",
+ default: 'Provide AWS Transit Gateway Route Table to be associated with the Inspection VPC TGW Attachment.',
},
[transitGatewayRTIdForDefaultRoute.logicalId]: {
- default: "Provide the AWS Transit Gateway Route Table to receive 0.0.0.0/0 route to the Inspection VPC TGW Attachment.",
+ default:
+ 'Provide the AWS Transit Gateway Route Table to receive 0.0.0.0/0 route to the Inspection VPC TGW Attachment.',
},
[logType.logicalId]: {
- default: "Select the type of log to send to the defined log" +
- " destination.",
+ default: 'Select the type of log to send to the defined log destination.',
},
[logDestinationType.logicalId]: {
- default: "Select the type of log destination for the Network" +
- " Firewall",
+ default: 'Select the type of log destination for the Network Firewall',
},
[logRetentionPeriod.logicalId]: {
- default: "Select the log retention period for Network Firewall" +
- " Logs.",
- }
+ default: 'Select the log retention period for Network Firewall Logs.',
+ },
},
},
};
@@ -162,19 +187,19 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
/**
* Mappings - define fixed values
*/
- const mappings = new cdk.CfnMapping(this, 'SolutionMapping')
- mappings.setValue('Version', 'Latest', 'latest')
- mappings.setValue('Route', 'QuadZero', '0.0.0.0/0')
- mappings.setValue('Log', 'Level', 'info')
- mappings.setValue('CodeCommitRepo', 'Name', 'network-firewall-config-repo-')
- mappings.setValue('Metrics', 'URL', 'https://metrics.awssolutionsbuilder.com/generic')
- mappings.setValue('Solution', 'Identifier', 'SO0108')
- mappings.setValue('TransitGatewayAttachment', 'ApplianceMode', 'enable')
-
- const send = new cdk.CfnMapping(this, 'Send')
- send.setValue('AnonymousUsage', 'Data', 'Yes')
- send.setValue('ParameterKey', 'UniqueId', `/Solutions/${props.solutionName}/UUID`)
-
+ const mappings = new CfnMapping(this, 'SolutionMapping');
+ mappings.setValue('Version', 'Latest', 'latest');
+ mappings.setValue('Route', 'QuadZero', '0.0.0.0/0');
+ mappings.setValue('Log', 'Level', 'info');
+ mappings.setValue('CodeCommitRepo', 'Name', 'network-firewall-config-repo-');
+ mappings.setValue('Metrics', 'URL', 'https://metrics.awssolutionsbuilder.com/generic');
+ mappings.setValue('Solution', 'Identifier', props.solutionId);
+ mappings.setValue('Solution', 'Version', props.solutionVersion);
+ mappings.setValue('TransitGatewayAttachment', 'ApplianceMode', 'enable');
+
+ const send = new CfnMapping(this, 'Send');
+ send.setValue('AnonymousUsage', 'Data', 'Yes');
+ send.setValue('ParameterKey', 'UniqueId', `Solutions/${props.solutionName}/UUID`);
/**
* Conditions - control whether certain resources are created or whether
@@ -182,60 +207,48 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
* creation or update.
*/
- const isLoggingInS3 = new cdk.CfnCondition(this,
- "LoggingInS3",
- {
- expression: cdk.Fn.conditionEquals(logDestinationType.valueAsString, 'S3')
- })
+ const isLoggingInS3 = new CfnCondition(this, 'LoggingInS3', {
+ expression: Fn.conditionEquals(logDestinationType.valueAsString, 'S3'),
+ });
- const isLoggingInCloudWatch = new cdk.CfnCondition(this,
- "LoggingInCloudWatch",
- {
- expression: cdk.Fn.conditionEquals(logDestinationType.valueAsString, 'CloudWatchLogs')
- })
+ const isLoggingInCloudWatch = new CfnCondition(this, 'LoggingInCloudWatch', {
+ expression: Fn.conditionEquals(logDestinationType.valueAsString, 'CloudWatchLogs'),
+ });
- const isNotLoggingConfigureManually = new cdk.CfnCondition(this,
- "NotLoggingConfigureManually",
- {
- expression: cdk.Fn.conditionNot(cdk.Fn.conditionEquals(logDestinationType.valueAsString, 'ConfigureManually'))
- })
+ const isNotLoggingConfigureManually = new CfnCondition(this, 'NotLoggingConfigureManually', {
+ expression: Fn.conditionNot(Fn.conditionEquals(logDestinationType.valueAsString, 'ConfigureManually')),
+ });
/**
* condition to determine if transit gateway id is provided or not if
* provided use it to create transit gateway attachment else skip
*/
- const createTransitGatewayAttachment = new cdk.CfnCondition(this,
- "CreateTransitGatewayAttachment",
- {
- expression: cdk.Fn.conditionNot(cdk.Fn.conditionEquals(existingTransitGatewayId.valueAsString, ''))
- })
+ const createTransitGatewayAttachment = new CfnCondition(this, 'CreateTransitGatewayAttachment', {
+ expression: Fn.conditionNot(Fn.conditionEquals(existingTransitGatewayId.valueAsString, '')),
+ });
/**
* condition to determine if transit gateway route table id is provided or
* not. if provided use it to create route table association else skip
*/
- const createTransitGatewayRTAssociation = new cdk.CfnCondition(this,
- "CreateTransitGatewayRTAssociation",
- {
- expression: cdk.Fn.conditionAnd(
- cdk.Fn.conditionNot(
- cdk.Fn.conditionEquals(
- transitGatewayRTIdForAssociation.valueAsString, '')), createTransitGatewayAttachment)
- })
+ const createTransitGatewayRTAssociation = new CfnCondition(this, 'CreateTransitGatewayRTAssociation', {
+ expression: Fn.conditionAnd(
+ Fn.conditionNot(Fn.conditionEquals(transitGatewayRTIdForAssociation.valueAsString, '')),
+ createTransitGatewayAttachment
+ ),
+ });
/**
* condition to determine if transit gateway route table id is provided or
* not. if provided use it to create route table propagation else skip
*/
- const createDefaultRouteFirewallRT = new cdk.CfnCondition(this,
- "CreateDefaultRouteFirewallRT",
- {
- expression: cdk.Fn.conditionAnd(
- cdk.Fn.conditionNot(
- cdk.Fn.conditionEquals(
- transitGatewayRTIdForDefaultRoute.valueAsString, '')), createTransitGatewayAttachment)
- })
+ const createDefaultRouteFirewallRT = new CfnCondition(this, 'CreateDefaultRouteFirewallRT', {
+ expression: Fn.conditionAnd(
+ Fn.conditionNot(Fn.conditionEquals(transitGatewayRTIdForDefaultRoute.valueAsString, '')),
+ createTransitGatewayAttachment
+ ),
+ });
/**
* Resources - Specifies the stack resources and their properties
@@ -245,408 +258,386 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
// Create a new VPC
- const vpc = new ec2.CfnVPC(this, 'VPC', {
+ const vpc = new CfnVPC(this, 'VPC', {
cidrBlock: cidrBlock.valueAsString,
});
//KMS Key for the VPC Flow logs and Firewall Logs
- const KMSKeyForNetworkFirewallLogDestinations = new kms.Key(this, "KMSKeyForNetworkFirewallLogDestinations", {
- description: "This key will be used for encrypting the vpc flow logs and firewall logs.",
- enableKeyRotation: true
- })
-
- //Permissions for network firewall service to be able use this key for publishing logs to S3.
- KMSKeyForNetworkFirewallLogDestinations.addToResourcePolicy(new iam.PolicyStatement({
- effect: iam.Effect.ALLOW,
- resources: ["*"],
- principals: [new iam.ServicePrincipal("delivery.logs.amazonaws.com")],
- actions: ["kms:GenerateDataKey*"]
- }))
+ const KMSKeyForNetworkFirewallBuckets = new Key(this, 'KMSKeyForNetworkFirewallBuckets', {
+ description: 'This key will be used for encrypting the vpc flow logs and firewall logs.',
+ enableKeyRotation: true,
+ });
+
+ //Permissions for network firewall service to be able use this key for publishing logs to
+ KMSKeyForNetworkFirewallBuckets.addToResourcePolicy(
+ new PolicyStatement({
+ effect: Effect.ALLOW,
+ resources: ['*'],
+ principals: [new ServicePrincipal('delivery.logs.amazonaws.com')],
+ actions: ['kms:GenerateDataKey*'],
+ })
+ );
//Permissions for network firewall service to be able use this key for publishing logs to cloudwatch.
- KMSKeyForNetworkFirewallLogDestinations.addToResourcePolicy(new iam.PolicyStatement({
- effect: iam.Effect.ALLOW,
- resources: ["*"],
- actions: [
- "kms:Encrypt*",
- "kms:Decrypt*",
- "kms:ReEncrypt*",
- "kms:GenerateDataKey*",
- "kms:Describe*"
- ],
- principals: [
- new iam.ServicePrincipal(`logs.${cdk.Aws.REGION}.amazonaws.com`)
- ]
- }))
+ KMSKeyForNetworkFirewallBuckets.addToResourcePolicy(
+ new PolicyStatement({
+ effect: Effect.ALLOW,
+ resources: ['*'],
+ actions: ['kms:Encrypt*', 'kms:Decrypt*', 'kms:ReEncrypt*', 'kms:GenerateDataKey*', 'kms:Describe*'],
+ principals: [new ServicePrincipal(`logs.${Aws.REGION}.amazonaws.com`)],
+ })
+ );
// Create a new log group for Firewall logging
- const cloudWatchLogGroup = new logs.CfnLogGroup(this, 'CloudWatchLogGroup', {
+ const cloudWatchLogGroup = new CfnLogGroup(this, 'CloudWatchLogGroup', {
retentionInDays: logRetentionPeriod.valueAsNumber,
- kmsKeyId: KMSKeyForNetworkFirewallLogDestinations.keyArn
- })
+ kmsKeyId: KMSKeyForNetworkFirewallBuckets.keyArn,
+ });
cloudWatchLogGroup.cfnOptions.condition = isLoggingInCloudWatch;
- const logsBucket = new s3.Bucket(this, 'Logs', {
- encryption: s3.BucketEncryption.KMS,
- encryptionKey: KMSKeyForNetworkFirewallLogDestinations,
+ const logsBucket = new Bucket(this, 'Logs', {
+ encryption: BucketEncryption.KMS,
+ encryptionKey: KMSKeyForNetworkFirewallBuckets,
publicReadAccess: false,
- blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
- lifecycleRules: [{
- expiration: cdk.Duration.days(logRetentionPeriod.valueAsNumber)
- }]
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
+ lifecycleRules: [
+ {
+ expiration: Duration.days(logRetentionPeriod.valueAsNumber),
+ },
+ ],
});
- const cfnLogsBucket = logsBucket.node.defaultChild as s3.CfnBucket;
+ const cfnLogsBucket = logsBucket.node.defaultChild as CfnBucket;
cfnLogsBucket.cfnOptions.metadata = {
cfn_nag: {
- rules_to_suppress: [{
- id: 'W35',
- reason: 'Logs bucket does not require logging configuration'
- }, {
- id: 'W51',
- reason: 'Logs bucket is private and does not require a bucket policy'
- }]
- }
+ rules_to_suppress: [
+ {
+ id: 'W35',
+ reason: 'Logs bucket does not require logging configuration',
+ },
+ {
+ id: 'W51',
+ reason: 'Logs bucket is private and does not require a bucket policy',
+ },
+ ],
+ },
};
cfnLogsBucket.cfnOptions.condition = isLoggingInS3;
//Solution Logging Changes stop.
+ vpc.applyRemovalPolicy(RemovalPolicy.RETAIN);
+ vpc.tags.setTag('Name', `${Aws.STACK_NAME}-Inspection-VPC`);
+ vpc.tags.setTag('created-by', `${props.solutionName}`);
- vpc.applyRemovalPolicy(RemovalPolicy.RETAIN)
- vpc.tags.setTag('Name', `${cdk.Aws.STACK_NAME}-Inspection-VPC`)
- vpc.tags.setTag('created-by', `${props.solutionName}`)
-
- const cidrCount = 4
- const cidrBits = '4'
+ const cidrCount = 4;
+ const cidrBits = '4';
const availabilityZoneA = {
- "Fn::Select": [
- "0",
+ 'Fn::Select': [
+ '0',
{
- "Fn::GetAZs": ""
- }
- ]
- }
+ 'Fn::GetAZs': '',
+ },
+ ],
+ };
const availabilityZoneB = {
- "Fn::Select": [
- "1",
+ 'Fn::Select': [
+ '1',
{
- "Fn::GetAZs": ""
- }
- ]
- }
+ 'Fn::GetAZs': '',
+ },
+ ],
+ };
// Create Firewall Subnet 1
- const NetworkFirewallSubnet1 = new ec2.CfnSubnet(this, "NetworkFirewallSubnet1", {
+ const NetworkFirewallSubnet1 = new CfnSubnet(this, 'NetworkFirewallSubnet1', {
vpcId: vpc.ref,
- cidrBlock: cdk.Fn.select(
- 0,
- cdk.Fn.cidr(
- vpc.attrCidrBlock,
- cidrCount,
- cidrBits
- )
- )
- })
- NetworkFirewallSubnet1.tags.setTag("Name", `${cdk.Aws.STACK_NAME}-FirewallSubnet1`)
- NetworkFirewallSubnet1.applyRemovalPolicy(RemovalPolicy.RETAIN)
- NetworkFirewallSubnet1.addPropertyOverride('AvailabilityZone', availabilityZoneA)
-
+ cidrBlock: Fn.select(0, Fn.cidr(vpc.attrCidrBlock, cidrCount, cidrBits)),
+ });
+ NetworkFirewallSubnet1.tags.setTag('Name', `${Aws.STACK_NAME}-FirewallSubnet1`);
+ NetworkFirewallSubnet1.applyRemovalPolicy(RemovalPolicy.RETAIN);
+ NetworkFirewallSubnet1.addPropertyOverride('AvailabilityZone', availabilityZoneA);
// Create Firewall Subnet 2
- const NetworkFirewallSubnet2 = new ec2.CfnSubnet(this, "NetworkFirewallSubnet2", {
+ const NetworkFirewallSubnet2 = new CfnSubnet(this, 'NetworkFirewallSubnet2', {
vpcId: vpc.ref,
- cidrBlock: cdk.Fn.select(
- 1,
- cdk.Fn.cidr(
- vpc.attrCidrBlock,
- cidrCount,
- cidrBits
- )
- )
- })
-
- NetworkFirewallSubnet2.tags.setTag("Name", `${cdk.Aws.STACK_NAME}-FirewallSubnet2`)
- NetworkFirewallSubnet2.applyRemovalPolicy(RemovalPolicy.RETAIN)
- NetworkFirewallSubnet2.addPropertyOverride('AvailabilityZone', availabilityZoneB)
+ cidrBlock: Fn.select(1, Fn.cidr(vpc.attrCidrBlock, cidrCount, cidrBits)),
+ });
+
+ NetworkFirewallSubnet2.tags.setTag('Name', `${Aws.STACK_NAME}-FirewallSubnet2`);
+ NetworkFirewallSubnet2.applyRemovalPolicy(RemovalPolicy.RETAIN);
+ NetworkFirewallSubnet2.addPropertyOverride('AvailabilityZone', availabilityZoneB);
//Subnet Route Tables.
- const firewallSubnetRouteTable = new ec2.CfnRouteTable(this, "FirewallSubnetRouteTable", {
- vpcId: vpc.ref
- })
- firewallSubnetRouteTable.tags.setTag("Name", `${cdk.Aws.STACK_NAME}-FirewallSubnetRouteTable`)
- firewallSubnetRouteTable.applyRemovalPolicy(RemovalPolicy.RETAIN)
+ const firewallSubnetRouteTable = new CfnRouteTable(this, 'FirewallSubnetRouteTable', {
+ vpcId: vpc.ref,
+ });
+ firewallSubnetRouteTable.tags.setTag('Name', `${Aws.STACK_NAME}-FirewallSubnetRouteTable`);
+ firewallSubnetRouteTable.applyRemovalPolicy(RemovalPolicy.RETAIN);
//Subnet Route Table Associations.
- const NetworkFirewallSubnet1RouteTableAssociation = new ec2.CfnSubnetRouteTableAssociation(this, "NetworkFirewallSubnet1RouteTableAssociation", {
- subnetId: NetworkFirewallSubnet1.ref,
- routeTableId: firewallSubnetRouteTable.ref
- })
- NetworkFirewallSubnet1RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN)
-
- const NetworkFirewallSubnet2RouteTableAssociation = new ec2.CfnSubnetRouteTableAssociation(this, "NetworkFirewallSubnet2RouteTableAssociation", {
- subnetId: NetworkFirewallSubnet2.ref,
- routeTableId: firewallSubnetRouteTable.ref
- })
- NetworkFirewallSubnet2RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN)
+ const NetworkFirewallSubnet1RouteTableAssociation = new CfnSubnetRouteTableAssociation(
+ this,
+ 'NetworkFirewallSubnet1RouteTableAssociation',
+ {
+ subnetId: NetworkFirewallSubnet1.ref,
+ routeTableId: firewallSubnetRouteTable.ref,
+ }
+ );
+ NetworkFirewallSubnet1RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN);
+
+ const NetworkFirewallSubnet2RouteTableAssociation = new CfnSubnetRouteTableAssociation(
+ this,
+ 'NetworkFirewallSubnet2RouteTableAssociation',
+ {
+ subnetId: NetworkFirewallSubnet2.ref,
+ routeTableId: firewallSubnetRouteTable.ref,
+ }
+ );
+ NetworkFirewallSubnet2RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN);
// Create Transit Gateway Subnet 1
- const vpcTGWSubnet1 = new ec2.CfnSubnet(this, "VPCTGWSubnet1", {
+ const vpcTGWSubnet1 = new CfnSubnet(this, 'VPCTGWSubnet1', {
vpcId: vpc.ref,
- cidrBlock: cdk.Fn.select(
- 2,
- cdk.Fn.cidr(
- vpc.attrCidrBlock,
- cidrCount,
- cidrBits
- )
- )
- })
- vpcTGWSubnet1.tags.setTag("Name", `${cdk.Aws.STACK_NAME}-VPCTGWSubnet1`)
- vpcTGWSubnet1.applyRemovalPolicy(RemovalPolicy.RETAIN)
- vpcTGWSubnet1.addPropertyOverride('AvailabilityZone', availabilityZoneA)
+ cidrBlock: Fn.select(2, Fn.cidr(vpc.attrCidrBlock, cidrCount, cidrBits)),
+ });
+ vpcTGWSubnet1.tags.setTag('Name', `${Aws.STACK_NAME}-VPCTGWSubnet1`);
+ vpcTGWSubnet1.applyRemovalPolicy(RemovalPolicy.RETAIN);
+ vpcTGWSubnet1.addPropertyOverride('AvailabilityZone', availabilityZoneA);
// Create Transit Gateway Subnet 2
- const vpcTGWSubnet2 = new ec2.CfnSubnet(this, "VPCTGWSubnet2", {
+ const vpcTGWSubnet2 = new CfnSubnet(this, 'VPCTGWSubnet2', {
vpcId: vpc.ref,
- cidrBlock: cdk.Fn.select(
- 3,
- cdk.Fn.cidr(
- vpc.attrCidrBlock,
- cidrCount,
- cidrBits
- )
- )
- })
- vpcTGWSubnet2.tags.setTag("Name", `${cdk.Aws.STACK_NAME}-VPCTGWSubnet2`)
- vpcTGWSubnet2.applyRemovalPolicy(RemovalPolicy.RETAIN)
- vpcTGWSubnet2.addPropertyOverride('AvailabilityZone', availabilityZoneB)
+ cidrBlock: Fn.select(3, Fn.cidr(vpc.attrCidrBlock, cidrCount, cidrBits)),
+ });
+ vpcTGWSubnet2.tags.setTag('Name', `${Aws.STACK_NAME}-VPCTGWSubnet2`);
+ vpcTGWSubnet2.applyRemovalPolicy(RemovalPolicy.RETAIN);
+ vpcTGWSubnet2.addPropertyOverride('AvailabilityZone', availabilityZoneB);
//Route Tables for VPC Transit Gateway subnets.
- const vpcTGWRouteTable1 = new ec2.CfnRouteTable(this, "VPCTGWRouteTable1", {
- vpcId: vpc.ref
- })
- vpcTGWRouteTable1.tags.setTag("Name", `${cdk.Aws.STACK_NAME}-TGWSubnetRouteTable1`)
- vpcTGWRouteTable1.applyRemovalPolicy(RemovalPolicy.RETAIN)
-
- const vpcTGWRouteTable2 = new ec2.CfnRouteTable(this, "VPCTGWRouteTable2", {
- vpcId: vpc.ref
- })
- vpcTGWRouteTable2.tags.setTag("Name", `${cdk.Aws.STACK_NAME}-TGWSubnetRouteTable2`)
- vpcTGWRouteTable2.applyRemovalPolicy(RemovalPolicy.RETAIN)
+ const vpcTGWRouteTable1 = new CfnRouteTable(this, 'VPCTGWRouteTable1', {
+ vpcId: vpc.ref,
+ });
+ vpcTGWRouteTable1.tags.setTag('Name', `${Aws.STACK_NAME}-TGWSubnetRouteTable1`);
+ vpcTGWRouteTable1.applyRemovalPolicy(RemovalPolicy.RETAIN);
+
+ const vpcTGWRouteTable2 = new CfnRouteTable(this, 'VPCTGWRouteTable2', {
+ vpcId: vpc.ref,
+ });
+ vpcTGWRouteTable2.tags.setTag('Name', `${Aws.STACK_NAME}-TGWSubnetRouteTable2`);
+ vpcTGWRouteTable2.applyRemovalPolicy(RemovalPolicy.RETAIN);
//Subnet Route Table Associations for Transit Gateway Subnets
- const vpcTGWSubnet1RouteTableAssociation = new ec2.CfnSubnetRouteTableAssociation(this, "VPCTGWSubnet1RouteTableAssociation", {
- subnetId: vpcTGWSubnet1.ref,
- routeTableId: vpcTGWRouteTable1.ref
- })
- vpcTGWSubnet1RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN)
-
- const vpcTGWSubnet2RouteTableAssociation = new ec2.CfnSubnetRouteTableAssociation(this, "VPCTGWSubnet2RouteTableAssociation", {
- subnetId: vpcTGWSubnet2.ref,
- routeTableId: vpcTGWRouteTable2.ref,
- })
- vpcTGWSubnet2RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN)
+ const vpcTGWSubnet1RouteTableAssociation = new CfnSubnetRouteTableAssociation(
+ this,
+ 'VPCTGWSubnet1RouteTableAssociation',
+ {
+ subnetId: vpcTGWSubnet1.ref,
+ routeTableId: vpcTGWRouteTable1.ref,
+ }
+ );
+ vpcTGWSubnet1RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN);
+
+ const vpcTGWSubnet2RouteTableAssociation = new CfnSubnetRouteTableAssociation(
+ this,
+ 'VPCTGWSubnet2RouteTableAssociation',
+ {
+ subnetId: vpcTGWSubnet2.ref,
+ routeTableId: vpcTGWRouteTable2.ref,
+ }
+ );
+ vpcTGWSubnet2RouteTableAssociation.applyRemovalPolicy(RemovalPolicy.RETAIN);
//VPC Flow Log
- const logGroup = new logs.CfnLogGroup(this, "LogGroupFlowLogs", {
+ const logGroup = new CfnLogGroup(this, 'LogGroupFlowLogs', {
retentionInDays: logRetentionPeriod.valueAsNumber,
- logGroupName: cdk.Aws.STACK_NAME,
- kmsKeyId: KMSKeyForNetworkFirewallLogDestinations.keyArn
- })
+ logGroupName: Aws.STACK_NAME,
+ kmsKeyId: KMSKeyForNetworkFirewallBuckets.keyArn,
+ });
- const flowLogRole = new iam.Role(this, "RoleFlowLogs", {
- assumedBy: new iam.ServicePrincipal("vpc-flow-logs.amazonaws.com")
+ const flowLogRole = new Role(this, 'RoleFlowLogs', {
+ assumedBy: new ServicePrincipal('vpc-flow-logs.amazonaws.com'),
});
- const policyStatement = new iam.PolicyStatement({
+ const policyStatement = new PolicyStatement({
actions: [
- "logs:CreateLogStream",
- "logs:DescribeLogStreams",
- "logs:PutLogEvents",
- "logs:CreateLogGroup",
- "logs:DescribeLogGroups"],
- resources: [logGroup.attrArn]
+ 'logs:CreateLogStream',
+ 'logs:DescribeLogStreams',
+ 'logs:PutLogEvents',
+ 'logs:CreateLogGroup',
+ 'logs:DescribeLogGroups',
+ ],
+ resources: [logGroup.attrArn],
});
- policyStatement.effect = iam.Effect.ALLOW;
+ policyStatement.effect = Effect.ALLOW;
flowLogRole.addToPolicy(policyStatement);
-
- new ec2.CfnFlowLog(this, "FlowLog", {
+ new CfnFlowLog(this, 'FlowLog', {
deliverLogsPermissionArn: flowLogRole.roleArn,
logGroupName: logGroup.logGroupName,
resourceId: vpc.ref,
- resourceType: "VPC",
- trafficType: "ALL"
+ resourceType: 'VPC',
+ trafficType: 'ALL',
});
//Start: associate for an existing transit gateway if user provides one.
-
//Transit gateway attachment.
- const vpcTGWAttachment = new ec2.CfnTransitGatewayAttachment(this, 'VPC_TGW_ATTACHMENT', {
+ const vpcTGWAttachment = new CfnTransitGatewayAttachment(this, 'VPC_TGW_ATTACHMENT', {
transitGatewayId: existingTransitGatewayId.valueAsString,
vpcId: vpc.ref,
- subnetIds: [
- vpcTGWSubnet1.ref,
- vpcTGWSubnet2.ref
- ]
- })
- vpcTGWAttachment.cfnOptions.condition = createTransitGatewayAttachment
- vpcTGWAttachment.tags.setTag('Name', `${cdk.Aws.STACK_NAME}-Inspection-VPC-Attachment`)
- vpcTGWAttachment.applyRemovalPolicy(RemovalPolicy.RETAIN)
- vpcTGWAttachment.addDeletionOverride("UpdateReplacePolicy")
+ subnetIds: [vpcTGWSubnet1.ref, vpcTGWSubnet2.ref],
+ });
+ vpcTGWAttachment.cfnOptions.condition = createTransitGatewayAttachment;
+ vpcTGWAttachment.tags.setTag('Name', `${Aws.STACK_NAME}-Inspection-VPC-Attachment`);
+ vpcTGWAttachment.applyRemovalPolicy(RemovalPolicy.RETAIN);
+ vpcTGWAttachment.addDeletionOverride('UpdateReplacePolicy');
//add the transit gateway id provided by the user to the firewall route
// table created for transit gateway interaction.
- const defaultTransitGatewayRoute = new ec2.CfnRoute(this, 'TGWRoute', {
+ const defaultTransitGatewayRoute = new CfnRoute(this, 'TGWRoute', {
routeTableId: firewallSubnetRouteTable.ref,
destinationCidrBlock: mappings.findInMap('Route', 'QuadZero'),
- transitGatewayId: existingTransitGatewayId.valueAsString
- })
- defaultTransitGatewayRoute.cfnOptions.condition = createTransitGatewayAttachment
- defaultTransitGatewayRoute.addDependsOn(vpcTGWAttachment)
-
+ transitGatewayId: existingTransitGatewayId.valueAsString,
+ });
+ defaultTransitGatewayRoute.cfnOptions.condition = createTransitGatewayAttachment;
+ defaultTransitGatewayRoute.addDependsOn(vpcTGWAttachment);
//Transit Gateway association with the TGW route table id provided by the user.
- const tgwRouteTableAssociation = new ec2.CfnTransitGatewayRouteTableAssociation(this, 'VPCTGWRouteTableAssociation', {
+ const tgwRouteTableAssociation = new CfnTransitGatewayRouteTableAssociation(this, 'VPCTGWRouteTableAssociation', {
transitGatewayAttachmentId: vpcTGWAttachment.ref,
- transitGatewayRouteTableId: transitGatewayRTIdForAssociation.valueAsString
- })
+ transitGatewayRouteTableId: transitGatewayRTIdForAssociation.valueAsString,
+ });
//createTransitGatewayRTAssociation
- tgwRouteTableAssociation.cfnOptions.condition = createTransitGatewayRTAssociation
- tgwRouteTableAssociation.addOverride("DeletionPolicy", "Retain")
- tgwRouteTableAssociation.addDeletionOverride("UpdateReplacePolicy")
+ tgwRouteTableAssociation.cfnOptions.condition = createTransitGatewayRTAssociation;
+ tgwRouteTableAssociation.addOverride('DeletionPolicy', 'Retain');
+ tgwRouteTableAssociation.addDeletionOverride('UpdateReplacePolicy');
// Add default route to Instection VPC-TGW Attachment in the Spoke VPC
// Route Transit Gateway Route Table
- const defaultRouteSpokeVPCTGWRouteTable = new ec2.CfnTransitGatewayRoute(this, 'DefaultRouteSpokeVPCTGWRouteTable', {
+ const defaultRouteSpokeVPCTGWRouteTable = new CfnTransitGatewayRoute(this, 'DefaultRouteSpokeVPCTGWRouteTable', {
transitGatewayRouteTableId: transitGatewayRTIdForDefaultRoute.valueAsString,
destinationCidrBlock: mappings.findInMap('Route', 'QuadZero'),
- transitGatewayAttachmentId: vpcTGWAttachment.ref
- })
- defaultRouteSpokeVPCTGWRouteTable.cfnOptions.condition = createDefaultRouteFirewallRT
- defaultRouteSpokeVPCTGWRouteTable.addOverride("DeletionPolicy", "Retain")
+ transitGatewayAttachmentId: vpcTGWAttachment.ref,
+ });
+ defaultRouteSpokeVPCTGWRouteTable.cfnOptions.condition = createDefaultRouteFirewallRT;
+ defaultRouteSpokeVPCTGWRouteTable.addOverride('DeletionPolicy', 'Retain');
//End: Transit gateway changes.
//CodeCommit Repo and Code Pipeline with default policy created.
- const codeCommitRepo = new codecommit.Repository(this, 'NetworkFirewallCodeRepository', {
- repositoryName: mappings.findInMap("CodeCommitRepo", "Name") + cdk.Aws.STACK_NAME,
- description: 'This repository is created by the AWS Network Firewall' +
+ const codeCommitRepo = new Repository(this, 'NetworkFirewallCodeRepository', {
+ repositoryName: mappings.findInMap('CodeCommitRepo', 'Name') + Aws.STACK_NAME,
+ description:
+ 'This repository is created by the AWS Network Firewall' +
' solution for AWS Transit Gateway, to store and trigger changes to' +
- ' the network firewall rules and configurations.'
- })
+ ' the network firewall rules and configurations.',
+ });
- const codeCommitRepo_cfn_ref = codeCommitRepo.node.defaultChild as codecommit.CfnRepository
- codeCommitRepo_cfn_ref.addOverride("Properties.Code.S3.Bucket", `${props.solutionBucket}-${this.region}`)
- codeCommitRepo_cfn_ref.addOverride("Properties.Code.S3.Key", `${props.solutionName}/${mappings.findInMap('Version', 'Latest')}/network-firewall-configuration.zip`)
- codeCommitRepo_cfn_ref.addOverride("DeletionPolicy", "Retain")
- codeCommitRepo_cfn_ref.addOverride("UpdateReplacePolicy", "Retain")
+ const codeCommitRepo_cfn_ref = codeCommitRepo.node.defaultChild as CfnRepository;
+ codeCommitRepo_cfn_ref.addOverride('Properties.Code.S3.Bucket', `${props.solutionBucket}-${this.region}`);
+ codeCommitRepo_cfn_ref.addOverride(
+ 'Properties.Code.S3.Key',
+ `${props.solutionName}/${mappings.findInMap('Version', 'Latest')}/network-firewall-configuration.zip`
+ );
+ codeCommitRepo_cfn_ref.addOverride('DeletionPolicy', 'Retain');
+ codeCommitRepo_cfn_ref.addOverride('UpdateReplacePolicy', 'Retain');
- const codeBuildStagesSourceCodeBucket = new s3.Bucket(this, 'CodeBuildStagesSourceCodeBucket', {
+ const codeBuildStagesSourceCodeBucket = new Bucket(this, 'CodeBuildStagesSourceCodeBucket', {
publicReadAccess: false,
- blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
});
- const sourceOutputArtifact = new codepipeline.Artifact('SourceArtifact')
- const buildOutputArtifact = new codepipeline.Artifact('BuildArtifact')
+ const sourceOutputArtifact = new Artifact('SourceArtifact');
+ const buildOutputArtifact = new Artifact('BuildArtifact');
- const subnetIds = NetworkFirewallSubnet1.ref + ',' + NetworkFirewallSubnet2.ref
+ const subnetIds = NetworkFirewallSubnet1.ref + ',' + NetworkFirewallSubnet2.ref;
const codeBuildEnvVariables = {
- ['LOG_LEVEL']:
- {
+ ['LOG_LEVEL']: {
value: mappings.findInMap('Log', 'Level'),
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['VPC_ID']:
- {
+ ['VPC_ID']: {
value: vpc.ref,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['SUBNET_IDS']:
- {
+ ['SUBNET_IDS']: {
value: subnetIds,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['LOG_TYPE']:
- {
+ ['LOG_TYPE']: {
value: logType.valueAsString,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['LOG_DESTINATION_TYPE']:
- {
+ ['LOG_DESTINATION_TYPE']: {
value: logDestinationType.valueAsString,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['S3_LOG_BUCKET_NAME']:
- {
- value: cdk.Fn.conditionIf('LoggingInS3', logsBucket.bucketName, 'NotConfigured'),
- type: BuildEnvironmentVariableType.PLAINTEXT
+ ['S3_LOG_BUCKET_NAME']: {
+ value: Fn.conditionIf('LoggingInS3', logsBucket.bucketName, 'NotConfigured'),
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['CLOUDWATCH_LOG_GROUP_NAME']:
- {
- value: cdk.Fn.conditionIf('LoggingInCloudWatch', cloudWatchLogGroup.ref, 'NotConfigured'),
- type: BuildEnvironmentVariableType.PLAINTEXT
+ ['CLOUDWATCH_LOG_GROUP_NAME']: {
+ value: Fn.conditionIf('LoggingInCloudWatch', cloudWatchLogGroup.ref, 'NotConfigured'),
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['VPC_TGW_ATTACHMENT_AZ_1']:
- {
- value: cdk.Fn.getAtt(
- 'NetworkFirewallSubnet1',
- 'AvailabilityZone').toString(),
- type: BuildEnvironmentVariableType.PLAINTEXT
+ ['VPC_TGW_ATTACHMENT_AZ_1']: {
+ value: Fn.getAtt('NetworkFirewallSubnet1', 'AvailabilityZone').toString(),
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['VPC_TGW_ATTACHMENT_AZ_2']:
- {
- value: cdk.Fn.getAtt(
- 'NetworkFirewallSubnet2',
- 'AvailabilityZone').toString(),
- type: BuildEnvironmentVariableType.PLAINTEXT
+ ['VPC_TGW_ATTACHMENT_AZ_2']: {
+ value: Fn.getAtt('NetworkFirewallSubnet2', 'AvailabilityZone').toString(),
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_1']:
- {
+ ['VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_1']: {
value: vpcTGWRouteTable1.ref,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
- ['VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_2']:
- {
+ ['VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_2']: {
value: vpcTGWRouteTable2.ref,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['CODE_BUILD_SOURCE_CODE_S3_KEY']: {
value: `${props.solutionName}/${props.solutionVersion}`,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['STACK_ID']: {
- value: `${cdk.Aws.STACK_ID}`,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ value: `${Aws.STACK_ID}`,
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['SSM_PARAM_FOR_UUID']: {
- value: send.findInMap('ParameterKey', 'UniqueId'),
- type: BuildEnvironmentVariableType.PLAINTEXT
+ value: `/${send.findInMap('ParameterKey', 'UniqueId')}`,
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['SEND_ANONYMOUS_METRICS']: {
value: `${send.findInMap('AnonymousUsage', 'Data')}`,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['SOLUTION_ID']: {
value: `${mappings.findInMap('Solution', 'Identifier')}`,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['METRICS_URL']: {
value: `${mappings.findInMap('Metrics', 'URL')}`,
- type: BuildEnvironmentVariableType.PLAINTEXT
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['TRANSIT_GATEWAY_ATTACHMENT_ID']: {
- value: cdk.Fn.conditionIf(createTransitGatewayAttachment.logicalId, vpcTGWAttachment.ref, ''),
- type: BuildEnvironmentVariableType.PLAINTEXT
+ value: Fn.conditionIf(createTransitGatewayAttachment.logicalId, vpcTGWAttachment.ref, ''),
+ type: BuildEnvironmentVariableType.PLAINTEXT,
},
['TRANSIT_GATEWAY_ATTACHMENT_APPLIANCE_MODE']: {
value: mappings.findInMap('TransitGatewayAttachment', 'ApplianceMode'),
- type: BuildEnvironmentVariableType.PLAINTEXT
- }
- }
+ type: BuildEnvironmentVariableType.PLAINTEXT,
+ },
+ ['CUSTOM_SDK_USER_AGENT']: {
+ value: `AwsSolution/${mappings.findInMap('Solution', 'Identifier')}/${mappings.findInMap(
+ 'Solution',
+ 'Version'
+ )}`,
+ type: BuildEnvironmentVariableType.PLAINTEXT,
+ },
+ };
// Code build project, code build role will be created by the construct.
const buildProject = new PipelineProject(this, 'BuildProject', {
@@ -655,9 +646,9 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
phases: {
install: {
'runtime-versions': {
- nodejs: '12'
+ nodejs: '16',
},
- commands: [`export current=$(pwd)`, `export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY`]
+ commands: [`export current=$(pwd)`, `export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY`],
},
pre_build: {
commands: [
@@ -665,263 +656,246 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
`pwd; ls -ltr`,
`echo 'Download Network Firewall Solution Package'`,
`aws s3 cp s3://${codeBuildStagesSourceCodeBucket.bucketName}/$sourceCodeKey/network-firewall-automation.zip $current || true`,
- `if [ -f $current/network-firewall-automation.zip ];then exit 0;else echo \"Copy file to s3 bucket\"; aws s3 cp s3://${props.solutionBucket}-${cdk.Aws.REGION}/$sourceCodeKey/network-firewall-automation.zip s3://${codeBuildStagesSourceCodeBucket.bucketName}/$sourceCodeKey/network-firewall-automation.zip; aws s3 cp s3://${codeBuildStagesSourceCodeBucket.bucketName}/$sourceCodeKey/network-firewall-automation.zip $current; fi;`,
+ `if [ -f $current/network-firewall-automation.zip ];then exit 0;else echo \"Copy file to s3 bucket\"; aws s3 cp s3://${props.solutionBucket}-${Aws.REGION}/$sourceCodeKey/network-firewall-automation.zip s3://${codeBuildStagesSourceCodeBucket.bucketName}/$sourceCodeKey/network-firewall-automation.zip --copy-props none; aws s3 cp s3://${codeBuildStagesSourceCodeBucket.bucketName}/$sourceCodeKey/network-firewall-automation.zip $current; fi;`,
`unzip -o $current/network-firewall-automation.zip -d $current`,
`pwd; ls -ltr`,
- ]
+ ],
},
build: {
- commands: [
- `echo "Validating the firewall config"`,
- `node build.js`
- ]
- }
+ commands: [`echo "Validating the firewall config"`, `node build.js`],
+ },
},
artifacts: {
- files: "**/*"
- }
+ files: '**/*',
+ },
}),
environment: {
- buildImage: LinuxBuildImage.STANDARD_4_0
+ buildImage: LinuxBuildImage.STANDARD_6_0,
},
- environmentVariables: codeBuildEnvVariables
- })
+ environmentVariables: codeBuildEnvVariables,
+ });
- const buildStageIAMPolicy = new iam.Policy(this, 'buildStageIAMPolicy', {
+ const buildStageIAMPolicy = new Policy(this, 'buildStageIAMPolicy', {
statements: [
- new iam.PolicyStatement({
- actions: [
- "network-firewall:CreateFirewallPolicy",
- "network-firewall:CreateRuleGroup"
- ],
+ new PolicyStatement({
+ actions: ['network-firewall:CreateFirewallPolicy', 'network-firewall:CreateRuleGroup'],
resources: [
- cdk.Fn.sub("arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateful-rulegroup/*"),
- cdk.Fn.sub("arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:firewall-policy/*"),
- cdk.Fn.sub("arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateless-rulegroup/*")
+ Fn.sub('arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateful-rulegroup/*'),
+ Fn.sub('arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:firewall-policy/*'),
+ Fn.sub('arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateless-rulegroup/*'),
],
- effect: iam.Effect.ALLOW
- }),
- new iam.PolicyStatement({
- actions: ["s3:GetObject"],
- resources: [cdk.Fn.sub("arn:${AWS::Partition}:s3:::${CodeBucketName}/${KeyName}/*", {
- CodeBucketName: `${props.solutionBucket}-${this.region}`,
- KeyName: `${props.solutionName}`
- }),
- `arn:${cdk.Aws.PARTITION}:s3:::${codeBuildStagesSourceCodeBucket.bucketName}/*`]
+ effect: Effect.ALLOW,
}),
- new iam.PolicyStatement({
- actions: ["s3:PutObject"],
+ new PolicyStatement({
+ actions: ['s3:GetObject'],
resources: [
- `arn:${cdk.Aws.PARTITION}:s3:::${codeBuildStagesSourceCodeBucket.bucketName}/*`
+ Fn.sub('arn:${AWS::Partition}:s3:::${CodeBucketName}/${KeyName}/*', {
+ CodeBucketName: `${props.solutionBucket}-${this.region}`,
+ KeyName: `${props.solutionName}`,
+ }),
+ `arn:${Aws.PARTITION}:s3:::${codeBuildStagesSourceCodeBucket.bucketName}/*`,
],
- effect: iam.Effect.ALLOW
}),
- new iam.PolicyStatement({
- actions: [
- "ssm:PutParameter",
- "ssm:GetParameter",
- ],
- effect: iam.Effect.ALLOW,
+ new PolicyStatement({
+ actions: ['s3:PutObject'],
+ resources: [`arn:${Aws.PARTITION}:s3:::${codeBuildStagesSourceCodeBucket.bucketName}/*`],
+ effect: Effect.ALLOW,
+ }),
+ new PolicyStatement({
+ actions: ['ssm:PutParameter', 'ssm:GetParameter'],
+ effect: Effect.ALLOW,
resources: [
- cdk.Fn.sub("arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${ParameterKey}", {
- ParameterKey: `${send.findInMap('ParameterKey', 'UniqueId')}`
- })
- ]
+ Fn.sub('arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${ParameterKey}-*', {
+ ParameterKey: `${send.findInMap('ParameterKey', 'UniqueId')}`,
+ }),
+ ],
}),
- ]
- })
+ ],
+ });
- buildProject.role?.attachInlinePolicy(buildStageIAMPolicy)
+ buildProject.role?.attachInlinePolicy(buildStageIAMPolicy);
//IAM Policy and Role to execute deploy stage
- const deployStageFirewallPolicy = new iam.Policy(this,
- 'deployStageFirewallPolicy',
- {
- statements: [
- new iam.PolicyStatement({
- actions: [
- "network-firewall:CreateFirewall",
- "network-firewall:UpdateFirewallDeleteProtection",
- "network-firewall:DeleteRuleGroup",
- "network-firewall:DescribeLoggingConfiguration",
- "network-firewall:UpdateFirewallDescription",
- "network-firewall:CreateRuleGroup",
- "network-firewall:DescribeFirewall",
- "network-firewall:DeleteFirewallPolicy",
- "network-firewall:UpdateRuleGroup",
- "network-firewall:DescribeRuleGroup",
- "network-firewall:ListRuleGroups",
- "network-firewall:UpdateSubnetChangeProtection",
- "network-firewall:UpdateFirewallPolicyChangeProtection",
- "network-firewall:AssociateFirewallPolicy",
- "network-firewall:DescribeFirewallPolicy",
- "network-firewall:UpdateFirewallPolicy",
- "network-firewall:DescribeResourcePolicy",
- "network-firewall:CreateFirewallPolicy",
- "network-firewall:UpdateLoggingConfiguration",
- "network-firewall:TagResource"
- ],
- resources: [
- cdk.Fn.sub("arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateful-rulegroup/*"),
- cdk.Fn.sub("arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:firewall-policy/*"),
- cdk.Fn.sub("arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:firewall/*"),
- cdk.Fn.sub("arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateless-rulegroup/*")
- ]
- }),
- new iam.PolicyStatement({
- actions: ["s3:GetObject"],
- resources: [cdk.Fn.sub("arn:${AWS::Partition}:s3:::${CodeBucketName}/${KeyName}/*", {
+ const deployStageFirewallPolicy = new Policy(this, 'deployStageFirewallPolicy', {
+ statements: [
+ new PolicyStatement({
+ actions: [
+ 'network-firewall:CreateFirewall',
+ 'network-firewall:UpdateFirewallDeleteProtection',
+ 'network-firewall:DeleteRuleGroup',
+ 'network-firewall:DescribeLoggingConfiguration',
+ 'network-firewall:UpdateFirewallDescription',
+ 'network-firewall:CreateRuleGroup',
+ 'network-firewall:DescribeFirewall',
+ 'network-firewall:DeleteFirewallPolicy',
+ 'network-firewall:UpdateRuleGroup',
+ 'network-firewall:DescribeRuleGroup',
+ 'network-firewall:ListRuleGroups',
+ 'network-firewall:UpdateSubnetChangeProtection',
+ 'network-firewall:UpdateFirewallPolicyChangeProtection',
+ 'network-firewall:AssociateFirewallPolicy',
+ 'network-firewall:DescribeFirewallPolicy',
+ 'network-firewall:UpdateFirewallPolicy',
+ 'network-firewall:DescribeResourcePolicy',
+ 'network-firewall:CreateFirewallPolicy',
+ 'network-firewall:UpdateLoggingConfiguration',
+ 'network-firewall:TagResource',
+ ],
+ resources: [
+ Fn.sub('arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateful-rulegroup/*'),
+ Fn.sub('arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:firewall-policy/*'),
+ Fn.sub('arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:firewall/*'),
+ Fn.sub('arn:${AWS::Partition}:network-firewall:${AWS::Region}:${AWS::AccountId}:stateless-rulegroup/*'),
+ ],
+ }),
+ new PolicyStatement({
+ actions: ['s3:GetObject'],
+ resources: [
+ Fn.sub('arn:${AWS::Partition}:s3:::${CodeBucketName}/${KeyName}/*', {
CodeBucketName: `${props.solutionBucket}-${this.region}`,
- KeyName: `${props.solutionName}`
+ KeyName: `${props.solutionName}`,
}),
- `arn:${cdk.Aws.PARTITION}:s3:::${codeBuildStagesSourceCodeBucket.bucketName}/*`]
- }),
- new iam.PolicyStatement({
- actions: [
- "ec2:DescribeVpcs",
- "ec2:DescribeSubnets",
- "ec2:DescribeRouteTables"
- ],
- resources: ["*"]
- }),
- new iam.PolicyStatement({
- actions: [
- "ec2:CreateRoute",
- "ec2:DeleteRoute",
- ],
- effect: iam.Effect.ALLOW,
- resources: [
- `arn:${cdk.Aws.PARTITION}:ec2:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:route-table/${vpcTGWRouteTable1.ref}`,
- `arn:${cdk.Aws.PARTITION}:ec2:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:route-table/${vpcTGWRouteTable2.ref}`
- ]
- }),
- new iam.PolicyStatement({
- actions: ["iam:CreateServiceLinkedRole"],
- resources: [cdk.Fn.sub("arn:aws:iam::${AWS::AccountId}:role/aws-service-role/network-firewall.amazonaws.com/AWSServiceRoleForNetworkFirewall")]
- })
- ]
- })
+ `arn:${Aws.PARTITION}:s3:::${codeBuildStagesSourceCodeBucket.bucketName}/*`,
+ ],
+ }),
+ new PolicyStatement({
+ actions: ['ec2:DescribeVpcs', 'ec2:DescribeSubnets', 'ec2:DescribeRouteTables'],
+ resources: ['*'],
+ }),
+ new PolicyStatement({
+ actions: ['ec2:CreateRoute', 'ec2:DeleteRoute'],
+ effect: Effect.ALLOW,
+ resources: [
+ `arn:${Aws.PARTITION}:ec2:${Aws.REGION}:${Aws.ACCOUNT_ID}:route-table/${vpcTGWRouteTable1.ref}`,
+ `arn:${Aws.PARTITION}:ec2:${Aws.REGION}:${Aws.ACCOUNT_ID}:route-table/${vpcTGWRouteTable2.ref}`,
+ ],
+ }),
+ new PolicyStatement({
+ actions: ['iam:CreateServiceLinkedRole'],
+ resources: [
+ Fn.sub(
+ 'arn:aws:iam::${AWS::AccountId}:role/aws-service-role/network-firewall.amazonaws.com/AWSServiceRoleForNetworkFirewall'
+ ),
+ ],
+ }),
+ ],
+ });
- const deployStageFirewallPolicyResource = deployStageFirewallPolicy.node.findChild('Resource') as iam.CfnPolicy;
+ const deployStageFirewallPolicyResource = deployStageFirewallPolicy.node.findChild('Resource') as CfnPolicy;
deployStageFirewallPolicyResource.cfnOptions.metadata = {
cfn_nag: {
rules_to_suppress: [
{
id: 'W12',
- reason: 'Resource * is required for describe APIs'
- }]
- }
+ reason: 'Resource * is required for describe APIs',
+ },
+ ],
+ },
};
//add modify transit gateway attachement permission only if the transit gateway attachment is provided.
- const deployStageModifyTransitGatewayAttachmentPolicy = new iam.Policy(this, 'deployStageModifyTransitGatewayAttachmentPolicy', {
- statements: [
- new iam.PolicyStatement({
- actions: [
- "ec2:ModifyTransitGatewayVpcAttachment"
- ],
- effect: iam.Effect.ALLOW,
- resources: [
- `arn:${cdk.Aws.PARTITION}:ec2:${cdk.Aws.REGION}:${cdk.Aws.ACCOUNT_ID}:transit-gateway-attachment/${vpcTGWAttachment.ref}`,
- ]
- })
- ]
- })
- const resourcePolicyModifyTGWAttachment = deployStageModifyTransitGatewayAttachmentPolicy.node.findChild('Resource') as iam.CfnPolicy;
- resourcePolicyModifyTGWAttachment.cfnOptions.condition = createTransitGatewayAttachment
-
- const deployStageFirewallLoggingPolicy = new iam.Policy(this,
- 'deployStageFirewallLoggingPolicy',
+ const deployStageModifyTransitGatewayAttachmentPolicy = new Policy(
+ this,
+ 'deployStageModifyTransitGatewayAttachmentPolicy',
{
statements: [
- new iam.PolicyStatement({
- actions: [
- "logs:CreateLogDelivery",
- "logs:GetLogDelivery",
- "logs:UpdateLogDelivery",
- "logs:DeleteLogDelivery",
- "logs:ListLogDeliveries"
+ new PolicyStatement({
+ actions: ['ec2:ModifyTransitGatewayVpcAttachment'],
+ effect: Effect.ALLOW,
+ resources: [
+ `arn:${Aws.PARTITION}:ec2:${Aws.REGION}:${Aws.ACCOUNT_ID}:transit-gateway-attachment/${vpcTGWAttachment.ref}`,
],
- resources: ["*"] // Per IAM service must use All Resources
- })
- ]
- })
+ }),
+ ],
+ }
+ );
+ const resourcePolicyModifyTGWAttachment = deployStageModifyTransitGatewayAttachmentPolicy.node.findChild(
+ 'Resource'
+ ) as CfnPolicy;
+ resourcePolicyModifyTGWAttachment.cfnOptions.condition = createTransitGatewayAttachment;
- const deployStageFirewallLoggingResource = deployStageFirewallLoggingPolicy.node.findChild('Resource') as iam.CfnPolicy;
+ const deployStageFirewallLoggingPolicy = new Policy(this, 'deployStageFirewallLoggingPolicy', {
+ statements: [
+ new PolicyStatement({
+ actions: [
+ 'logs:CreateLogDelivery',
+ 'logs:GetLogDelivery',
+ 'logs:UpdateLogDelivery',
+ 'logs:DeleteLogDelivery',
+ 'logs:ListLogDeliveries',
+ ],
+ resources: ['*'], // Per IAM service must use All Resources
+ }),
+ ],
+ });
+
+ const deployStageFirewallLoggingResource = deployStageFirewallLoggingPolicy.node.findChild('Resource') as CfnPolicy;
deployStageFirewallLoggingResource.cfnOptions.metadata = {
cfn_nag: {
rules_to_suppress: [
{
id: 'W12',
- reason: 'Resource * is required for these actions.'
- }]
- }
+ reason: 'Resource * is required for these actions.',
+ },
+ ],
+ },
};
// skip creating the 'deployStageFirewallLoggingPolicy' IAM policy if
// logging destination type is set to configure manually
- deployStageFirewallLoggingResource.cfnOptions.condition = isNotLoggingConfigureManually
+ deployStageFirewallLoggingResource.cfnOptions.condition = isNotLoggingConfigureManually;
- const deployStageFirewallLoggingS3Policy = new iam.Policy(this,
- 'deployStageFirewallLoggingS3Policy',
- {
- statements: [
- new iam.PolicyStatement({
- actions: [
- "s3:PutBucketPolicy",
- "s3:GetBucketPolicy"
- ],
- resources: [logsBucket.bucketArn]
- })
- ]
- })
+ const deployStageFirewallLoggingS3Policy = new Policy(this, 'deployStageFirewallLoggingS3Policy', {
+ statements: [
+ new PolicyStatement({
+ actions: ['s3:PutBucketPolicy', 's3:GetBucketPolicy'],
+ resources: [logsBucket.bucketArn],
+ }),
+ ],
+ });
- const deployStageFirewallLoggingS3PolicyResource = deployStageFirewallLoggingS3Policy.node.findChild('Resource') as iam.CfnPolicy;
+ const deployStageFirewallLoggingS3PolicyResource = deployStageFirewallLoggingS3Policy.node.findChild(
+ 'Resource'
+ ) as CfnPolicy;
// create the 'deployStageFirewallLoggingS3Policy' IAM policy only if
// logging destination type is set to S3
- deployStageFirewallLoggingS3PolicyResource.cfnOptions.condition = isLoggingInS3
+ deployStageFirewallLoggingS3PolicyResource.cfnOptions.condition = isLoggingInS3;
- const deployStageFirewallLoggingCWPolicy = new iam.Policy(this,
- 'deployStageFirewallLoggingCWPolicy',
- {
- statements: [
- new iam.PolicyStatement({
- actions: [
- "logs:PutResourcePolicy",
- "logs:DescribeResourcePolicies"
- ],
- resources: ["*"] // Per IAM service must use All Resources
- }),
- new iam.PolicyStatement({
- actions: [
- "logs:DescribeLogGroups"
- ],
- resources: [
- cdk.Fn.sub("arn:${AWS::Partition}:logs:*:${AWS::AccountId}:log-group:*")
- ]
- })
- ]
- })
+ const deployStageFirewallLoggingCWPolicy = new Policy(this, 'deployStageFirewallLoggingCWPolicy', {
+ statements: [
+ new PolicyStatement({
+ actions: ['logs:PutResourcePolicy', 'logs:DescribeResourcePolicies'],
+ resources: ['*'], // Per IAM service must use All Resources
+ }),
+ new PolicyStatement({
+ actions: ['logs:DescribeLogGroups'],
+ resources: [Fn.sub('arn:${AWS::Partition}:logs:*:${AWS::AccountId}:log-group:*')],
+ }),
+ ],
+ });
- const deployStageFirewallLoggingCWPolicyResource = deployStageFirewallLoggingCWPolicy.node.findChild('Resource') as iam.CfnPolicy;
+ const deployStageFirewallLoggingCWPolicyResource = deployStageFirewallLoggingCWPolicy.node.findChild(
+ 'Resource'
+ ) as CfnPolicy;
deployStageFirewallLoggingCWPolicyResource.cfnOptions.metadata = {
cfn_nag: {
rules_to_suppress: [
{
id: 'W12',
- reason: 'Resource * is required for describe APIs'
- }]
- }
+ reason: 'Resource * is required for describe APIs',
+ },
+ ],
+ },
};
// create the 'deployStageFirewallLoggingCWPolicy' IAM policy if
// logging destination type is set to CloudWatch Logs
- deployStageFirewallLoggingCWPolicyResource.cfnOptions.condition = isLoggingInCloudWatch
+ deployStageFirewallLoggingCWPolicyResource.cfnOptions.condition = isLoggingInCloudWatch;
// Code deploy build action project, role will be created by the construct.
@@ -931,9 +905,9 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
phases: {
install: {
'runtime-versions': {
- nodejs: '12'
+ nodejs: '16',
},
- commands: [`export current=$(pwd)`, `export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY`]
+ commands: [`export current=$(pwd)`, `export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY`],
},
pre_build: {
commands: [
@@ -943,281 +917,230 @@ export class NetworkFirewallAutomationStack extends cdk.Stack {
`aws s3 cp s3://${codeBuildStagesSourceCodeBucket.bucketName}/$sourceCodeKey/network-firewall-automation.zip $current`,
`unzip -o $current/network-firewall-automation.zip -d $current`,
`pwd; ls -ltr`,
- ]
+ ],
},
build: {
- commands: [
- `echo "Initiating Network Firewall Automation"`,
- `node index.js`
- ]
+ commands: [`echo "Initiating Network Firewall Automation"`, `node index.js`],
},
post_build: {
- commands: []
- }
+ commands: [],
+ },
},
artifacts: {
- files: "**/*"
- }
+ files: '**/*',
+ },
}),
environment: {
- buildImage: LinuxBuildImage.STANDARD_4_0
+ buildImage: LinuxBuildImage.STANDARD_6_0,
},
- environmentVariables: codeBuildEnvVariables
- })
+ environmentVariables: codeBuildEnvVariables,
+ });
// attach inline IAM policies with the default CodeBuild role.
- deployProject.role?.attachInlinePolicy(deployStageFirewallPolicy)
- deployProject.role?.attachInlinePolicy(deployStageFirewallLoggingPolicy)
- deployProject.role?.attachInlinePolicy(deployStageFirewallLoggingS3Policy)
- deployProject.role?.attachInlinePolicy(deployStageFirewallLoggingCWPolicy)
- deployProject.role?.attachInlinePolicy(deployStageModifyTransitGatewayAttachmentPolicy)
+ deployProject.role?.attachInlinePolicy(deployStageFirewallPolicy);
+ deployProject.role?.attachInlinePolicy(deployStageFirewallLoggingPolicy);
+ deployProject.role?.attachInlinePolicy(deployStageFirewallLoggingS3Policy);
+ deployProject.role?.attachInlinePolicy(deployStageFirewallLoggingCWPolicy);
+ deployProject.role?.attachInlinePolicy(deployStageModifyTransitGatewayAttachmentPolicy);
-
- const codePipeline = new codepipeline.Pipeline(this, `NetworkFirewallCodePipeline`, {
+ const codePipeline = new Pipeline(this, `NetworkFirewallCodePipeline`, {
stages: [
{
stageName: 'Source',
actions: [
- new codepipeline_action.CodeCommitSourceAction({
+ new CodeCommitSourceAction({
actionName: 'Source',
repository: codeCommitRepo,
branch: 'main',
output: sourceOutputArtifact,
- })
- ]
+ }),
+ ],
},
{
stageName: 'Validation',
actions: [
- new codepipeline_action.CodeBuildAction({
+ new CodeBuildAction({
actionName: 'CodeBuild',
input: sourceOutputArtifact,
project: buildProject,
- outputs: [buildOutputArtifact]
- })
- ]
+ outputs: [buildOutputArtifact],
+ }),
+ ],
},
{
stageName: 'Deployment',
actions: [
- new codepipeline_action.CodeBuildAction({
+ new CodeBuildAction({
actionName: 'CodeDeploy',
input: buildOutputArtifact,
project: deployProject,
- })
- ]
- }]
- })
+ }),
+ ],
+ },
+ ],
+ });
//Adding bucket encryption
- const kmsKeyCfn_ref = codePipeline.artifactBucket.encryptionKey?.node.defaultChild as kms.CfnKey
- kmsKeyCfn_ref.addPropertyOverride('EnableKeyRotation', true)
+ const kmsKeyCfn_ref = codePipeline.artifactBucket.encryptionKey?.node.defaultChild as CfnKey;
+ kmsKeyCfn_ref.addPropertyOverride('EnableKeyRotation', true);
- const stack = cdk.Stack.of(this);
+ const stack = Stack.of(this);
- const codePipelineArtifactBucketKmsKeyAlias = stack.node.findChild("NetworkFirewallCodePipeline").node.findChild("ArtifactsBucketEncryptionKeyAlias").node.defaultChild as kms.CfnAlias
- codePipelineArtifactBucketKmsKeyAlias.addPropertyOverride("AliasName", {
- "Fn::Join": [
- "",
+ const codePipelineArtifactBucketKmsKeyAlias = stack.node
+ .findChild('NetworkFirewallCodePipeline')
+ .node.findChild('ArtifactsBucketEncryptionKeyAlias').node.defaultChild as CfnAlias;
+ codePipelineArtifactBucketKmsKeyAlias.addPropertyOverride('AliasName', {
+ 'Fn::Join': [
+ '',
[
- "alias/",
+ 'alias/',
{
- "Ref": "AWS::StackName"
+ Ref: 'AWS::StackName',
},
- "-artifactBucket-EncryptionKeyAlias"
- ]
- ]
- })
+ '-artifactBucket-EncryptionKeyAlias',
+ ],
+ ],
+ });
- const codeBuildStagesSourceCodeBucket_cfn_ref = codeBuildStagesSourceCodeBucket.node.defaultChild as s3.CfnBucket
+ const codeBuildStagesSourceCodeBucket_cfn_ref = codeBuildStagesSourceCodeBucket.node.defaultChild as CfnBucket;
codeBuildStagesSourceCodeBucket_cfn_ref.bucketEncryption = {
serverSideEncryptionConfiguration: [
{
serverSideEncryptionByDefault: {
kmsMasterKeyId: codePipeline.artifactBucket.encryptionKey?.keyArn,
- sseAlgorithm: "aws:kms"
- }
- }
- ]
- }
+ sseAlgorithm: 'aws:kms',
+ },
+ },
+ ],
+ };
codeBuildStagesSourceCodeBucket_cfn_ref.cfnOptions.metadata = {
cfn_nag: {
- rules_to_suppress: [{
- id: 'W35',
- reason: 'Source Code bucket bucket does not require logging configuration'
- }, {
- id: 'W51',
- reason: 'Source Code bucket is private and does not require a bucket policy'
- }]
- }
- };
-
- //S3 Bucket policy for the pipeline artifacts bucket
- const bucketPolicy = new s3.BucketPolicy(this, 'CodePipelineArtifactS3BucketPolicy', {
- bucket: codePipeline.artifactBucket,
- removalPolicy: RemovalPolicy.RETAIN
- })
-
- bucketPolicy.document.addStatements(
- new iam.PolicyStatement({
- effect: iam.Effect.ALLOW,
- actions: [
- 's3:DeleteBucket'
- ],
- principals: [new iam.ServicePrincipal('cloudformation.amazonaws.com')],
- resources: [
- codePipeline.artifactBucket.bucketArn
- ]
- }),
- new iam.PolicyStatement({
- effect: iam.Effect.DENY,
- actions: [
- 's3:GetObject'
- ],
- principals: [
- new iam.AnyPrincipal()
- ],
- resources: [
- `${codePipeline.artifactBucket.bucketArn}/*`,
- `${codePipeline.artifactBucket.bucketArn}`
+ rules_to_suppress: [
+ {
+ id: 'W35',
+ reason: 'Source Code bucket bucket does not require logging configuration',
+ },
+ {
+ id: 'W51',
+ reason: 'Source Code bucket is private and does not require a bucket policy',
+ },
],
- conditions: {
- Bool: {
- "aws:SecureTransport": false
- }
- }
- }));
+ },
+ };
- const bucketPolicyForlogsBucket = new s3.BucketPolicy(this, 'CloudWatchLogsForNetworkFirewallBucketPolicy', {
+ const bucketPolicyForlogsBucket = new BucketPolicy(this, 'CloudWatchLogsForNetworkFirewallBucketPolicy', {
bucket: logsBucket,
- removalPolicy: RemovalPolicy.RETAIN
- })
+ removalPolicy: RemovalPolicy.RETAIN,
+ });
bucketPolicyForlogsBucket.document.addStatements(
- new iam.PolicyStatement({
- effect: iam.Effect.DENY,
- actions: [
- 's3:GetObject'
- ],
- principals: [
- new iam.AnyPrincipal()
- ],
- resources: [
- `${logsBucket.bucketArn}/*`,
- `${logsBucket.bucketArn}`
- ],
+ new PolicyStatement({
+ effect: Effect.DENY,
+ actions: ['s3:GetObject'],
+ principals: [new AnyPrincipal()],
+ resources: [`${logsBucket.bucketArn}/*`, `${logsBucket.bucketArn}`],
conditions: {
Bool: {
- "aws:SecureTransport": false
- }
- }
- }));
+ 'aws:SecureTransport': false,
+ },
+ },
+ })
+ );
- const bucketPolicyForlogsBucket_cfn_ref = bucketPolicyForlogsBucket.node.defaultChild as s3.CfnBucketPolicy
- bucketPolicyForlogsBucket_cfn_ref.cfnOptions.condition = isLoggingInS3
+ const bucketPolicyForlogsBucket_cfn_ref = bucketPolicyForlogsBucket.node.defaultChild as CfnBucketPolicy;
+ bucketPolicyForlogsBucket_cfn_ref.cfnOptions.condition = isLoggingInS3;
- const bucketPolicyForSourceCodeBucket = new s3.BucketPolicy(this, 'CodeBuildStageSourceCodeBucketPolicy', {
+ const bucketPolicyForSourceCodeBucket = new BucketPolicy(this, 'CodeBuildStageSourceCodeBucketPolicy', {
bucket: codeBuildStagesSourceCodeBucket,
- removalPolicy: RemovalPolicy.RETAIN
+ removalPolicy: RemovalPolicy.RETAIN,
});
bucketPolicyForSourceCodeBucket.document.addStatements(
- new iam.PolicyStatement({
- effect: iam.Effect.DENY,
- actions: [
- 's3:GetObject'
- ],
- principals: [
- new iam.AnyPrincipal()
- ],
- resources: [
- `${codeBuildStagesSourceCodeBucket.bucketArn}`,
- `${codeBuildStagesSourceCodeBucket.bucketArn}/*`
- ],
+ new PolicyStatement({
+ effect: Effect.DENY,
+ actions: ['s3:GetObject'],
+ principals: [new AnyPrincipal()],
+ resources: [`${codeBuildStagesSourceCodeBucket.bucketArn}`, `${codeBuildStagesSourceCodeBucket.bucketArn}/*`],
conditions: {
Bool: {
- "aws:SecureTransport": false
- }
- }
- }));
+ 'aws:SecureTransport': false,
+ },
+ },
+ })
+ );
//disable W35 for the artifact bucket as it only store the artifact files.
const w35Rule = {
- rules_to_suppress: [{
- id: 'W35',
- reason: "This S3 bucket is used as the destination for 'NetworkFirewallCodePipelineArtifactsBucket'"
- }]
- }
- const s3ArtifactBucket_cfn_ref = codePipeline.artifactBucket.node.defaultChild as s3.CfnBucket
+ rules_to_suppress: [
+ {
+ id: 'W35',
+ reason: "This S3 bucket is used as the destination for 'NetworkFirewallCodePipelineArtifactsBucket'",
+ },
+ ],
+ };
+ const s3ArtifactBucket_cfn_ref = codePipeline.artifactBucket.node.defaultChild as CfnBucket;
s3ArtifactBucket_cfn_ref.cfnOptions.metadata = {
- cfn_nag: w35Rule
- }
+ cfn_nag: w35Rule,
+ };
/**
* Outputs - describes the values that are returned whenever you view
* your stack's properties.
*/
- new cdk.CfnOutput(this, 'Inspection VPC ID', {
+ new CfnOutput(this, 'Inspection VPC ID', {
value: vpc.ref,
description: 'Inspection VPC ID to create Network Firewall.',
- })
+ });
- new cdk.CfnOutput(this, 'Firewall Subnet 1 ID', {
+ new CfnOutput(this, 'Firewall Subnet 1 ID', {
value: NetworkFirewallSubnet1.ref,
description: 'Subnet 1 associated with Network Firewall.',
- })
+ });
- new cdk.CfnOutput(this, 'Firewall Subnet 2 ID', {
+ new CfnOutput(this, 'Firewall Subnet 2 ID', {
value: NetworkFirewallSubnet2.ref,
description: 'Subnet 2 associated with Network Firewall.',
- })
+ });
- new cdk.CfnOutput(this, 'Transit Gateway Subnet 1 ID', {
+ new CfnOutput(this, 'Transit Gateway Subnet 1 ID', {
value: vpcTGWSubnet1.ref,
description: 'Subnet 1 associated with Transit Gateway.',
- })
+ });
- new cdk.CfnOutput(this, 'Transit Gateway Subnet 2 ID', {
+ new CfnOutput(this, 'Transit Gateway Subnet 2 ID', {
value: vpcTGWSubnet2.ref,
description: 'Subnet 1 associated with Transit Gateway.',
- })
+ });
- new cdk.CfnOutput(this, 'Network Firewall Availability Zone 1', {
- value: cdk.Fn.getAtt(
- 'NetworkFirewallSubnet1',
- 'AvailabilityZone').toString(),
+ new CfnOutput(this, 'Network Firewall Availability Zone 1', {
+ value: Fn.getAtt('NetworkFirewallSubnet1', 'AvailabilityZone').toString(),
description: 'Availability Zone configured for Network Firewall subnet 1',
- })
+ });
- new cdk.CfnOutput(this, 'Network Firewall Availability Zone 2', {
- value: cdk.Fn.getAtt(
- 'NetworkFirewallSubnet2',
- 'AvailabilityZone').toString(),
+ new CfnOutput(this, 'Network Firewall Availability Zone 2', {
+ value: Fn.getAtt('NetworkFirewallSubnet2', 'AvailabilityZone').toString(),
description: 'Availability Zone configured for Network Firewall subnet 2',
- })
+ });
- new cdk.CfnOutput(this, 'Artifact Bucket for CodePipeline', {
+ new CfnOutput(this, 'Artifact Bucket for CodePipeline', {
value: codePipeline.artifactBucket.bucketName,
description: 'Artifact bucket name configured for the CodePipeline.',
- })
+ });
- new cdk.CfnOutput(this, 'Code Build source code bucket', {
+ new CfnOutput(this, 'Code Build source code bucket', {
value: codeBuildStagesSourceCodeBucket.bucketName,
description: 'Code Build source code bucket',
- })
-
- new cdk.CfnOutput(this, 'S3 Bucket for Firewall Logs', {
- value: cdk.Fn.conditionIf('LoggingInS3', logsBucket.bucketName, 'NotConfigured').toString(),
- description: 'S3 Bucket used as the log destination for Firewall' +
- ' Logs.',
- })
+ });
- new cdk.CfnOutput(this, 'CloudWatch Log Group for Firewall Logs', {
- value: cdk.Fn.conditionIf('LoggingInCloudWatch', cloudWatchLogGroup.ref, 'NotConfigured').toString(),
- description: 'CloudWatch Log Group used as the log destination for Firewall' +
- ' Logs.',
- })
+ new CfnOutput(this, 'S3 Bucket for Firewall Logs', {
+ value: Fn.conditionIf('LoggingInS3', logsBucket.bucketName, 'NotConfigured').toString(),
+ description: 'S3 Bucket used as the log destination for Firewall Logs.',
+ });
+ new CfnOutput(this, 'CloudWatch Log Group for Firewall Logs', {
+ value: Fn.conditionIf('LoggingInCloudWatch', cloudWatchLogGroup.ref, 'NotConfigured').toString(),
+ description: 'CloudWatch Log Group used as the log destination for Firewall Logs.',
+ });
}
}
diff --git a/source/networkFirewallAutomation/__tests__/ec2-manager.spec.ts b/source/networkFirewallAutomation/__tests__/ec2-manager.spec.ts
index aeeca0b..d5d024e 100644
--- a/source/networkFirewallAutomation/__tests__/ec2-manager.spec.ts
+++ b/source/networkFirewallAutomation/__tests__/ec2-manager.spec.ts
@@ -1,92 +1,121 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
import { Ec2Manager } from '../lib/ec2-manager';
const ec2EnvProps = [
{
- "routeTableId":"rtb-0e99886b16ecb5710",
- "availabilityZone": 'us-east-1a'
+ routeTableId: 'rtb-0e99886b16ecb5710',
+ availabilityZone: 'us-east-1a',
},
- {
- "routeTableId":"rtb-0e99886b16ecb5710",
- "availabilityZone": 'us-east-1b'
- }]
+ {
+ routeTableId: 'rtb-0e99886b16ecb5710',
+ availabilityZone: 'us-east-1b',
+ },
+];
-jest.mock("aws-sdk", () => {
+jest.mock(
+ 'aws-sdk',
+ () => {
return {
- __esModule: true,
- EC2: jest.fn().mockReturnValue({
-
- })
- }
-}, { virtual: true });
+ __esModule: true,
+ EC2: jest.fn().mockReturnValue({}),
+ };
+ },
+ { virtual: true }
+);
-jest.mock("../lib/service/ec2-service", () => {
+jest.mock(
+ '../lib/service/ec2-service',
+ () => {
return {
- __esModule: true,
- Ec2Service: jest.fn().mockReturnValue({
- describeRouteTables: jest.fn().mockImplementation(() => {
- return [{"Associations":[{"Main":false,"RouteTableAssociationId":"rtbassoc-041509f1a595fa5dd","RouteTableId":"rtb-0e99886b16ecb5710","SubnetId":"subnet-028bf1f940038d771","AssociationState":{"State":"associated"}},{"Main":false,"RouteTableAssociationId":"rtbassoc-0c83e3ec6163f1999","RouteTableId":"rtb-0e99886b16ecb5710","SubnetId":"subnet-0884864b53eaf5171","AssociationState":{"State":"associated"}}],"PropagatingVgws":[],"RouteTableId":"rtb-0e99886b16ecb5710","Routes":[{"DestinationCidrBlock":"192.168.1.0/26","GatewayId":"local","Origin":"CreateRouteTable","State":"active"}],"Tags":[{"Key":"Name","Value":"FirewallSubnetRouteTable"}],"VpcId":"vpc-0ea9f7f530319814a","OwnerId":"1234"}]
- }),
- createRoute: jest.fn().mockImplementation(() => {
- return {
- 'Return': true
- }
- })
- })
- }
-}, { virtual: true });
-
-test('test the method routeTableOperations - 2 VPCE', async () => {
- const syncStates = {
- "us-east-1a": {
- "Attachment": {
- "SubnetId": "subnet-1",
- "EndpointId": "vpce-1",
- "Status": "READY"
- },
- "Config": {
- "arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1": {'SyncStatus': "IN_SYNC"},
- "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1": {'SyncStatus': "IN_SYNC"},
- "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1": {'SyncStatus': "IN_SYNC"},
- "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2": {'SyncStatus': "IN_SYNC"}
- }
- },
- "us-east-1b": {
- "Attachment": {
- "SubnetId": "subnet-2",
- "EndpointId": "vpce-2",
- "Status": "READY"
+ __esModule: true,
+ Ec2Service: jest.fn().mockReturnValue({
+ describeRouteTables: jest.fn().mockImplementation(() => {
+ return [
+ {
+ Associations: [
+ {
+ Main: false,
+ RouteTableAssociationId: 'rtbassoc-041509f1a595fa5dd',
+ RouteTableId: 'rtb-0e99886b16ecb5710',
+ SubnetId: 'subnet-028bf1f940038d771',
+ AssociationState: { State: 'associated' },
+ },
+ {
+ Main: false,
+ RouteTableAssociationId: 'rtbassoc-0c83e3ec6163f1999',
+ RouteTableId: 'rtb-0e99886b16ecb5710',
+ SubnetId: 'subnet-0884864b53eaf5171',
+ AssociationState: { State: 'associated' },
+ },
+ ],
+ PropagatingVgws: [],
+ RouteTableId: 'rtb-0e99886b16ecb5710',
+ Routes: [
+ {
+ DestinationCidrBlock: '192.168.1.0/26',
+ GatewayId: 'local',
+ Origin: 'CreateRouteTable',
+ State: 'active',
+ },
+ ],
+ Tags: [{ Key: 'Name', Value: 'FirewallSubnetRouteTable' }],
+ VpcId: 'vpc-0ea9f7f530319814a',
+ OwnerId: '1234',
},
- "Config": {
- "arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1": {'SyncStatus': "IN_SYNC"},
- "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1": {'SyncStatus': "IN_SYNC"},
- "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1": {'SyncStatus': "IN_SYNC"},
- "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2": {'SyncStatus': "IN_SYNC"}
- }
- }
-
- }
+ ];
+ }),
+ createRoute: jest.fn().mockImplementation(() => {
+ return {
+ Return: true,
+ };
+ }),
+ }),
+ };
+ },
+ { virtual: true }
+);
- const ec2Mgr = new Ec2Manager(ec2EnvProps, syncStates)
- const response = await ec2Mgr.routeTableOperations()
- console.log(response)
- expect(response[0].VpcEndpointId).toStrictEqual("vpce-1")
- expect(response[0].RouteTableId).toStrictEqual("rtb-0e99886b16ecb5710")
- expect(response[0].DefaultRouteCreated).toStrictEqual(true)
- expect(response[1].VpcEndpointId).toStrictEqual("vpce-2")
- expect(response[0].RouteTableId).toStrictEqual("rtb-0e99886b16ecb5710")
- expect(response[1].DefaultRouteCreated).toStrictEqual(true)
+test('test the method routeTableOperations - 2 VPCE', async () => {
+ const syncStates = {
+ 'us-east-1a': {
+ Attachment: {
+ SubnetId: 'subnet-1',
+ EndpointId: 'vpce-1',
+ Status: 'READY',
+ },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': { SyncStatus: 'IN_SYNC' },
+ },
+ },
+ 'us-east-1b': {
+ Attachment: {
+ SubnetId: 'subnet-2',
+ EndpointId: 'vpce-2',
+ Status: 'READY',
+ },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': { SyncStatus: 'IN_SYNC' },
+ },
+ },
+ };
-})
+ const ec2Mgr = new Ec2Manager(ec2EnvProps, syncStates);
+ const response = await ec2Mgr.routeTableOperations();
+ console.log(response);
+ expect(response[0].VpcEndpointId).toStrictEqual('vpce-1');
+ expect(response[0].RouteTableId).toStrictEqual('rtb-0e99886b16ecb5710');
+ expect(response[0].DefaultRouteCreated).toStrictEqual(true);
+ expect(response[1].VpcEndpointId).toStrictEqual('vpce-2');
+ expect(response[0].RouteTableId).toStrictEqual('rtb-0e99886b16ecb5710');
+ expect(response[1].DefaultRouteCreated).toStrictEqual(true);
+});
diff --git a/source/networkFirewallAutomation/__tests__/ec2-service.spec.ts b/source/networkFirewallAutomation/__tests__/ec2-service.spec.ts
new file mode 100644
index 0000000..d50ffb2
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/ec2-service.spec.ts
@@ -0,0 +1,125 @@
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { Ec2Service } from '../lib/service/ec2-service';
+
+const routeTable = {
+ Associations: [
+ {
+ Main: false,
+ RouteTableAssociationId: 'rtbassoc-041509f1a595fa5dd',
+ RouteTableId: 'rtb-0e99886b16ecb5710',
+ SubnetId: 'subnet-028bf1f940038d771',
+ AssociationState: { State: 'associated' },
+ },
+ {
+ Main: false,
+ RouteTableAssociationId: 'rtbassoc-0c83e3ec6163f1999',
+ RouteTableId: 'rtb-0e99886b16ecb5710',
+ SubnetId: 'subnet-0884864b53eaf5171',
+ AssociationState: { State: 'associated' },
+ },
+ ],
+ PropagatingVgws: [],
+ RouteTableId: 'rtb-0e99886b16ecb5710',
+ Routes: [
+ {
+ DestinationCidrBlock: '192.168.1.0/26',
+ GatewayId: 'local',
+ Origin: 'CreateRouteTable',
+ State: 'active',
+ },
+ ],
+ Tags: [{ Key: 'Name', Value: 'FirewallSubnetRouteTable' }],
+ VpcId: 'vpc-0ea9f7f530319814a',
+ OwnerId: '1234',
+};
+
+const routeTables = [routeTable];
+
+const mockDescribeRouteTablesPromise = jest.fn().mockImplementation(() => {
+ return Promise.resolve({
+ RouteTables: routeTables,
+ });
+});
+
+jest.mock('aws-sdk', () => {
+ return {
+ __esModule: true,
+ EC2: jest.fn().mockReturnValue({
+ describeRouteTables: jest.fn().mockImplementation(() => {
+ return {
+ promise: mockDescribeRouteTablesPromise,
+ };
+ }),
+ createRoute: jest.fn().mockImplementation(() => {
+ return {
+ promise: jest.fn().mockImplementation(() => {
+ return Promise.resolve({});
+ }),
+ };
+ }),
+ deleteRoute: jest.fn().mockImplementation(() => {
+ return {
+ promise: jest.fn().mockImplementation(() => {
+ return Promise.resolve({});
+ }),
+ };
+ }),
+ modifyTransitGatewayVpcAttachment: jest.fn().mockImplementation(() => {
+ return {
+ promise: jest.fn().mockImplementation(() => {
+ return Promise.resolve({});
+ }),
+ };
+ }),
+ }),
+ };
+});
+
+describe('EC2 Service', () => {
+ const service = new Ec2Service();
+
+ it('should describe the route tables', async () => {
+ const routeTableId = 'route-table-id';
+ const response = await service.describeRouteTables(routeTableId);
+ expect(response).toBe(routeTables);
+ });
+
+ it('should describe route tables with paging', async () => {
+ mockDescribeRouteTablesPromise.mockResolvedValueOnce({
+ NextToken: true,
+ RouteTables: routeTables,
+ });
+
+ const routeTableId = 'route-table-id';
+ const response = await service.describeRouteTables(routeTableId);
+ expect(response).toStrictEqual([routeTable, routeTable]);
+ });
+
+ it('should create a route', async () => {
+ const testCase = async () => {
+ await service.createRoute({ RouteTableId: 'id' });
+ };
+
+ await expect(testCase).not.toThrowError();
+ });
+
+ it('should delete a route', async () => {
+ const testCase = async () => {
+ await service.deleteRoute({ RouteTableId: 'id' });
+ };
+
+ await expect(testCase).not.toThrowError();
+ });
+
+ it('should modify the transit gateway attachment', async () => {
+ const testCase = async () => {
+ await service.modifyTransitGatewayAttachment({ TransitGatewayAttachmentId: 'id' });
+ };
+
+ await expect(testCase).not.toThrowError();
+ });
+});
diff --git a/source/networkFirewallAutomation/__tests__/firewall-config-validation.spec.ts b/source/networkFirewallAutomation/__tests__/firewall-config-validation.spec.ts
index 13bad4b..b1fafad 100644
--- a/source/networkFirewallAutomation/__tests__/firewall-config-validation.spec.ts
+++ b/source/networkFirewallAutomation/__tests__/firewall-config-validation.spec.ts
@@ -1,49 +1,134 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { FirewallConfigValidation } from "../lib/common/firewall-config-validation"
-
-jest.mock("aws-sdk", () => {
- return {
- __esModule: true,
- NetworkFirewall: jest.fn().mockReturnValue({
- createRuleGroup: jest.fn().mockImplementation(() => {
- //console.log(`Inside rule group mock ${JSON.stringify(data)}` )
- }),
- createFirewallPolicy: jest.fn().mockImplementation(() => {
- //console.log(`Inside firewall policy mock ${JSON.stringify(data)}` )
- }),
- })
- }
-})
-
-test('test firewall config validation.', async () => {
+import { FirewallConfigValidation } from '../lib/common/firewall-config-validation';
+
+jest.mock('aws-sdk', () => {
+ return {
+ __esModule: true,
+ NetworkFirewall: jest.fn().mockReturnValue({
+ createRuleGroup: jest.fn().mockImplementation(() => {
+ //console.log(`Inside rule group mock ${JSON.stringify(data)}` )
+ }),
+ createFirewallPolicy: jest.fn().mockImplementation(() => {
+ //console.log(`Inside firewall policy mock ${JSON.stringify(data)}` )
+ }),
+ }),
+ };
+});
+
+describe('Firewall Config Validation', () => {
+ it('should not throw an error if all firewalls are valid', async () => {
+ const firewallConfigValidation = new FirewallConfigValidation();
+
+ const testCase = async () => {
+ await firewallConfigValidation.validate('/__tests__/firewall-test-configuration/firewalls-valid/');
+ };
+
+ await expect(testCase).not.toThrowError();
+
+ expect(firewallConfigValidation.getInvalidFiles().length).toBe(0);
+ });
+
+ it('should throw an exception if the firewall file is missing.', async () => {
const firewallConfigValidation = new FirewallConfigValidation();
- try {
- await firewallConfigValidation.execute("/__tests__/firewall-test-configuration/firewalls/")
- } catch (error) {
- expect(firewallConfigValidation.getInvalidFiles()).toStrictEqual([
- {
- "path": "__tests__/firewall-test-configuration/ruleGroups/stateless-fwd-to-stateful.invalid.json",
- "referencedInFile": "__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy.json",
- "error": "The file in the attribute path is not available in the configuration."
- },
- {
- "path": "__tests__/firewall-test-configuration/firewallPolicies/firewall-notavailable.json",
- "referencedInFile": "__tests__/firewall-test-configuration/firewallPolicies/firewall-notavailable.json",
- "error": "The file in the attribute path is not available in the configuration."
- }
- ])
- }
-
-})
\ No newline at end of file
+
+ const testCase = async () => {
+ await firewallConfigValidation.validate();
+ };
+
+ await expect(testCase).rejects.toThrowError('Validation failed.');
+ });
+
+ it('should fail with invalid files', async () => {
+ const firewallConfigValidation = new FirewallConfigValidation();
+
+ const testCase = async () => {
+ await firewallConfigValidation.validate('/__tests__/firewall-test-configuration/firewalls/');
+ };
+
+ await expect(testCase).rejects.toThrowError('Validation failed: Invalid Files.');
+
+ expect(firewallConfigValidation.getInvalidFiles()).toStrictEqual([
+ {
+ path: '__tests__/firewall-test-configuration/ruleGroups/stateless-fwd-to-stateful.invalid.json',
+ referencedInFile: '__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy.json',
+ error: 'The file in the attribute path is not available in the configuration.',
+ },
+ {
+ path: '__tests__/firewall-test-configuration/firewallPolicies/firewall-notavailable.json',
+ referencedInFile: '__tests__/firewall-test-configuration/firewallPolicies/firewall-notavailable.json',
+ error: 'The file in the attribute path is not available in the configuration.',
+ },
+ ]);
+ });
+
+ it('should fail with invalid stateless and stateful rule groups', async () => {
+ const firewallConfigValidation = new FirewallConfigValidation();
+
+ const testCase = async () => {
+ await firewallConfigValidation.validate('/__tests__/firewall-test-configuration/firewalls-invalid-rule-groups/');
+ };
+
+ await expect(testCase).rejects.toThrowError('Validation failed: Invalid Files.');
+
+ expect(firewallConfigValidation.getInvalidFiles()).toStrictEqual([
+ {
+ error:
+ 'Both RuleGroup and Rules have data, You must provide either the rule group setting or a Rules setting, but not both. ',
+ path: '__tests__/firewall-test-configuration/ruleGroups/invalid-rulegroup.example.json',
+ },
+ {
+ error:
+ 'Both RuleGroup and Rules have data, You must provide either the rule group setting or a Rules setting, but not both. ',
+ path: '__tests__/firewall-test-configuration/ruleGroups/invalid-rulegroup.example.json',
+ },
+ ]);
+ });
+
+ it('should fail with invalid rule group ARNs', async () => {
+ const firewallConfigValidation = new FirewallConfigValidation();
+
+ const testCase = async () => {
+ await firewallConfigValidation.validate(
+ '/__tests__/firewall-test-configuration/firewalls-invalid-rule-group-arns/'
+ );
+ };
+
+ await expect(testCase).rejects.toThrowError('Validation failed: Invalid Files.');
+
+ expect(firewallConfigValidation.getInvalidFiles()).toStrictEqual([
+ {
+ error: 'The file in the attribute path is not available in the configuration.',
+ path: '__tests__/firewall-test-configuration/ruleGroups/missing.example.json',
+ referencedInFile:
+ '__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-arns.json',
+ },
+ {
+ error: 'The file in the attribute path is not available in the configuration.',
+ path: '__tests__/firewall-test-configuration/ruleGroups/missing.json',
+ referencedInFile:
+ '__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-arns.json',
+ },
+ ]);
+ });
+
+ it('should fail with a missing rule file', async () => {
+ const firewallConfigValidation = new FirewallConfigValidation();
+
+ const testCase = async () => {
+ await firewallConfigValidation.validate('/__tests__/firewall-test-configuration/firewalls-invalid-rule-file/');
+ };
+
+ await expect(testCase).rejects.toThrowError('Validation failed: Invalid Files.');
+
+ expect(firewallConfigValidation.getInvalidFiles()).toStrictEqual([
+ {
+ error: 'Rules attribute has invalid file path. ',
+ path: '__tests__/firewall-test-configuration/ruleGroups/empty-rules.example.json',
+ },
+ ]);
+ });
+});
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-arns.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-arns.json
new file mode 100644
index 0000000..ce9776a
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-arns.json
@@ -0,0 +1,18 @@
+{
+ "FirewallPolicyName": "Firewall-Policy-1",
+ "FirewallPolicy": {
+ "StatelessDefaultActions": ["aws:drop"],
+ "StatelessFragmentDefaultActions": ["aws:drop"],
+ "StatelessRuleGroupReferences": [
+ {
+ "Priority": 30,
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/missing.json"
+ }
+ ],
+ "StatefulRuleGroupReferences": [
+ {
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/missing.example.json"
+ }
+ ]
+ }
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-path.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-path.json
new file mode 100644
index 0000000..2cca052
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-path.json
@@ -0,0 +1,12 @@
+{
+ "FirewallPolicyName": "Firewall-Policy-1",
+ "FirewallPolicy": {
+ "StatelessDefaultActions": ["aws:drop"],
+ "StatelessFragmentDefaultActions": ["aws:drop"],
+ "StatefulRuleGroupReferences": [
+ {
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/empty-rules.example.json"
+ }
+ ]
+ }
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateful-rule-group.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateful-rule-group.json
new file mode 100644
index 0000000..7f6572a
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateful-rule-group.json
@@ -0,0 +1,25 @@
+{
+ "FirewallPolicyName": "Firewall-Policy-1",
+ "FirewallPolicy": {
+ "StatelessDefaultActions": ["aws:drop"],
+ "StatelessFragmentDefaultActions": ["aws:drop"],
+ "StatelessRuleGroupReferences": [
+ {
+ "Priority": 30,
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/stateless-fwd-to-stateful.example.json"
+ },
+ {
+ "Priority": 20,
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/stateless-pass-action.example.json"
+ }
+ ],
+ "StatefulRuleGroupReferences": [
+ {
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/invalid-rulegroup.example.json"
+ },
+ {
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/suricata-rule-reference.json"
+ }
+ ]
+ }
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateless-rule-group.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateless-rule-group.json
new file mode 100644
index 0000000..24423f5
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateless-rule-group.json
@@ -0,0 +1,25 @@
+{
+ "FirewallPolicyName": "Firewall-Policy-1",
+ "FirewallPolicy": {
+ "StatelessDefaultActions": ["aws:drop"],
+ "StatelessFragmentDefaultActions": ["aws:drop"],
+ "StatelessRuleGroupReferences": [
+ {
+ "Priority": 30,
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/invalid-rulegroup.example.json"
+ },
+ {
+ "Priority": 20,
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/stateless-pass-action.example.json"
+ }
+ ],
+ "StatefulRuleGroupReferences": [
+ {
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/stateful-domainblock.example.json"
+ },
+ {
+ "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/suricata-rule-reference.json"
+ }
+ ]
+ }
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy.json
index 929842a..cc2c980 100644
--- a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy.json
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy.json
@@ -1,12 +1,8 @@
{
"FirewallPolicyName": "Firewall-Policy-2",
"FirewallPolicy": {
- "StatelessDefaultActions": [
- "aws:drop"
- ],
- "StatelessFragmentDefaultActions": [
- "aws:drop"
- ],
+ "StatelessDefaultActions": ["aws:drop"],
+ "StatelessFragmentDefaultActions": ["aws:drop"],
"StatelessRuleGroupReferences": [
{
"Priority": 30,
@@ -23,4 +19,4 @@
}
]
}
-}
\ No newline at end of file
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-file/firewall-invalid-rule-path.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-file/firewall-invalid-rule-path.json
new file mode 100644
index 0000000..f920545
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-file/firewall-invalid-rule-path.json
@@ -0,0 +1,8 @@
+{
+ "FirewallName": "VpcFirewall-1",
+ "FirewallPolicyArn": "__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-path.json",
+ "Description": "Network Firewall created by AWS Solutions",
+ "DeleteProtection": true,
+ "FirewallPolicyChangeProtection": true,
+ "SubnetChangeProtection": true
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-group-arns/firewall-invalid-rule-group-arn.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-group-arns/firewall-invalid-rule-group-arn.json
new file mode 100644
index 0000000..63e9dd3
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-group-arns/firewall-invalid-rule-group-arn.json
@@ -0,0 +1,8 @@
+{
+ "FirewallName": "VpcFirewall-1",
+ "FirewallPolicyArn": "__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-rule-arns.json",
+ "Description": "Network Firewall created by AWS Solutions",
+ "DeleteProtection": true,
+ "FirewallPolicyChangeProtection": true,
+ "SubnetChangeProtection": true
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-groups/firewall-invalid-stateful.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-groups/firewall-invalid-stateful.json
new file mode 100644
index 0000000..63f4db3
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-groups/firewall-invalid-stateful.json
@@ -0,0 +1,8 @@
+{
+ "FirewallName": "VpcFirewall-1",
+ "FirewallPolicyArn": "__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateless-rule-group.json",
+ "Description": "Network Firewall created by AWS Solutions",
+ "DeleteProtection": true,
+ "FirewallPolicyChangeProtection": true,
+ "SubnetChangeProtection": true
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-groups/firewall-invalid-stateless.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-groups/firewall-invalid-stateless.json
new file mode 100644
index 0000000..81951ab
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-invalid-rule-groups/firewall-invalid-stateless.json
@@ -0,0 +1,8 @@
+{
+ "FirewallName": "VpcFirewall-1",
+ "FirewallPolicyArn": "__tests__/firewall-test-configuration/firewallPolicies/firewall-invalid-policy-stateful-rule-group.json",
+ "Description": "Network Firewall created by AWS Solutions",
+ "DeleteProtection": true,
+ "FirewallPolicyChangeProtection": true,
+ "SubnetChangeProtection": true
+ }
\ No newline at end of file
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-valid/firewall.example.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-valid/firewall.example.json
new file mode 100644
index 0000000..8bc8538
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/firewalls-valid/firewall.example.json
@@ -0,0 +1,8 @@
+{
+ "FirewallName": "VpcFirewall-1",
+ "FirewallPolicyArn": "__tests__/firewall-test-configuration/firewallPolicies/firewall-policy.example.json",
+ "Description": "Network Firewall created by AWS Solutions",
+ "DeleteProtection": true,
+ "FirewallPolicyChangeProtection": true,
+ "SubnetChangeProtection": true
+}
\ No newline at end of file
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/ruleGroups/empty-rules.example.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/ruleGroups/empty-rules.example.json
new file mode 100644
index 0000000..783c436
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/ruleGroups/empty-rules.example.json
@@ -0,0 +1,7 @@
+{
+ "RuleGroupName": "empty-icmp-rules2",
+ "Rules": "__tests__/firewall-test-configuration/ruleGroups/empty.rules",
+ "Type": "STATEFUL",
+ "Description": "Empty rule group",
+ "Capacity": 100
+}
diff --git a/source/networkFirewallAutomation/__tests__/firewall-test-configuration/ruleGroups/invalid-rulegroup.example.json b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/ruleGroups/invalid-rulegroup.example.json
new file mode 100644
index 0000000..510d8e7
--- /dev/null
+++ b/source/networkFirewallAutomation/__tests__/firewall-test-configuration/ruleGroups/invalid-rulegroup.example.json
@@ -0,0 +1,16 @@
+{
+ "RuleGroupName": "StatefulRulesExample1",
+ "Rules": "__tests__/firewall-test-configuration/ruleGroups/drop.rules",
+ "RuleGroup": {
+ "RulesSource": {
+ "RulesSourceList": {
+ "Targets": ["test.example.com"],
+ "TargetTypes": ["HTTP_HOST", "TLS_SNI"],
+ "GeneratedRulesType": "DENYLIST"
+ }
+ }
+ },
+ "Type": "STATEFUL",
+ "Description": "Stateful Rule3",
+ "Capacity": 100
+}
diff --git a/source/networkFirewallAutomation/__tests__/network-firewall-manager.spec.ts b/source/networkFirewallAutomation/__tests__/network-firewall-manager.spec.ts
index da0c3f5..08ab992 100644
--- a/source/networkFirewallAutomation/__tests__/network-firewall-manager.spec.ts
+++ b/source/networkFirewallAutomation/__tests__/network-firewall-manager.spec.ts
@@ -1,327 +1,791 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
import { NetworkFirewallManager } from '../lib/network-firewall-manager';
import { ConfigReader } from '../lib/common/configReader/config-reader';
-
-jest.mock("aws-sdk", () => {
+jest.mock(
+ 'aws-sdk',
+ () => {
return {
- __esModule: true,
- NetworkFirewall: jest.fn().mockReturnValue({
-
- })
- }
-}, { virtual: true });
-
-jest.mock("../lib/service/network-firewall-service", () => {
+ __esModule: true,
+ NetworkFirewall: jest.fn().mockReturnValue({}),
+ };
+ },
+ { virtual: true }
+);
+
+jest.mock(
+ '../lib/service/network-firewall-service',
+ () => {
return {
- __esModule: true,
- NetworkFirewallService: jest.fn().mockReturnValue({
- describeRuleGroup: jest.fn().mockImplementation((data) => {
- const StatelessExample2Describe = { "UpdateToken": "c7007261-d236-4997-8eab-7e15445c84a2", "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2", "RuleGroupName": "StatelessExample2", "RuleGroupId": "206bd83b-3b59-4000-9ff3-3fe369f34719", "Description": "Stateless Rule with Forward to Stateful3", "Type": "STATELESS", "Capacity": 220, "RuleGroupStatus": "ACTIVE", "Tags": [] } }
- const StatelessExample1Describe = { "UpdateToken": "9b5bc310-99d4-45c9-a16e-bdb58f883a48", "RuleGroup": { "RulesSource": { "StatelessRulesAndCustomActions": { "StatelessRules": [{ "RuleDefinition": { "MatchAttributes": { "Sources": [{ "AddressDefinition": "192.0.2.0/8" }], "Destinations": [{ "AddressDefinition": "198.51.100.0/16" }], "SourcePorts": [{ "FromPort": 53, "ToPort": 53 }, { "FromPort": 1001, "ToPort": 1053 }], "DestinationPorts": [{ "FromPort": 53, "ToPort": 53 }, { "FromPort": 1001, "ToPort": 1053 }], "Protocols": [6], "TCPFlags": [{ "Flags": ["SYN"], "Masks": ["SYN", "ACK"] }] }, "Actions": ["aws:drop"] }, "Priority": 19 }], "CustomActions": [{ "ActionName": "CustomAction", "ActionDefinition": { "PublishMetricAction": { "Dimensions": [{ "Value": "test" }] } } }] } } }, "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1", "RuleGroupName": "StatelessExample1", "RuleGroupId": "7246cfe2-00c7-4ef9-8d47-2b80bf8840e5", "Description": "Stateless Rule with Custom Action2", "Type": "STATELESS", "Capacity": 199, "RuleGroupStatus": "ACTIVE", "Tags": [] } }
- const StatefulRulesExample1Describe = { "UpdateToken": "dd7696c5-e2cd-4882-a560-21e28570fc0f", "RuleGroup": { "RulesSource": { "RulesSourceList": { "Targets": ["test.example.com"], "TargetTypes": ["HTTP_HOST", "TLS_SNI"], "GeneratedRulesType": "DENYLIST" } } }, "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1", "RuleGroupName": "StatefulRulesExample1", "RuleGroupId": "2560e622-5d9e-4c5c-9680-958bcb5c231b", "Description": "Stateful Rule2", "Type": "STATEFUL", "Capacity": 100, "RuleGroupStatus": "ACTIVE", "Tags": [] } }
- const suricataRuleGroup = {
- UpdateToken: '72e4e89b-acec-4184-b033-2dab8dd2a35f',
- RuleGroupResponse: {
- RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/suricata-icmp-rules2',
- RuleGroupName: 'suricata-icmp-rules2',
- RuleGroupId: 'f593c04a-079c-423f-8558-b02a8c0edb0e',
- Type: 'STATEFUL',
- Capacity: 300,
- RuleGroupStatus: 'ACTIVE'
- }
- }
-
- if (data === 'StatelessExample2') {
- return StatelessExample2Describe
- } else if (data === 'StatelessExample1') {
- return StatelessExample1Describe
- } else if (data === 'StatefulRulesExample1') {
- return StatefulRulesExample1Describe;
- } else if(data === 'suricata-icmp-rules2') {
- return suricataRuleGroup;
- }
- return ''
- }),
- updateRuleGroup: jest.fn().mockImplementation((data) => {
- const StatelessExample2Update = { "UpdateToken": "7fa52fd2-6b3a-41c5-8356-359d17a01ac0", "RuleGroup": { "RulesSource": { "StatelessRulesAndCustomActions": { "StatelessRules": [{ "RuleDefinition": { "MatchAttributes": { "Sources": [{ "AddressDefinition": "192.0.2.0/8" }], "Destinations": [{ "AddressDefinition": "124.1.1.5/32" }, { "AddressDefinition": "198.51.100.0/16" }], "Protocols": [6, 17] }, "Actions": ["aws:forward_to_sfe"] }, "Priority": 100 }] } } }, "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2", "RuleGroupName": "StatelessExample2", "RuleGroupId": "206bd83b-3b59-4000-9ff3-3fe369f34719", "Description": "Stateless Rule with Forward to Stateful2", "Type": "STATELESS", "Capacity": 220, "RuleGroupStatus": "ACTIVE", "Tags": [] } }
- const StatelessExample1Update = { "UpdateToken": "327d0dca-e671-46bc-9ed7-83cf51773868", "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1", "RuleGroupName": "StatelessExample1", "RuleGroupId": "7246cfe2-00c7-4ef9-8d47-2b80bf8840e5", "Description": "Stateless Rule with Custom Action3", "Type": "STATELESS", "Capacity": 199, "RuleGroupStatus": "ACTIVE", "Tags": [] } }
- const StatefulRulesExample1Update = { "UpdateToken": "cc4687e1-f370-4e10-abfc-12984e1d62e7", "RuleGroupResponse": { "RuleGroupArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1", "RuleGroupName": "StatefulRulesExample1", "RuleGroupId": "2560e622-5d9e-4c5c-9680-958bcb5c231b", "Description": "Stateful Rule3", "Type": "STATEFUL", "Capacity": 100, "RuleGroupStatus": "ACTIVE", "Tags": [] } }
- if (data["RuleGroupArn"] === 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2') {
- return StatelessExample2Update
- } else if (data["RuleGroupArn"] === 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1') {
- return StatelessExample1Update
- } else if (data["RuleGroupArn"] === 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1') {
- return StatefulRulesExample1Update;
- }
- return ''
- }),
- createRuleGroup: jest.fn().mockImplementation(() => {
- //console.log(`Inside createRuleGroup mock ${JSON.stringify(data)}`);
- }),
- listRuleGroupsForPolicy: jest.fn().mockImplementation(() => {
- return ''
- }),
- describeFirewall: jest.fn().mockImplementation(() => {
- //console.log(`Inside describeFirewall mock ${JSON.stringify(data)}`);
- return { Firewall: { "FirewallName": "VpcFirewall-1", "FirewallPolicyArn": "arn:aws:network-firewall:us-east-1:1234::firewall/*", "Description": "NetworkFirewallcreatedbyAWSSolutions", "VpcId": "vpc-1", "SubnetMappings": [{ "SubnetId": "subnet-1" }, { "SubnetId": "subnet-2" },], "DeleteProtection": true, "SubnetChangeProtection": true, "FirewallPolicyChangeProtection": true, "FirewallId": "string", "Tags": [{ "Key": "string", "Value": "string" },] }, FirewallStatus: { "Status": "READY", "ConfigurationSyncStateSummary": "IN_SYNC", "SyncStates": { "us-east-1a": { "Attachment": { "SubnetId": "subnet-1", "EndpointId": "vpce-1", "Status": "READY" }, "Config": { "arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2": {'SyncStatus': "IN_SYNC"} } }, "us-east-1b": { "Attachment": { "SubnetId": "subnet-2", "EndpointId": "vpce-2", "Status": "READY" }, "Config": { "arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2": {'SyncStatus': "IN_SYNC"} } } } } }
- }),
- describeFirewallPolicy: jest.fn().mockImplementation((data) => {
- if (data && data === "Firewall-Policy-2") {
- return Promise.resolve({
- UpdateToken: 'aaa',
- FirewallPolicyResponse: {
- FirewallPolicyName: 'Firewall-Policy-2',
- FirewallPolicyArn: 'arn:aws',
- FirewallPolicyId: 100
- }
- })
- }
- return Promise.resolve()
- }),
- createFirewallPolicy: jest.fn().mockImplementation(() => {
- //console.log(`Inside describeFirewallPolicy mock ${JSON.stringify(data)}`);
- return { "FirewallPolicyResponse": { "FirewallPolicyName": "Firewall-Policy-1", "Description": "FirewallPolicy1", "FirewallPolicyArn": "arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1", "FirewallPolicyStatus": "ACTIVE", "Tags": [{ "Key": "string", "Value": "string" }] }, "FirewallPolicy": { "StatelessDefaultActions": ["aws:drop"], "StatelessFragmentDefaultActions": ["aws:drop"], "StatelessRuleGroupReferences": [{ "Priority": 30, "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2" }, { "Priority": 20, "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1" }], "StatefulRuleGroupReferences": [{ "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1" }] } }
- }),
- createFirewall: jest.fn().mockImplementation(() => {
- //console.log(`Inside describeFirewallPolicy mock ${JSON.stringify(data)}`);
- return { "FirewallResponse": { "Firewall": { "FirewallName": "VpcFirewall-1", "FirewallPolicyArn": "arn:aws:network-firewall:us-east-1:1234::firewall/*", "Description": "NetworkFirewallcreatedbyAWSSolutions", "VpcId": "vpc-1", "SubnetMappings": [{ "SubnetId": "subnet-1" }, { "SubnetId": "subnet-2" }], "DeleteProtection": true, "SubnetChangeProtection": true, "FirewallPolicyChangeProtection": true, "FirewallId": "string", "Tags": [{ "Key": "string", "Value": "string" }] }, "FirewallStatus": { "Status": "READY", "ConfigurationSyncStateSummary": "IN_SYNC", "SyncStates": { "us-east-1a": { "Attachment": { "SubnetId": "subnet-1", "EndpointId": "vpce-1", "Status": "READY" }, "Config": { "arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2": {'SyncStatus': "IN_SYNC"} } }, "us-east-1b": { "Attachment": { "SubnetId": "subnet-2", "EndpointId": "vpce-2", "Status": "READY" }, "Config": { "arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1": {'SyncStatus': "IN_SYNC"}, "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2": {'SyncStatus': "IN_SYNC"} } } } } } }
- }),
- updateLoggingConfiguration: jest.fn().mockImplementation(() => {
- return {}
- }),
- updateFirewallPolicy: jest.fn().mockImplementation(() => {
- return {
-
- }
- }),
- associateFirewallPolicy: jest.fn().mockImplementation((data) => {
- expect(data["FirewallPolicyArn"]).toBe("arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1");
- }),
- updateFirewallDeleteProtection: jest.fn().mockImplementation((data) => {
- expect(data["DeleteProtection"]).toBeTruthy();
- }),
- updateFirewallPolicyChangeProtection: jest.fn().mockImplementation((data) => {
- expect(data["FirewallPolicyChangeProtection"]).toBeTruthy()
- }),
- updateSubnetChangeProtection: jest.fn().mockImplementation((data) => {
- expect(data["SubnetChangeProtection"]).toBeTruthy();
- }),
- updateFirewallDescription: jest.fn().mockImplementation((data) => {
- expect(data["Description"]).toBe("Network Firewall created by AWS Solutions")
- })
- })
- }
-}, { virtual: true });
+ __esModule: true,
+ NetworkFirewallService: jest.fn().mockReturnValue({
+ describeRuleGroup: jest.fn().mockImplementation(data => {
+ const StatelessExample2Describe = {
+ UpdateToken: 'c7007261-d236-4997-8eab-7e15445c84a2',
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ RuleGroupName: 'StatelessExample2',
+ RuleGroupId: '206bd83b-3b59-4000-9ff3-3fe369f34719',
+ Description: 'Stateless Rule with Forward to Stateful3',
+ Type: 'STATELESS',
+ Capacity: 220,
+ RuleGroupStatus: 'ACTIVE',
+ Tags: [],
+ },
+ };
+ const StatelessExample1Describe = {
+ UpdateToken: '9b5bc310-99d4-45c9-a16e-bdb58f883a48',
+ RuleGroup: {
+ RulesSource: {
+ StatelessRulesAndCustomActions: {
+ StatelessRules: [
+ {
+ RuleDefinition: {
+ MatchAttributes: {
+ Sources: [{ AddressDefinition: '192.0.2.0/8' }],
+ Destinations: [{ AddressDefinition: '198.51.100.0/16' }],
+ SourcePorts: [
+ { FromPort: 53, ToPort: 53 },
+ { FromPort: 1001, ToPort: 1053 },
+ ],
+ DestinationPorts: [
+ { FromPort: 53, ToPort: 53 },
+ { FromPort: 1001, ToPort: 1053 },
+ ],
+ Protocols: [6],
+ TCPFlags: [{ Flags: ['SYN'], Masks: ['SYN', 'ACK'] }],
+ },
+ Actions: ['aws:drop'],
+ },
+ Priority: 19,
+ },
+ ],
+ CustomActions: [
+ {
+ ActionName: 'CustomAction',
+ ActionDefinition: { PublishMetricAction: { Dimensions: [{ Value: 'test' }] } },
+ },
+ ],
+ },
+ },
+ },
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1',
+ RuleGroupName: 'StatelessExample1',
+ RuleGroupId: '7246cfe2-00c7-4ef9-8d47-2b80bf8840e5',
+ Description: 'Stateless Rule with Custom Action2',
+ Type: 'STATELESS',
+ Capacity: 199,
+ RuleGroupStatus: 'ACTIVE',
+ Tags: [],
+ },
+ };
+ const StatefulRulesExample1Describe = {
+ UpdateToken: 'dd7696c5-e2cd-4882-a560-21e28570fc0f',
+ RuleGroup: {
+ RulesSource: {
+ RulesSourceList: {
+ Targets: ['test.example.com'],
+ TargetTypes: ['HTTP_HOST', 'TLS_SNI'],
+ GeneratedRulesType: 'DENYLIST',
+ },
+ },
+ },
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1',
+ RuleGroupName: 'StatefulRulesExample1',
+ RuleGroupId: '2560e622-5d9e-4c5c-9680-958bcb5c231b',
+ Description: 'Stateful Rule2',
+ Type: 'STATEFUL',
+ Capacity: 100,
+ RuleGroupStatus: 'ACTIVE',
+ Tags: [],
+ },
+ };
+ const suricataRuleGroup = {
+ UpdateToken: '72e4e89b-acec-4184-b033-2dab8dd2a35f',
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/suricata-icmp-rules2',
+ RuleGroupName: 'suricata-icmp-rules2',
+ RuleGroupId: 'f593c04a-079c-423f-8558-b02a8c0edb0e',
+ Type: 'STATEFUL',
+ Capacity: 300,
+ RuleGroupStatus: 'ACTIVE',
+ },
+ };
+
+ if (data === 'StatelessExample2') {
+ return StatelessExample2Describe;
+ } else if (data === 'StatelessExample1') {
+ return StatelessExample1Describe;
+ } else if (data === 'StatefulRulesExample1') {
+ return StatefulRulesExample1Describe;
+ } else if (data === 'suricata-icmp-rules2') {
+ return suricataRuleGroup;
+ }
+ return '';
+ }),
+ updateRuleGroup: jest.fn().mockImplementation(data => {
+ const StatelessExample2Update = {
+ UpdateToken: '7fa52fd2-6b3a-41c5-8356-359d17a01ac0',
+ RuleGroup: {
+ RulesSource: {
+ StatelessRulesAndCustomActions: {
+ StatelessRules: [
+ {
+ RuleDefinition: {
+ MatchAttributes: {
+ Sources: [{ AddressDefinition: '192.0.2.0/8' }],
+ Destinations: [
+ { AddressDefinition: '124.1.1.5/32' },
+ { AddressDefinition: '198.51.100.0/16' },
+ ],
+ Protocols: [6, 17],
+ },
+ Actions: ['aws:forward_to_sfe'],
+ },
+ Priority: 100,
+ },
+ ],
+ },
+ },
+ },
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ RuleGroupName: 'StatelessExample2',
+ RuleGroupId: '206bd83b-3b59-4000-9ff3-3fe369f34719',
+ Description: 'Stateless Rule with Forward to Stateful2',
+ Type: 'STATELESS',
+ Capacity: 220,
+ RuleGroupStatus: 'ACTIVE',
+ Tags: [],
+ },
+ };
+ const StatelessExample1Update = {
+ UpdateToken: '327d0dca-e671-46bc-9ed7-83cf51773868',
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1',
+ RuleGroupName: 'StatelessExample1',
+ RuleGroupId: '7246cfe2-00c7-4ef9-8d47-2b80bf8840e5',
+ Description: 'Stateless Rule with Custom Action3',
+ Type: 'STATELESS',
+ Capacity: 199,
+ RuleGroupStatus: 'ACTIVE',
+ Tags: [],
+ },
+ };
+ const StatefulRulesExample1Update = {
+ UpdateToken: 'cc4687e1-f370-4e10-abfc-12984e1d62e7',
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1',
+ RuleGroupName: 'StatefulRulesExample1',
+ RuleGroupId: '2560e622-5d9e-4c5c-9680-958bcb5c231b',
+ Description: 'Stateful Rule3',
+ Type: 'STATEFUL',
+ Capacity: 100,
+ RuleGroupStatus: 'ACTIVE',
+ Tags: [],
+ },
+ };
+ if (
+ data['RuleGroupArn'] === 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2'
+ ) {
+ return StatelessExample2Update;
+ } else if (
+ data['RuleGroupArn'] === 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1'
+ ) {
+ return StatelessExample1Update;
+ } else if (
+ data['RuleGroupArn'] === 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1'
+ ) {
+ return StatefulRulesExample1Update;
+ }
+ return '';
+ }),
+ createRuleGroup: jest.fn().mockImplementation(() => {
+ //console.log(`Inside createRuleGroup mock ${JSON.stringify(data)}`);
+ }),
+ listRuleGroupsForPolicy: jest.fn().mockImplementation(() => {
+ return '';
+ }),
+ describeFirewall: jest.fn().mockImplementation(() => {
+ //console.log(`Inside describeFirewall mock ${JSON.stringify(data)}`);
+ return {
+ Firewall: {
+ FirewallName: 'VpcFirewall-1',
+ FirewallPolicyArn: 'arn:aws:network-firewall:us-east-1:1234::firewall/*',
+ Description: 'NetworkFirewallcreatedbyAWSSolutions',
+ VpcId: 'vpc-1',
+ SubnetMappings: [{ SubnetId: 'subnet-1' }, { SubnetId: 'subnet-2' }],
+ DeleteProtection: true,
+ SubnetChangeProtection: true,
+ FirewallPolicyChangeProtection: true,
+ FirewallId: 'string',
+ Tags: [{ Key: 'string', Value: 'string' }],
+ },
+ FirewallStatus: {
+ Status: 'READY',
+ ConfigurationSyncStateSummary: 'IN_SYNC',
+ SyncStates: {
+ 'us-east-1a': {
+ Attachment: { SubnetId: 'subnet-1', EndpointId: 'vpce-1', Status: 'READY' },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': {
+ SyncStatus: 'IN_SYNC',
+ },
+ },
+ },
+ 'us-east-1b': {
+ Attachment: { SubnetId: 'subnet-2', EndpointId: 'vpce-2', Status: 'READY' },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': {
+ SyncStatus: 'IN_SYNC',
+ },
+ },
+ },
+ },
+ },
+ };
+ }),
+ describeFirewallPolicy: jest.fn().mockImplementation(data => {
+ if (data && data === 'Firewall-Policy-2') {
+ return Promise.resolve({
+ UpdateToken: 'aaa',
+ FirewallPolicyResponse: {
+ FirewallPolicyName: 'Firewall-Policy-2',
+ FirewallPolicyArn: 'arn:aws',
+ FirewallPolicyId: 100,
+ },
+ });
+ }
+ return Promise.resolve();
+ }),
+ createFirewallPolicy: jest.fn().mockImplementation(() => {
+ //console.log(`Inside describeFirewallPolicy mock ${JSON.stringify(data)}`);
+ return {
+ FirewallPolicyResponse: {
+ FirewallPolicyName: 'Firewall-Policy-1',
+ Description: 'FirewallPolicy1',
+ FirewallPolicyArn: 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1',
+ FirewallPolicyStatus: 'ACTIVE',
+ Tags: [{ Key: 'string', Value: 'string' }],
+ },
+ FirewallPolicy: {
+ StatelessDefaultActions: ['aws:drop'],
+ StatelessFragmentDefaultActions: ['aws:drop'],
+ StatelessRuleGroupReferences: [
+ {
+ Priority: 30,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ },
+ {
+ Priority: 20,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1',
+ },
+ ],
+ StatefulRuleGroupReferences: [
+ { ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1' },
+ ],
+ },
+ };
+ }),
+ createFirewall: jest.fn().mockImplementation(() => {
+ //console.log(`Inside describeFirewallPolicy mock ${JSON.stringify(data)}`);
+ return {
+ FirewallResponse: {
+ Firewall: {
+ FirewallName: 'VpcFirewall-1',
+ FirewallPolicyArn: 'arn:aws:network-firewall:us-east-1:1234::firewall/*',
+ Description: 'NetworkFirewallcreatedbyAWSSolutions',
+ VpcId: 'vpc-1',
+ SubnetMappings: [{ SubnetId: 'subnet-1' }, { SubnetId: 'subnet-2' }],
+ DeleteProtection: true,
+ SubnetChangeProtection: true,
+ FirewallPolicyChangeProtection: true,
+ FirewallId: 'string',
+ Tags: [{ Key: 'string', Value: 'string' }],
+ },
+ FirewallStatus: {
+ Status: 'READY',
+ ConfigurationSyncStateSummary: 'IN_SYNC',
+ SyncStates: {
+ 'us-east-1a': {
+ Attachment: { SubnetId: 'subnet-1', EndpointId: 'vpce-1', Status: 'READY' },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': {
+ SyncStatus: 'IN_SYNC',
+ },
+ },
+ },
+ 'us-east-1b': {
+ Attachment: { SubnetId: 'subnet-2', EndpointId: 'vpce-2', Status: 'READY' },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': {
+ SyncStatus: 'IN_SYNC',
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': {
+ SyncStatus: 'IN_SYNC',
+ },
+ },
+ },
+ },
+ },
+ },
+ };
+ }),
+ updateLoggingConfiguration: jest.fn().mockImplementation(() => {
+ return {};
+ }),
+ updateFirewallPolicy: jest.fn().mockImplementation(() => {
+ return {};
+ }),
+ associateFirewallPolicy: jest.fn().mockImplementation(data => {
+ expect(data['FirewallPolicyArn']).toBe(
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1'
+ );
+ }),
+ updateFirewallDeleteProtection: jest.fn().mockImplementation(data => {
+ expect(data['DeleteProtection']).toBeTruthy();
+ }),
+ updateFirewallPolicyChangeProtection: jest.fn().mockImplementation(data => {
+ expect(data['FirewallPolicyChangeProtection']).toBeTruthy();
+ }),
+ updateSubnetChangeProtection: jest.fn().mockImplementation(data => {
+ expect(data['SubnetChangeProtection']).toBeTruthy();
+ }),
+ updateFirewallDescription: jest.fn().mockImplementation(data => {
+ expect(data['Description']).toBe('Network Firewall created by AWS Solutions');
+ }),
+ }),
+ };
+ },
+ { virtual: true }
+);
test('test the method ruleGroupExist.', async () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: '', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: '' }, firewallObject, new ConfigReader());
-
- //load the firewall policy
- const policyObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewallPolicies/firewall-policy.example.json')
-
- const response = await managerInstance.ruleGroupOperations(policyObject);
-
- expect(response).toStrictEqual({ "FirewallPolicyName": "Firewall-Policy-1", "FirewallPolicy": { "StatelessDefaultActions": ["aws:drop"], "StatelessFragmentDefaultActions": ["aws:drop"], "StatelessRuleGroupReferences": [{ "Priority": 30, "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2" }, { "Priority": 20, "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1" }], "StatefulRuleGroupReferences": [{ "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1" }, { "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/suricata-icmp-rules2" }] } })
-})
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: '',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: '',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ //load the firewall policy
+ const policyObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewallPolicies/firewall-policy.example.json'
+ );
+
+ const response = await managerInstance.ruleGroupOperations(policyObject);
+
+ expect(response).toStrictEqual({
+ FirewallPolicyName: 'Firewall-Policy-1',
+ FirewallPolicy: {
+ StatelessDefaultActions: ['aws:drop'],
+ StatelessFragmentDefaultActions: ['aws:drop'],
+ StatelessRuleGroupReferences: [
+ { Priority: 30, ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2' },
+ { Priority: 20, ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1' },
+ ],
+ StatefulRuleGroupReferences: [
+ { ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1' },
+ { ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/suricata-icmp-rules2' },
+ ],
+ },
+ });
+});
test('test the method ruleGroupExist error scenario.', async () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: '', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: '' }, firewallObject, new ConfigReader());
-
- const policyObject = {
- FirewallPolicyName: 'Firewall-Policy-1',
- FirewallPolicy: {
- StatelessDefaultActions: ['aws:drop'],
- StatelessFragmentDefaultActions: ['aws:drop'],
- StatelessRuleGroupReferences: [{
- "Priority": 30,
- "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/stateless-fwd-to-stateful.example.json"
- },
- {
- "Priority": 20,
- "ResourceArn": "__tests__/firewall-test-configuration/ruleGroups/stateless-pass-action.example.json"
- }],
- StatefulRuleGroupReferences: [{
- "ResourceArn": "error"
- }]
- }
- }
-
- await expect(managerInstance.ruleGroupOperations(policyObject)).rejects.toThrowError("Error: ENOENT: no such file or directory, open 'error'")
-
-})
-
-test('test the method firewallExist.', async () => {
-
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: 'vpc-1', subnetIds: 'subnet-1, subnet-2', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
-
- const response = await managerInstance.firewallOperations();
- expect(response).toStrictEqual({
- 'us-east-1a': {
- Attachment: { SubnetId: 'subnet-1', EndpointId: 'vpce-1', Status: 'READY' },
- Config: {
- 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': {'SyncStatus': "IN_SYNC"},
- 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': {'SyncStatus': "IN_SYNC"},
- 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': {'SyncStatus': "IN_SYNC"},
- 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': {'SyncStatus': "IN_SYNC"}
- }
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: '',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: '',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ const policyObject = {
+ FirewallPolicyName: 'Firewall-Policy-1',
+ FirewallPolicy: {
+ StatelessDefaultActions: ['aws:drop'],
+ StatelessFragmentDefaultActions: ['aws:drop'],
+ StatelessRuleGroupReferences: [
+ {
+ Priority: 30,
+ ResourceArn: '__tests__/firewall-test-configuration/ruleGroups/stateless-fwd-to-stateful.example.json',
},
- 'us-east-1b': {
- Attachment: { SubnetId: 'subnet-2', EndpointId: 'vpce-2', Status: 'READY' },
- Config: {
- 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': {'SyncStatus': "IN_SYNC"},
- 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': {'SyncStatus': "IN_SYNC"},
- 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': {'SyncStatus': "IN_SYNC"},
- 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': {'SyncStatus': "IN_SYNC"}
- }
- }
- })
-})
-
+ {
+ Priority: 20,
+ ResourceArn: '__tests__/firewall-test-configuration/ruleGroups/stateless-pass-action.example.json',
+ },
+ ],
+ StatefulRuleGroupReferences: [
+ {
+ ResourceArn: 'error',
+ },
+ ],
+ },
+ };
-test('firewall policy already exists', async () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: 'vpc-1', subnetIds: 'subnet-1, subnet-2', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
+ await expect(managerInstance.ruleGroupOperations(policyObject)).rejects.toThrowError(
+ "Error: ENOENT: no such file or directory, open 'error'"
+ );
+});
- const response = await managerInstance.firewallPolicyOperations("__tests__/firewall-test-configuration/firewallPolicies/firewall-policy-2.json")
- expect(response).toBe("arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1")
-})
+test('test the method firewallExist.', async () => {
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: 'vpc-1',
+ subnetIds: 'subnet-1, subnet-2',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ const response = await managerInstance.firewallOperations();
+ expect(response).toStrictEqual({
+ 'us-east-1a': {
+ Attachment: { SubnetId: 'subnet-1', EndpointId: 'vpce-1', Status: 'READY' },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': { SyncStatus: 'IN_SYNC' },
+ },
+ },
+ 'us-east-1b': {
+ Attachment: { SubnetId: 'subnet-2', EndpointId: 'vpce-2', Status: 'READY' },
+ Config: {
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1': { SyncStatus: 'IN_SYNC' },
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2': { SyncStatus: 'IN_SYNC' },
+ },
+ },
+ });
+});
+test('firewall policy already exists', async () => {
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: 'vpc-1',
+ subnetIds: 'subnet-1, subnet-2',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ const response = await managerInstance.firewallPolicyOperations(
+ '__tests__/firewall-test-configuration/firewallPolicies/firewall-policy-2.json'
+ );
+ expect(response).toBe('arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1');
+});
test('test the logging configuration object creation from environment variables', async () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- let managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: '', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
-
- let loggingConfiguration = await managerInstance.createLoggingConfigurations()
-
- expect(loggingConfiguration.length).toBe(1)
- expect(loggingConfiguration[0].LogType).toBe("ALERT")
- expect(loggingConfiguration[0].LogDestinationType).toBe("S3")
- expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual("{\"bucketName\":\"test-bucket\",\"prefix\":\"alerts\"}")
-
-
- managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: '', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'FLOW', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
-
- loggingConfiguration = await managerInstance.createLoggingConfigurations()
-
- expect(loggingConfiguration.length).toBe(1)
- expect(loggingConfiguration[0].LogType).toBe("FLOW")
- expect(loggingConfiguration[0].LogDestinationType).toBe("S3")
- expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual("{\"bucketName\":\"test-bucket\",\"prefix\":\"flow\"}")
-
- managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: '', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'EnableBoth', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
-
- loggingConfiguration = await managerInstance.createLoggingConfigurations()
-
- expect(loggingConfiguration.length).toBe(2)
- expect(loggingConfiguration[0].LogType).toBe("ALERT")
- expect(loggingConfiguration[0].LogDestinationType).toBe("S3")
- expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual("{\"bucketName\":\"test-bucket\",\"prefix\":\"alerts\"}")
- expect(loggingConfiguration[1].LogType).toBe("FLOW")
- expect(loggingConfiguration[1].LogDestinationType).toBe("S3")
- expect(JSON.stringify(loggingConfiguration[1].LogDestination)).toStrictEqual("{\"bucketName\":\"test-bucket\",\"prefix\":\"flow\"}")
-
- managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: '', logDestinationType: 'CloudWatchLogs', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'EnableBoth', logDestination: 'log-group-name' }, firewallObject, new ConfigReader());
-
- loggingConfiguration = await managerInstance.createLoggingConfigurations()
-
- expect(loggingConfiguration.length).toBe(2)
- expect(loggingConfiguration[0].LogType).toBe("ALERT")
- expect(loggingConfiguration[0].LogDestinationType).toBe("CloudWatchLogs")
- expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual("{\"logGroup\":\"log-group-name\"}")
-
- expect(loggingConfiguration[1].LogType).toBe("FLOW")
- expect(loggingConfiguration[1].LogDestinationType).toBe("CloudWatchLogs")
- expect(JSON.stringify(loggingConfiguration[1].LogDestination)).toStrictEqual("{\"logGroup\":\"log-group-name\"}")
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ let managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: '',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ let loggingConfiguration = await managerInstance.createLoggingConfigurations();
+
+ expect(loggingConfiguration.length).toBe(1);
+ expect(loggingConfiguration[0].LogType).toBe('ALERT');
+ expect(loggingConfiguration[0].LogDestinationType).toBe('S3');
+ expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual(
+ '{"bucketName":"test-bucket","prefix":"alerts"}'
+ );
+
+ managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: '',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'FLOW',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ loggingConfiguration = await managerInstance.createLoggingConfigurations();
+
+ expect(loggingConfiguration.length).toBe(1);
+ expect(loggingConfiguration[0].LogType).toBe('FLOW');
+ expect(loggingConfiguration[0].LogDestinationType).toBe('S3');
+ expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual(
+ '{"bucketName":"test-bucket","prefix":"flow"}'
+ );
+
+ managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: '',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'EnableBoth',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ loggingConfiguration = await managerInstance.createLoggingConfigurations();
+
+ expect(loggingConfiguration.length).toBe(2);
+ expect(loggingConfiguration[0].LogType).toBe('ALERT');
+ expect(loggingConfiguration[0].LogDestinationType).toBe('S3');
+ expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual(
+ '{"bucketName":"test-bucket","prefix":"alerts"}'
+ );
+ expect(loggingConfiguration[1].LogType).toBe('FLOW');
+ expect(loggingConfiguration[1].LogDestinationType).toBe('S3');
+ expect(JSON.stringify(loggingConfiguration[1].LogDestination)).toStrictEqual(
+ '{"bucketName":"test-bucket","prefix":"flow"}'
+ );
+
+ managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: '',
+ logDestinationType: 'CloudWatchLogs',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'EnableBoth',
+ logDestination: 'log-group-name',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ loggingConfiguration = await managerInstance.createLoggingConfigurations();
+
+ expect(loggingConfiguration.length).toBe(2);
+ expect(loggingConfiguration[0].LogType).toBe('ALERT');
+ expect(loggingConfiguration[0].LogDestinationType).toBe('CloudWatchLogs');
+ expect(JSON.stringify(loggingConfiguration[0].LogDestination)).toStrictEqual('{"logGroup":"log-group-name"}');
+
+ expect(loggingConfiguration[1].LogType).toBe('FLOW');
+ expect(loggingConfiguration[1].LogDestinationType).toBe('CloudWatchLogs');
+ expect(JSON.stringify(loggingConfiguration[1].LogDestination)).toStrictEqual('{"logGroup":"log-group-name"}');
});
test('subnet mappings function should return an array', () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: 'vpc-1', subnetIds: 'subnet-1, subnet-2', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
- expect(managerInstance.getSubnetMapping()).toStrictEqual([ { SubnetId: 'subnet-1' }, { SubnetId: ' subnet-2' } ])
-})
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: 'vpc-1',
+ subnetIds: 'subnet-1, subnet-2',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+ expect(managerInstance.getSubnetMapping()).toStrictEqual([{ SubnetId: 'subnet-1' }, { SubnetId: ' subnet-2' }]);
+});
test('subnet mappings function should return an array --error scenario', () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: 'vpc-1', subnetIds: '', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
- try {
- managerInstance.getSubnetMapping()
- } catch(error) {
- expect(error["message"]).toBe("Subnet IDs must be in the environment variables")
- }
-})
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: 'vpc-1',
+ subnetIds: '',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+ try {
+ managerInstance.getSubnetMapping();
+ } catch (error: any) {
+ expect(error['message']).toBe('Subnet IDs must be in the environment variables');
+ }
+});
test('vpc id should be return from environment variable', () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: 'vpc-1', subnetIds: 'subnet-1, subnet-2', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
- expect(managerInstance.getVpcId()).toBe("vpc-1")
-})
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: 'vpc-1',
+ subnetIds: 'subnet-1, subnet-2',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+ expect(managerInstance.getVpcId()).toBe('vpc-1');
+});
test('vpc id should be return from environment variable --error scenario', () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: 'subnet-1, subnet-2', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
- try {
- managerInstance.getVpcId()
- } catch (error) {
- expect(error["message"]).toBe("VPC ID must be in the environment variables")
- }
-})
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: 'subnet-1, subnet-2',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+ try {
+ managerInstance.getVpcId();
+ } catch (error: any) {
+ expect(error['message']).toBe('VPC ID must be in the environment variables');
+ }
+});
test('Update firewall properties', async () => {
- const fileHandler = new ConfigReader();
- let firewallObject = fileHandler.convertFileToObject('__tests__/firewall-test-configuration/firewalls/firewall.example.json')
- const managerInstance = new NetworkFirewallManager(
- { vpcId: '', subnetIds: 'subnet-1, subnet-2', logDestinationType: 'S3', logRetentionPeriod: "90", stackId : 'f449b250-b969-11e0-a185-5081d0136786', logType: 'ALERT', logDestination: 'test-bucket' }, firewallObject, new ConfigReader());
-
- await managerInstance.updateFirewall({
- Firewall: {
- FirewallId: '12345',
- FirewallPolicyArn: 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-2',
- SubnetMappings: [],
- VpcId: '',
- DeleteProtection: false,
- Description: '',
- FirewallName: 'VpcFirewall-1',
- FirewallArn: '',
- FirewallPolicyChangeProtection: false,
- SubnetChangeProtection: false
- }
- }, 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1')
-
-})
-
+ const fileHandler = new ConfigReader();
+ let firewallObject = fileHandler.convertFileToObject(
+ '__tests__/firewall-test-configuration/firewalls/firewall.example.json'
+ );
+ const managerInstance = new NetworkFirewallManager(
+ {
+ vpcId: '',
+ subnetIds: 'subnet-1, subnet-2',
+ logDestinationType: 'S3',
+ logRetentionPeriod: '90',
+ stackId: 'f449b250-b969-11e0-a185-5081d0136786',
+ logType: 'ALERT',
+ logDestination: 'test-bucket',
+ },
+ firewallObject,
+ new ConfigReader()
+ );
+
+ await managerInstance.updateFirewall(
+ {
+ Firewall: {
+ FirewallId: '12345',
+ FirewallPolicyArn: 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-2',
+ SubnetMappings: [],
+ VpcId: '',
+ DeleteProtection: false,
+ Description: '',
+ FirewallName: 'VpcFirewall-1',
+ FirewallArn: '',
+ FirewallPolicyChangeProtection: false,
+ SubnetChangeProtection: false,
+ },
+ },
+ 'arn:aws:network-firewall:us-east-1:1234:firewall-policy/Firewall-Policy-1'
+ );
+});
diff --git a/source/networkFirewallAutomation/__tests__/network-firewall-service.spec.ts b/source/networkFirewallAutomation/__tests__/network-firewall-service.spec.ts
index 8bd18e7..9c14203 100644
--- a/source/networkFirewallAutomation/__tests__/network-firewall-service.spec.ts
+++ b/source/networkFirewallAutomation/__tests__/network-firewall-service.spec.ts
@@ -1,740 +1,774 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
import { NetworkFirewallService } from '../lib/service/network-firewall-service';
-jest.mock("aws-sdk", () => {
- return {
- __esModule: true,
- NetworkFirewall: jest.fn().mockReturnValue({
- deleteRuleGroup: jest.fn().mockImplementation((data) => {
- expect(data['RuleGroupArn']).toBeDefined();
- return {
- promise: jest.fn().mockImplementation(() => {
- return Promise.resolve(
- {
+jest.mock(
+ 'aws-sdk',
+ () => {
+ return {
+ __esModule: true,
+ NetworkFirewall: jest.fn().mockReturnValue({
+ deleteRuleGroup: jest.fn().mockImplementation(data => {
+ expect(data['RuleGroupArn']).toBeDefined();
+ return {
+ promise: jest.fn().mockImplementation(() => {
+ return Promise.resolve({
ResourceArn: '',
ResourceName: 'rg1',
Description: '',
UpdateToken: '',
- RulesSource: {}
- })
- })
- }
- }),
- describeRuleGroup: jest.fn().mockImplementation((ruleGroup) => {
- if (ruleGroup["RuleGroupName"] === "ThrottlingException") {
- throw {
- "message": "ThrottlingException"
+ RulesSource: {},
+ });
+ }),
+ };
+ }),
+ describeRuleGroup: jest.fn().mockImplementation(ruleGroup => {
+ if (ruleGroup['RuleGroupName'] === 'ThrottlingException') {
+ throw {
+ message: 'ThrottlingException',
+ };
+ }
+ if (ruleGroup['RuleGroupName'] === 'ResourceNotFoundException') {
+ throw { code: 'ResourceNotFoundException' };
+ }
+ if (ruleGroup['RuleGroupName'] === 'Error') {
+ return Promise.reject({
+ message: 'Error',
+ });
+ }
+ if (
+ ruleGroup['RuleGroupArn'] ===
+ 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2'
+ ) {
+ return {
+ promise: jest.fn().mockReturnValue({
+ UpdateToken: 'aaaa',
+ RuleGroupResponse: {
+ RuleGroupArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ RuleGroupName: 'StatelessExample2',
+ RuleGroupId: 111,
+ },
+ }),
+ };
}
- }
- if (ruleGroup["RuleGroupName"] === "ResourceNotFoundException") {
- throw {"code": "ResourceNotFoundException"};
- }
- if (ruleGroup["RuleGroupName"] === "Error") {
- return Promise.reject({
- message: "Error"
- })
- }
- if (ruleGroup["RuleGroupArn"] === "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2") {
return {
promise: jest.fn().mockReturnValue({
- UpdateToken: "aaaa",
+ RuleGroup: {
+ RuleVariables: {
+ IPSets: [
+ {
+ foo: {
+ Definition: [''],
+ Reference: 'AWS_ARN',
+ },
+ },
+ ],
+ PortSets: [
+ {
+ foo: {
+ Definition: [''],
+ },
+ },
+ ],
+ },
+ RulesSource: {
+ RulesString: '',
+ RulesSourceList: [
+ {
+ Targets: [''],
+ TargetType: [''],
+ GeneratedRulesType: '',
+ },
+ ],
+ StatefulRules: [
+ {
+ Action: '',
+ Header: {
+ Protocol: '',
+ Source: '',
+ SourcePort: '',
+ Direction: '',
+ Destination: '',
+ DestinationPort: '',
+ },
+ RuleOptions: [
+ {
+ Keyword: '',
+ Settings: [''],
+ },
+ ],
+ },
+ ],
+ StatelessRulesAndCustomActions: {
+ StatelessRules: [
+ {
+ RuleDefinition: {
+ MatchAttributes: {
+ Sources: [''],
+ Destinations: [''],
+ SourcePorts: [
+ {
+ FromPort: 0,
+ ToPort: 999,
+ },
+ ],
+ DestinationPorts: [
+ {
+ FromPort: 0,
+ ToPort: 999,
+ },
+ ],
+ Protocols: [0, 1, 2, 3],
+ TCPFlags: [
+ {
+ Flags: [''],
+ Masks: [''],
+ },
+ ],
+ },
+ Actions: [''],
+ },
+ Priority: 9999,
+ },
+ ],
+ CustomAction: {
+ PublishMetrics: {
+ Dimensions: [
+ {
+ Value: '',
+ },
+ ],
+ },
+ },
+ },
+ },
+ },
RuleGroupResponse: {
- RuleGroupArn: "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2",
- RuleGroupName: "StatelessExample2",
- RuleGroupId: 111
- }
- })
- }
- }
- return {
- promise: jest.fn().mockReturnValue({
- RuleGroup: {
- RuleVariables: {
- IPSets: [{
- "foo": {
- Definition: [''],
- Reference: 'AWS_ARN'
- }
- }],
- PortSets: [{
- "foo": {
- Definition: ['']
- }
- }]
+ RuleGroupArn: '',
+ RuleGroupName: '',
+ RuleGroupId: '',
+ Description: '',
+ Type: '',
+ Capacity: 9999,
+ RuleGroupStatus: 'ACTIVE|DELETING|string',
+ Tags: [
+ {
+ Key: '',
+ Value: '',
+ },
+ ],
+ },
+ UpdateToken: 'aaa',
+ }),
+ };
+ }),
+ describeFirewallPolicy: jest.fn().mockImplementation(() => {
+ return {
+ promise: jest.fn().mockReturnValue({
+ UpdateToken: 'aaaa',
+ FirewallPolicyResponse: {
+ FirewallPolicyName: 'test-firewall-policy',
+ FirewallPolicyArn: '',
+ FirewallPolicyId: '',
+ Description: '',
+ FirewallPolicyStatus: 'ACTIVE',
+ Tags: [
+ {
+ Key: '',
+ Value: '',
+ },
+ ],
},
- RulesSource: {
- RulesString: '',
- RulesSourceList: [{
- Targets: [''],
- TargetType: [''],
- GeneratedRulesType: ''
- }],
- StatefulRules: [{
- Action: '',
- Header: {
- Protocol: '',
- Source: '',
- SourcePort: '',
- Direction: '',
- Destination: '',
- DestinationPort: ''
+ FirewallPolicy: {
+ StatelessRuleGroupReferences: [
+ {
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ Priority: 999,
},
- RuleOptions: [{
- Keyword: '',
- Settings: ['']
- }]
- }],
- StatelessRulesAndCustomActions: {
- StatelessRules: [{
- RuleDefinition: {
- MatchAttributes: {
- Sources: [''],
- Destinations: [''],
- SourcePorts: [{
- FromPort: 0,
- ToPort: 999
- }],
- DestinationPorts: [{
- FromPort: 0,
- ToPort: 999
- }],
- Protocols: [0, 1, 2, 3],
- TCPFlags: [{
- Flags: [''],
- Masks: ['']
- }]
+ ],
+ StatelessDefaultActions: [''],
+ StatelessFragmentDefaultActions: [''],
+ StatelessCustomActions: [
+ {
+ ActionName: '',
+ CustomAction: {
+ PublishMetrics: {
+ Dimensions: [
+ {
+ Value: '',
+ },
+ ],
},
- Actions: ['']
},
- Priority: 9999
- }],
- CustomAction: {
- PublishMetrics: {
- Dimensions: [{
- Value: ''
- }]
- }
- }
- }
- }
- },
- RuleGroupResponse: {
- RuleGroupArn: '',
- RuleGroupName: '',
- RuleGroupId: '',
- Description: '',
- Type: '',
- Capacity: 9999,
- RuleGroupStatus: 'ACTIVE|DELETING|string',
- Tags: [{
- Key: '',
- Value: ''
- }]
- },
- UpdateToken: 'aaa'
- })
- }
- }),
- describeFirewallPolicy: jest.fn().mockImplementation(() => {
- return {
- promise: jest.fn().mockReturnValue({
- UpdateToken: 'aaaa',
- FirewallPolicyResponse: {
- FirewallPolicyName: 'test-firewall-policy',
- FirewallPolicyArn: '',
- FirewallPolicyId: '',
- Description: '',
- FirewallPolicyStatus: 'ACTIVE',
- Tags: [{
- Key: '',
- Value: ''
- }]
- },
- FirewallPolicy: {
- StatelessRuleGroupReferences: [{
- ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
- Priority: 999
- }],
- StatelessDefaultActions: [''],
- StatelessFragmentDefaultActions: [''],
- StatelessCustomActions: [{
- ActionName: '',
- CustomAction: {
- PublishMetrics: {
- Dimensions: [{
- Value: ''
- }]
- }
- }
- }],
- StatefulRuleGroupReferences: [{
- ResourceArn: ''
- }]
+ },
+ ],
+ StatefulRuleGroupReferences: [
+ {
+ ResourceArn: '',
+ },
+ ],
+ },
+ }),
+ };
+ }),
+ updateRuleGroup: jest.fn().mockImplementation(data => {
+ if (data['UpdateToken'] === 'invalid token') {
+ return {
+ promise: jest.fn().mockReturnValue({
+ message: 'Update token is invalid.',
+ }),
+ };
+ }
+ if (data['UpdateToken'] === 'error') {
+ return {
+ promise: jest.fn().mockReturnValue(Promise.reject()),
+ };
+ }
- }
- })
- }
- }),
- updateRuleGroup: jest.fn().mockImplementation((data) =>{
- if (data['UpdateToken'] === 'invalid token') {
return {
promise: jest.fn().mockReturnValue({
- message: 'Update token is invalid.'
- })
+ UpdateToken: '',
+ RuleGroupResponse: {
+ RuleGroupArn: '',
+ RuleGroupName: '',
+ RuleGroupId: '',
+ Description: '',
+ Type: '"STATELESS"|"STATEFUL"|string',
+ Capacity: 999,
+ RuleGroupStatus: '"ACTIVE"|"DELETING"|string',
+ Tags: [
+ {
+ Key: '',
+ Value: '',
+ },
+ ],
+ },
+ }),
+ };
+ }),
+ updateFirewallPolicy: jest.fn().mockImplementation(data => {
+ if (data && data['UpdateToken'] === 'test invalid token scenario') {
+ throw {
+ message: 'Update token is invalid.',
+ };
}
- }
- if (data["UpdateToken"] === "error") {
+ if (data && data['UpdateToken'] === 'error') {
+ throw {
+ message: 'error',
+ };
+ }
+
return {
- promise: jest.fn().mockReturnValue(
- Promise.reject())
+ promise: jest.fn().mockReturnValue({
+ UpdateToken: 'aaa',
+ FirewallPolicyResponse: {
+ FirewallPolicyName: '',
+ FirewallPolicyArn: '',
+ FirewallPolicyId: '',
+ Description: '',
+ FirewallPolicyStatus: '"ACTIVE"|"DELETING"|string',
+ Tags: [
+ {
+ Key: '',
+ Value: '',
+ },
+ ],
+ },
+ }),
+ };
+ }),
+ listFirewalls: jest.fn().mockReturnValue({
+ promise: jest.fn().mockReturnValue({}),
+ }),
+ createFirewall: jest.fn().mockImplementation(data => {
+ if (data['Description'] === 'Error') {
+ throw Error('ResourceNotFoundException');
}
- }
-
- return {
- promise: jest.fn().mockReturnValue({
- UpdateToken: '',
- RuleGroupResponse: {
- RuleGroupArn: '',
- RuleGroupName: '',
- RuleGroupId: '',
- Description: '',
- Type: '"STATELESS"|"STATEFUL"|string',
- Capacity: 999,
- RuleGroupStatus: '"ACTIVE"|"DELETING"|string',
- Tags: [{
- Key: '',
- Value: ''
- }]
+ return {
+ promise: jest.fn().mockReturnValue({}),
+ };
+ }),
+ createFirewallPolicy: jest.fn().mockReturnValue({
+ promise: jest.fn().mockReturnValue({}),
+ }),
+ createRuleGroup: jest.fn().mockReturnValue({
+ promise: jest.fn().mockReturnValue({}),
+ }),
+ describeFirewall: jest.fn().mockImplementation(data => {
+ if (data['FirewallName'] === 'error') {
+ throw Error('ResourceNotFoundException');
}
- })}
- }),
- updateFirewallPolicy: jest.fn().mockImplementation((data) => {
- if (data && data["UpdateToken"] === "test invalid token scenario") {
- throw {
- message: "Update token is invalid."
+ expect(data['FirewallName']).toBeDefined();
+ return {
+ promise: jest.fn().mockReturnValue({}),
+ };
+ }),
+ describeLoggingConfiguration: jest.fn().mockReturnValue({
+ promise: jest.fn().mockReturnValue({
+ LoggingConfiguration: {
+ LogDestinationConfigs: [
+ {
+ LogType: 'ALERT',
+ LogDestinationType: 'CloudWatchLogs',
+ LogDestination: {
+ logGroup: 'network-firewall-automation-solution',
+ prefix: 'alerts',
+ },
+ },
+ ],
+ },
+ }),
+ }),
+ updateLoggingConfiguration: jest.fn().mockImplementation(config => {
+ if (config['LoggingConfiguration']['LogDestinationConfigs'][0] === undefined) {
+ return {
+ promise: jest.fn().mockReturnValue({
+ LoggingConfiguration: {
+ LogDestinationConfigs: [],
+ },
+ }),
+ };
}
- }
- if (data && data["UpdateToken"] === "error") {
- throw {
- "message": "error"
+ if (config['LoggingConfiguration']['LogDestinationConfigs'][0]['LogDestinationType'] === 'CloudWatchLogs') {
+ return {
+ promise: jest.fn().mockReturnValue({
+ LoggingConfiguration: {
+ LogDestinationConfigs: [],
+ },
+ }),
+ };
}
- }
-
- return {
- promise: jest.fn().mockReturnValue({
- UpdateToken: 'aaa',
- FirewallPolicyResponse: {
- FirewallPolicyName: '',
- FirewallPolicyArn: '',
- FirewallPolicyId: '',
- Description: '',
- FirewallPolicyStatus: '"ACTIVE"|"DELETING"|string',
- Tags: [{
- Key: '',
- Value: ''
- }]
- }
- })
- }
- }),
- listFirewalls: jest.fn().mockReturnValue({
- promise: jest.fn().mockReturnValue({})
- }),
- createFirewall: jest.fn().mockImplementation((data) => {
- if (data["Description"] === "Error") {
- throw Error("ResourceNotFoundException")
- }
- return {
- promise: jest.fn().mockReturnValue({})
-
- }
- }),
- createFirewallPolicy: jest.fn().mockReturnValue({
- promise: jest.fn().mockReturnValue({
-
- })
- }),
- createRuleGroup: jest.fn().mockReturnValue({
- promise: jest.fn().mockReturnValue({
-
- })
- }),
- describeFirewall: jest.fn().mockImplementation((data) => {
- if (data["FirewallName"] === "error") {
- throw Error("ResourceNotFoundException")
- }
- expect(data["FirewallName"]).toBeDefined();
- return {
- promise: jest.fn().mockReturnValue({
-
- })
- }
- }),
- describeLoggingConfiguration: jest.fn().mockReturnValue({
- promise: jest.fn().mockReturnValue({
- LoggingConfiguration: {
- LogDestinationConfigs: [{
- LogType: 'ALERT',
- LogDestinationType: 'CloudWatchLogs',
- LogDestination: {
- 'logGroup': "network-firewall-automation-solution",
- 'prefix': 'alerts'
- }
- }]
- }
- })
- }),
- updateLoggingConfiguration: jest.fn().mockImplementation((config)=> {
- if(config["LoggingConfiguration"]["LogDestinationConfigs"][0] === undefined) {
-
return {
promise: jest.fn().mockReturnValue({
LoggingConfiguration: {
- LogDestinationConfigs: []
- }
- })
+ LogDestinationConfigs: [config['LoggingConfiguration']['LogDestinationConfigs'][0]],
+ },
+ }),
+ };
+ }),
+ associateFirewallPolicy: jest.fn().mockImplementation(data => {
+ if (data && data['FirewallName'] === 'error') {
+ throw {
+ message: 'error',
+ };
}
- }
- if (config["LoggingConfiguration"]["LogDestinationConfigs"][0]["LogDestinationType"] === "CloudWatchLogs") {
- return {
- promise: jest.fn().mockReturnValue({
- LoggingConfiguration: {
- LogDestinationConfigs: []
- }
- })
+ return { promise: jest.fn().mockReturnValue({}) };
+ }),
+ updateSubnetChangeProtection: jest.fn().mockImplementation(data => {
+ if (data && data['FirewallName'] === 'error') {
+ throw {
+ message: 'error',
+ };
}
- }
-
-
- return {
- promise: jest.fn().mockReturnValue({
- LoggingConfiguration: {
- LogDestinationConfigs: [config["LoggingConfiguration"]["LogDestinationConfigs"][0]]
- }
- })
- }
- }),
- associateFirewallPolicy: jest.fn().mockImplementation((data) => {
-
- if (data && data["FirewallName"] === "error") {
- throw {
- "message": "error"
- }
- }
- return {promise: jest.fn().mockReturnValue({
-
- })}
- }),
- updateSubnetChangeProtection: jest.fn().mockImplementation((data) => {
- if (data && data["FirewallName"] === "error") {
- throw {
- "message": "error"
- }
- }
- return {promise: jest.fn().mockReturnValue({
-
- })}
- }),
- updateFirewallDescription: jest.fn().mockImplementation((data) => {
- if (data && data["FirewallName"] === "error") {
- throw {
- "message": "error"
- }
- }
- return {promise: jest.fn().mockReturnValue({
-
- })}
- }),
- updateFirewallPolicyChangeProtection: jest.fn().mockImplementation((data) => {
- if (data && data["FirewallName"] === "error") {
- throw {
- "message": "error"
- }
- }
- return {promise: jest.fn().mockReturnValue({
-
- })}
+ return { promise: jest.fn().mockReturnValue({}) };
+ }),
+ updateFirewallDescription: jest.fn().mockImplementation(data => {
+ if (data && data['FirewallName'] === 'error') {
+ throw {
+ message: 'error',
+ };
+ }
+ return { promise: jest.fn().mockReturnValue({}) };
+ }),
+ updateFirewallPolicyChangeProtection: jest.fn().mockImplementation(data => {
+ if (data && data['FirewallName'] === 'error') {
+ throw {
+ message: 'error',
+ };
+ }
+ return { promise: jest.fn().mockReturnValue({}) };
+ }),
+ updateFirewallDeleteProtection: jest.fn().mockImplementation(data => {
+ if (data && data['FirewallName'] === 'error') {
+ throw {
+ message: 'error',
+ };
+ }
+ return { promise: jest.fn().mockReturnValue({}) };
+ }),
}),
- updateFirewallDeleteProtection: jest.fn().mockImplementation((data) => {
- if (data && data["FirewallName"] === "error") {
- throw {
- "message": "error"
- }
- }
- return {promise: jest.fn().mockReturnValue({
-
- })}
- })
- })
- }
-}, { virtual: true });
-
-
+ };
+ },
+ { virtual: true }
+);
test('test describe firewall policy', async () => {
-
const service = new NetworkFirewallService();
- await expect(service.describeFirewallPolicy(
-'test-network-firewall'
- )).resolves.toBeDefined()
-})
-
+ await expect(service.describeFirewallPolicy('test-network-firewall')).resolves.toBeDefined();
+});
test('test describe rule group', async () => {
- const service = new NetworkFirewallService()
+ const service = new NetworkFirewallService();
await expect(service.describeRuleGroup('test-stateless-rg1', 'STATEFUL')).resolves.toBeDefined();
-})
+});
test('test describe rule group throttling error response', async () => {
- const service = new NetworkFirewallService()
- await expect(service.describeRuleGroup('ThrottlingException', 'STATEFUL')).rejects.toStrictEqual({"message":"ThrottlingException"});
-})
+ const service = new NetworkFirewallService();
+ await expect(service.describeRuleGroup('ThrottlingException', 'STATEFUL')).rejects.toStrictEqual({
+ message: 'Unable to resolve request and completed retries.',
+ });
+});
test('test describe rule group resource not found exception response', async () => {
- const service = new NetworkFirewallService()
+ const service = new NetworkFirewallService();
await expect(service.describeRuleGroup('ResourceNotFoundException', 'STATEFUL')).resolves.toBeUndefined();
-})
+});
test('create firewall ', async () => {
- const service = new NetworkFirewallService()
- await expect(service.createFirewall({
- "FirewallName": "VpcFirewall-1",
- "FirewallPolicyArn": "__tests__/firewall-test-configuration/firewallPolicies/firewall-policy.example.json",
- "Description": "Network Firewall created by AWS Solutions",
- "DeleteProtection": true,
- "FirewallPolicyChangeProtection": true,
- "SubnetChangeProtection": true,
- "SubnetMappings": [],
- "VpcId": '',
- "Tags": [{
- "Key": "SampleKey",
- "Value": "SampleValue"
- }]
- })).resolves.toBeDefined()
-})
-test('create firewall handle error response from the sdk. ', async () => {
- const service = new NetworkFirewallService()
- await expect(service.createFirewall({
- "FirewallName": "VpcFirewall-1",
- "FirewallPolicyArn": "__tests__/firewall-test-configuration/firewallPolicies/firewall-policy.example.json",
- "Description": "Error",
- "DeleteProtection": true,
- "FirewallPolicyChangeProtection": true,
- "SubnetChangeProtection": true,
- "SubnetMappings": [],
- "VpcId": '',
- "Tags": [{
- "Key": "SampleKey",
- "Value": "SampleValue"
- }]
- })).rejects.toThrowError("ResourceNotFoundException")
-})
-
-test('create Firewall policy', async () => {
- const service = new NetworkFirewallService()
- await expect(service.createFirewallPolicy({
- "FirewallPolicyName": "Firewall-Policy-1",
- "FirewallPolicy": {
- "StatelessDefaultActions": [
- "aws:drop"
- ],
- "StatelessFragmentDefaultActions": [
- "aws:drop"
- ],
- "StatelessRuleGroupReferences": [
+ const service = new NetworkFirewallService();
+ await expect(
+ service.createFirewall({
+ FirewallName: 'VpcFirewall-1',
+ FirewallPolicyArn: '__tests__/firewall-test-configuration/firewallPolicies/firewall-policy.example.json',
+ Description: 'Network Firewall created by AWS Solutions',
+ DeleteProtection: true,
+ FirewallPolicyChangeProtection: true,
+ SubnetChangeProtection: true,
+ SubnetMappings: [],
+ VpcId: '',
+ Tags: [
{
- "Priority": 30,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2"
+ Key: 'SampleKey',
+ Value: 'SampleValue',
},
- {
- "Priority": 20,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1"
- }
],
- "StatefulRuleGroupReferences": [
+ })
+ ).resolves.toBeDefined();
+});
+test('create firewall handle error response from the sdk. ', async () => {
+ const service = new NetworkFirewallService();
+ await expect(
+ service.createFirewall({
+ FirewallName: 'VpcFirewall-1',
+ FirewallPolicyArn: '__tests__/firewall-test-configuration/firewallPolicies/firewall-policy.example.json',
+ Description: 'Error',
+ DeleteProtection: true,
+ FirewallPolicyChangeProtection: true,
+ SubnetChangeProtection: true,
+ SubnetMappings: [],
+ VpcId: '',
+ Tags: [
{
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1"
- }
- ]
- }
- })).resolves.toBeDefined();
+ Key: 'SampleKey',
+ Value: 'SampleValue',
+ },
+ ],
+ })
+ ).rejects.toThrowError('ResourceNotFoundException');
+});
-})
+test('create Firewall policy', async () => {
+ const service = new NetworkFirewallService();
+ await expect(
+ service.createFirewallPolicy({
+ FirewallPolicyName: 'Firewall-Policy-1',
+ FirewallPolicy: {
+ StatelessDefaultActions: ['aws:drop'],
+ StatelessFragmentDefaultActions: ['aws:drop'],
+ StatelessRuleGroupReferences: [
+ {
+ Priority: 30,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ },
+ {
+ Priority: 20,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1',
+ },
+ ],
+ StatefulRuleGroupReferences: [
+ {
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1',
+ },
+ ],
+ },
+ })
+ ).resolves.toBeDefined();
+});
test('create rule group', async () => {
-
- const service = new NetworkFirewallService()
- await expect(service.createRuleGroup({
- "RuleGroupName": "StatefulRulesExample1",
- "RuleGroup": {
- "RulesSource": {
- "RulesSourceList": {
- "Targets": ["test.example.com"],
- "TargetTypes": ["HTTP_HOST", "TLS_SNI"],
- "GeneratedRulesType": "DENYLIST"
- }
- }
- },
- "Type": "STATEFUL",
- "Description": "Stateful Rule3",
- "Capacity": 100
- })).resolves.toBeDefined();
-
-})
+ const service = new NetworkFirewallService();
+ await expect(
+ service.createRuleGroup({
+ RuleGroupName: 'StatefulRulesExample1',
+ RuleGroup: {
+ RulesSource: {
+ RulesSourceList: {
+ Targets: ['test.example.com'],
+ TargetTypes: ['HTTP_HOST', 'TLS_SNI'],
+ GeneratedRulesType: 'DENYLIST',
+ },
+ },
+ },
+ Type: 'STATEFUL',
+ Description: 'Stateful Rule3',
+ Capacity: 100,
+ })
+ ).resolves.toBeDefined();
+});
test(' describe firewall', async () => {
- const service = new NetworkFirewallService()
+ const service = new NetworkFirewallService();
await expect(service.describeFirewall('firewall-name')).resolves.toBeDefined();
-})
+});
test(' describe firewall handle sdk error', async () => {
- const service = new NetworkFirewallService()
- await expect(service.describeFirewall('error'))
- .rejects.toThrowError("ResourceNotFoundException")
-})
+ const service = new NetworkFirewallService();
+ await expect(service.describeFirewall('error')).rejects.toThrowError('ResourceNotFoundException');
+});
test('Update firewall policy ', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallPolicy({
- UpdateToken: '',
- FirewallPolicyArn: '',
- FirewallPolicyName: 'test',
- FirewallPolicy: {
- "StatelessDefaultActions": [
- "aws:drop"
- ],
- "StatelessFragmentDefaultActions": [
- "aws:drop"
- ],
- "StatelessRuleGroupReferences": [
- {
- "Priority": 30,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2"
- },
- {
- "Priority": 20,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1"
- }
- ],
- "StatefulRuleGroupReferences": [
- {
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1"
- }
- ]
- }
- })).resolves.toBeDefined()
-})
+ await expect(
+ service.updateFirewallPolicy({
+ UpdateToken: '',
+ FirewallPolicyArn: '',
+ FirewallPolicyName: 'test',
+ FirewallPolicy: {
+ StatelessDefaultActions: ['aws:drop'],
+ StatelessFragmentDefaultActions: ['aws:drop'],
+ StatelessRuleGroupReferences: [
+ {
+ Priority: 30,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ },
+ {
+ Priority: 20,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1',
+ },
+ ],
+ StatefulRuleGroupReferences: [
+ {
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1',
+ },
+ ],
+ },
+ })
+ ).resolves.toBeDefined();
+});
test('Update firewall policy handle invalid token scenario.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallPolicy({
- UpdateToken: 'test invalid token scenario',
- FirewallPolicyArn: '',
- FirewallPolicyName: 'test',
- FirewallPolicy: {
- "StatelessDefaultActions": [
- "aws:drop"
- ],
- "StatelessFragmentDefaultActions": [
- "aws:drop"
- ],
- "StatelessRuleGroupReferences": [
- {
- "Priority": 30,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2"
- },
- {
- "Priority": 20,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1"
- }
- ],
- "StatefulRuleGroupReferences": [
- {
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1"
- }
- ]
- }
- })).resolves.toBeDefined()
-})
+ await expect(
+ service.updateFirewallPolicy({
+ UpdateToken: 'test invalid token scenario',
+ FirewallPolicyArn: '',
+ FirewallPolicyName: 'test',
+ FirewallPolicy: {
+ StatelessDefaultActions: ['aws:drop'],
+ StatelessFragmentDefaultActions: ['aws:drop'],
+ StatelessRuleGroupReferences: [
+ {
+ Priority: 30,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ },
+ {
+ Priority: 20,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1',
+ },
+ ],
+ StatefulRuleGroupReferences: [
+ {
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1',
+ },
+ ],
+ },
+ })
+ ).resolves.toBeDefined();
+});
test('Update firewall policy handle error.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallPolicy({
- UpdateToken: 'error',
- FirewallPolicyArn: '',
- FirewallPolicyName: 'test',
- FirewallPolicy: {
- "StatelessDefaultActions": [
- "aws:drop"
- ],
- "StatelessFragmentDefaultActions": [
- "aws:drop"
- ],
- "StatelessRuleGroupReferences": [
- {
- "Priority": 30,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2"
- },
- {
- "Priority": 20,
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1"
- }
- ],
- "StatefulRuleGroupReferences": [
- {
- "ResourceArn": "arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1"
- }
- ]
- }
- })).rejects.toBeDefined()
-})
-
+ await expect(
+ service.updateFirewallPolicy({
+ UpdateToken: 'error',
+ FirewallPolicyArn: '',
+ FirewallPolicyName: 'test',
+ FirewallPolicy: {
+ StatelessDefaultActions: ['aws:drop'],
+ StatelessFragmentDefaultActions: ['aws:drop'],
+ StatelessRuleGroupReferences: [
+ {
+ Priority: 30,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample2',
+ },
+ {
+ Priority: 20,
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateless-rulegroup/StatelessExample1',
+ },
+ ],
+ StatefulRuleGroupReferences: [
+ {
+ ResourceArn: 'arn:aws:network-firewall:us-east-1:1234:stateful-rulegroup/StatefulRulesExample1',
+ },
+ ],
+ },
+ })
+ ).rejects.toBeDefined();
+});
test('Update rule groups', async () => {
-
- const service = new NetworkFirewallService()
- await expect(service.updateRuleGroup({
- UpdateToken: '',
- RuleGroupName: 'test'
- })).resolves.toBeDefined()
-
-})
+ const service = new NetworkFirewallService();
+ await expect(
+ service.updateRuleGroup({
+ UpdateToken: '',
+ RuleGroupName: 'test',
+ })
+ ).resolves.toBeDefined();
+});
test('Update rule groups handle invalid token error', async () => {
-
- const service = new NetworkFirewallService()
- await expect(service.updateRuleGroup({
- UpdateToken: 'invalid token',
- RuleGroupName: 'test'
- })).resolves.toBeDefined()
-
-})
+ const service = new NetworkFirewallService();
+ await expect(
+ service.updateRuleGroup({
+ UpdateToken: 'invalid token',
+ RuleGroupName: 'test',
+ })
+ ).resolves.toBeDefined();
+});
test('Update rule groups handle error', async () => {
-
- const service = new NetworkFirewallService()
- await expect(service.updateRuleGroup({
- UpdateToken: 'error',
- RuleGroupName: 'test'
- })).rejects.toThrowError()
-
-})
+ const service = new NetworkFirewallService();
+ await expect(
+ service.updateRuleGroup({
+ UpdateToken: 'error',
+ RuleGroupName: 'test',
+ })
+ ).rejects.toThrowError();
+});
test('Update logging configuration', async () => {
- const service = new NetworkFirewallService()
+ const service = new NetworkFirewallService();
const response = await service.updateLoggingConfiguration('firewallName', {
- LogDestinationConfigs: [{
- LogType: 'ALERT',
- LogDestination: {
- 'bucketName': "network-firewall-automation-solution",
- 'prefix': "alerts"
+ LogDestinationConfigs: [
+ {
+ LogType: 'ALERT',
+ LogDestination: {
+ bucketName: 'network-firewall-automation-solution',
+ prefix: 'alerts',
+ },
+ LogDestinationType: 'S3',
},
- LogDestinationType: 'S3'
- }]
- })
- expect(response).toStrictEqual({"LoggingConfiguration":{"LogDestinationConfigs":[{"LogType":"ALERT","LogDestination":{"bucketName":"network-firewall-automation-solution","prefix":"alerts"},"LogDestinationType":"S3"}]}})
-})
+ ],
+ });
+ expect(response).toStrictEqual({
+ LoggingConfiguration: {
+ LogDestinationConfigs: [
+ {
+ LogType: 'ALERT',
+ LogDestination: { bucketName: 'network-firewall-automation-solution', prefix: 'alerts' },
+ LogDestinationType: 'S3',
+ },
+ ],
+ },
+ });
+});
test('List rule groups for firewall Policy', async () => {
- const service = new NetworkFirewallService()
- await expect(service.listRuleGroupsForPolicy('FirewallName')).resolves.toBeDefined()
-})
+ const service = new NetworkFirewallService();
+ await expect(service.listRuleGroupsForPolicy('FirewallName')).resolves.toBeDefined();
+});
test('delete rule Group', async () => {
- const service = new NetworkFirewallService()
- await expect(service.deleteRuleGroup('')).resolves.toBeUndefined()
-})
+ const service = new NetworkFirewallService();
+ await expect(service.deleteRuleGroup('')).resolves.toBeUndefined();
+});
test('associate firewall policy', async () => {
-
const service = new NetworkFirewallService();
- await expect(service.associateFirewallPolicy({
- FirewallPolicyArn: '',
- FirewallName: ''
- })).resolves.toBeDefined();
-
-})
+ await expect(
+ service.associateFirewallPolicy({
+ FirewallPolicyArn: '',
+ FirewallName: '',
+ })
+ ).resolves.toBeDefined();
+});
test('associate firewall policy error response', async () => {
-
const service = new NetworkFirewallService();
- await expect(service.associateFirewallPolicy({
- FirewallPolicyArn: '',
- FirewallName: 'error'
- })).rejects.toBeDefined();
-
-})
+ await expect(
+ service.associateFirewallPolicy({
+ FirewallPolicyArn: '',
+ FirewallName: 'error',
+ })
+ ).rejects.toBeDefined();
+});
test('update firewall description.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallDescription({
- Description: '',
- FirewallName: ''
- })).resolves.toBeDefined();
-
-})
+ await expect(
+ service.updateFirewallDescription({
+ Description: '',
+ FirewallName: '',
+ })
+ ).resolves.toBeDefined();
+});
test('associate firewall description error response', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallDescription({
- Description: '',
- FirewallName: 'error'
- })).rejects.toBeDefined();
-})
+ await expect(
+ service.updateFirewallDescription({
+ Description: '',
+ FirewallName: 'error',
+ })
+ ).rejects.toBeDefined();
+});
test('update firewall deletion protection.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallDeleteProtection({
- DeleteProtection: false,
- FirewallName: ''
- })).resolves.toBeDefined();
-})
+ await expect(
+ service.updateFirewallDeleteProtection({
+ DeleteProtection: false,
+ FirewallName: '',
+ })
+ ).resolves.toBeDefined();
+});
test('associate firewall deletion protection error response', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallDeleteProtection({
- DeleteProtection: false,
- FirewallName: 'error'
- })).rejects.toBeDefined();
-})
+ await expect(
+ service.updateFirewallDeleteProtection({
+ DeleteProtection: false,
+ FirewallName: 'error',
+ })
+ ).rejects.toBeDefined();
+});
test('update firewall policy change protection.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallPolicyChangeProtection({
- FirewallPolicyChangeProtection: false,
- FirewallName: ''
- })).resolves.toBeDefined();
-})
+ await expect(
+ service.updateFirewallPolicyChangeProtection({
+ FirewallPolicyChangeProtection: false,
+ FirewallName: '',
+ })
+ ).resolves.toBeDefined();
+});
test('update firewall policy change protection error response.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateFirewallPolicyChangeProtection({
- FirewallPolicyChangeProtection: false,
- FirewallName: 'error'
- })).rejects.toBeDefined();
-})
+ await expect(
+ service.updateFirewallPolicyChangeProtection({
+ FirewallPolicyChangeProtection: false,
+ FirewallName: 'error',
+ })
+ ).rejects.toBeDefined();
+});
test('update subnet change protection.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateSubnetChangeProtection({
- SubnetChangeProtection: false,
- FirewallName: ''
- })).resolves.toBeDefined();
-})
+ await expect(
+ service.updateSubnetChangeProtection({
+ SubnetChangeProtection: false,
+ FirewallName: '',
+ })
+ ).resolves.toBeDefined();
+});
test('update subnet change protection error response.', async () => {
const service = new NetworkFirewallService();
- await expect(service.updateSubnetChangeProtection({
- SubnetChangeProtection: false,
- FirewallName: 'error'
- })).rejects.toBeDefined();
-})
\ No newline at end of file
+ await expect(
+ service.updateSubnetChangeProtection({
+ SubnetChangeProtection: false,
+ FirewallName: 'error',
+ })
+ ).rejects.toBeDefined();
+});
diff --git a/source/networkFirewallAutomation/__tests__/send-metrics.spec.ts b/source/networkFirewallAutomation/__tests__/send-metrics.spec.ts
index f4a38f4..2728c66 100644
--- a/source/networkFirewallAutomation/__tests__/send-metrics.spec.ts
+++ b/source/networkFirewallAutomation/__tests__/send-metrics.spec.ts
@@ -1,74 +1,73 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { MetricsManager } from "../lib/common/send-metrics"
+import { MetricsManager } from '../lib/common/send-metrics';
-jest.mock("aws-sdk", () => {
+jest.mock(
+ 'aws-sdk',
+ () => {
return {
- __esModule: true,
- SSM: jest.fn().mockReturnValue({
- getParameter: jest.fn().mockImplementation((data) => {
- expect(data).toStrictEqual({ Name: 'network-firewall-solution-uuid-asds' })
- if ('network-firewall-solution-uuid-asds' === data["Name"]) {
- return {
- promise: jest.fn().mockReturnValue({
- Parameter: {
- Value: '5d358dfa-bc71-4a48-a00c-0931e8ec1456'
- }
- })
- }
- } else {
- return {
- promise: jest.fn().mockReturnValue({
-
- })
- }
- }
- })
- })
- }
-}, { virtual: true });
+ __esModule: true,
+ SSM: jest.fn().mockReturnValue({
+ getParameter: jest.fn().mockImplementation(data => {
+ expect(data).toStrictEqual({ Name: 'network-firewall-solution-uuid-asds' });
+ if ('network-firewall-solution-uuid-asds' === data['Name']) {
+ return {
+ promise: jest.fn().mockReturnValue({
+ Parameter: {
+ Value: '5d358dfa-bc71-4a48-a00c-0931e8ec1456',
+ },
+ }),
+ };
+ } else {
+ return {
+ promise: jest.fn().mockReturnValue({}),
+ };
+ }
+ }),
+ }),
+ };
+ },
+ { virtual: true }
+);
-jest.mock("uuid", () => {
+jest.mock(
+ 'uuid',
+ () => {
return {
- __esModule: true,
- v4: jest.fn().mockImplementation(() => {
- return '5d358dfa-bc71-4a48-a00c-0931e8ec1456'
- })
- }
-}, { virtual: true });
+ __esModule: true,
+ v4: jest.fn().mockImplementation(() => {
+ return '5d358dfa-bc71-4a48-a00c-0931e8ec1456';
+ }),
+ };
+ },
+ { virtual: true }
+);
-jest.mock("axios", () => {
+jest.mock(
+ 'axios',
+ () => {
return {
- __esModule: true,
- post: jest.fn().mockImplementation(() => {
- return {
- promise: jest.fn().mockReturnValue({
-
- })
- }
- })
- }
-}, { virtual: true });
+ __esModule: true,
+ post: jest.fn().mockImplementation(() => {
+ return {
+ promise: jest.fn().mockReturnValue({}),
+ };
+ }),
+ };
+ },
+ { virtual: true }
+);
test('test sending the metrics when the uuid is already in the parameter store.', async () => {
- process.env.STACK_ID = 'asds'
- process.env.SEND_ANONYMOUS_METRICS = 'Yes'
- await MetricsManager.sendMetrics({
- numberOfFirewalls: 1,
- numberOfPolicies: 1,
- numberOfStatefulRuleGroups: 1,
- numberOfStatelessRuleGroups: 1,
- numberOfSuricataRules: 0
- })
-})
-
+ process.env.STACK_ID = 'asds';
+ process.env.SEND_ANONYMOUS_METRICS = 'Yes';
+ await MetricsManager.sendMetrics({
+ numberOfFirewalls: 1,
+ numberOfPolicies: 1,
+ numberOfStatefulRuleGroups: 1,
+ numberOfStatelessRuleGroups: 1,
+ numberOfSuricataRules: 0,
+ });
+});
diff --git a/source/networkFirewallAutomation/__tests__/stringManipulation.spec.ts b/source/networkFirewallAutomation/__tests__/stringManipulation.spec.ts
index 743b503..ee08200 100644
--- a/source/networkFirewallAutomation/__tests__/stringManipulation.spec.ts
+++ b/source/networkFirewallAutomation/__tests__/stringManipulation.spec.ts
@@ -1,32 +1,25 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
import { StringUtils, Name } from '../lib/common/stringUtils';
-const stackId = 'f449b250-b969-11e0-a185-5081d0136786'
+const stackId = 'f449b250-b969-11e0-a185-5081d0136786';
test('test resource name less than 128 chars', async () => {
- const resourceName = 'Firewall-1'
- const stringMod = new StringUtils(stackId)
- const customName = stringMod.getUniqueResourceName(resourceName)
- console.log(customName)
- expect(customName.length < Name.maxCharacters)
-})
+ const resourceName = 'Firewall-1';
+ const stringMod = new StringUtils(stackId);
+ const customName = stringMod.getUniqueResourceName(resourceName);
+ console.log(customName);
+ expect(customName.length < Name.maxCharacters);
+});
test('test resource name more than 128 chars', async () => {
- const resourceName = 'Firewall-1-f449b250-b969-11e0-a185-5081d0136786-f449b250-b969-11e0-a185-5081d0136786-f449b250-b969-11e0-a185-9-11e0-a185-5081d0136786-f449b250-b969-11e0-a185'
- const stringMod = new StringUtils(stackId)
- const customName = stringMod.getUniqueResourceName(resourceName)
- console.log(customName)
- expect(customName.length == Name.maxCharacters)
-})
+ const resourceName =
+ 'Firewall-1-f449b250-b969-11e0-a185-5081d0136786-f449b250-b969-11e0-a185-5081d0136786-f449b250-b969-11e0-a185-9-11e0-a185-5081d0136786-f449b250-b969-11e0-a185';
+ const stringMod = new StringUtils(stackId);
+ const customName = stringMod.getUniqueResourceName(resourceName);
+ console.log(customName);
+ expect(customName.length == Name.maxCharacters);
+});
diff --git a/source/networkFirewallAutomation/build.ts b/source/networkFirewallAutomation/build.ts
index 59a0817..e846987 100644
--- a/source/networkFirewallAutomation/build.ts
+++ b/source/networkFirewallAutomation/build.ts
@@ -1,27 +1,18 @@
-
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { FirewallConfigValidation } from "./lib/common/firewall-config-validation"
-import { Logger, LOG_LEVEL } from "./lib/common/logger";
+import { FirewallConfigValidation } from './lib/common/firewall-config-validation';
+import { Logger, LOG_LEVEL } from './lib/common/logger';
async function main() {
- try {
- const firewallConfigValidation = new FirewallConfigValidation()
- await firewallConfigValidation.execute();
- } catch(error) {
- Logger.log(LOG_LEVEL.ERROR, `Error in firewall config validation`, error)
- process.exit(1)
- }
+ try {
+ const firewallConfigValidation = new FirewallConfigValidation();
+ await firewallConfigValidation.validate();
+ } catch (error) {
+ Logger.log(LOG_LEVEL.ERROR, `Error in firewall config validation`, error);
+ process.exit(1);
+ }
}
-main();
\ No newline at end of file
+main();
diff --git a/source/networkFirewallAutomation/index.ts b/source/networkFirewallAutomation/index.ts
index 49c47bb..993a3a7 100644
--- a/source/networkFirewallAutomation/index.ts
+++ b/source/networkFirewallAutomation/index.ts
@@ -1,88 +1,78 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
/**
* @description
- * AWS Network Firewall Manager Solution
+ * Firewall Automation for Network Traffic on AWS
* @author aws-solutions
*/
-import {
- EnvironmentProps,
- NetworkFirewallManager
-} from "./lib/network-firewall-manager"
-import {
- Ec2EnvironmentProps,
- Ec2Manager
-} from "./lib/ec2-manager"
-import { ConfigReader, ConfigPath } from "./lib/common/configReader/config-reader"
-import { Logger, LOG_LEVEL } from "./lib/common/logger"
-
+import { EnvironmentProps, NetworkFirewallManager } from './lib/network-firewall-manager';
+import { Ec2EnvironmentProps, Ec2Manager } from './lib/ec2-manager';
+import { ConfigReader, ConfigPath } from './lib/common/configReader/config-reader';
+import { Logger, LOG_LEVEL } from './lib/common/logger';
async function firewallManager() {
-
// declare environment variables
let envProps: EnvironmentProps = {
vpcId: process.env.VPC_ID,
subnetIds: process.env.SUBNET_IDS,
logDestinationType: process.env.LOG_DESTINATION_TYPE, //S3 or CloudWatchLogs
- logDestination: process.env.S3_LOG_BUCKET_NAME !== 'NotConfigured' ? process.env.S3_LOG_BUCKET_NAME : process.env.CLOUDWATCH_LOG_GROUP_NAME, //S3 bucket name or CloudWatchLogs group name
+ logDestination:
+ process.env.S3_LOG_BUCKET_NAME !== 'NotConfigured'
+ ? process.env.S3_LOG_BUCKET_NAME
+ : process.env.CLOUDWATCH_LOG_GROUP_NAME, //S3 bucket name or CloudWatchLogs group name
logType: process.env.LOG_TYPE, //ALERT OR FLOW
logRetentionPeriod: process.env.LOG_RETENTION_IN_DAYS,
- stackId: process.env.STACK_ID ? process.env.STACK_ID : ""
- }
+ stackId: process.env.STACK_ID ? process.env.STACK_ID : '',
+ };
- const transitGatewayAttachmentId = process.env.TRANSIT_GATEWAY_ATTACHMENT_ID ? process.env.TRANSIT_GATEWAY_ATTACHMENT_ID : "";
- const applianceMode = process.env.TRANSIT_GATEWAY_ATTACHMENT_APPLIANCE_MODE ? process.env.TRANSIT_GATEWAY_ATTACHMENT_APPLIANCE_MODE : "enable";
+ const transitGatewayAttachmentId = process.env.TRANSIT_GATEWAY_ATTACHMENT_ID
+ ? process.env.TRANSIT_GATEWAY_ATTACHMENT_ID
+ : '';
+ const applianceMode = process.env.TRANSIT_GATEWAY_ATTACHMENT_APPLIANCE_MODE
+ ? process.env.TRANSIT_GATEWAY_ATTACHMENT_APPLIANCE_MODE
+ : 'enable';
Ec2Manager.updateTransitGatewayAttachementApplianceMode(transitGatewayAttachmentId, applianceMode);
-
let ec2EnvProps: Ec2EnvironmentProps[] = [
{
- availabilityZone: process.env.VPC_TGW_ATTACHMENT_AZ_1,
- routeTableId: process.env.VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_1
+ availabilityZone: process.env.VPC_TGW_ATTACHMENT_AZ_1,
+ routeTableId: process.env.VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_1,
},
{
availabilityZone: process.env.VPC_TGW_ATTACHMENT_AZ_2,
- routeTableId: process.env.VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_2
- }]
+ routeTableId: process.env.VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_2,
+ },
+ ];
try {
- const currentPath = process.cwd()
- const directoryPath = currentPath.concat(ConfigPath.firewallDirectory)
+ const currentPath = process.cwd();
+ const directoryPath = currentPath.concat(ConfigPath.firewallDirectory);
- const fileHandler = new ConfigReader()
- const firewallFiles = fileHandler.getJSONFileNames(directoryPath)
+ const fileHandler = new ConfigReader();
+ const firewallFiles = fileHandler.getJSONFileNames(directoryPath);
for (let filePath of firewallFiles) {
-
- Logger.log(LOG_LEVEL.INFO, `Processing ${filePath}`)
- let firewallObject = fileHandler.convertFileToObject(filePath)
- Logger.log(LOG_LEVEL.INFO, firewallObject)
- let firewallMgr = new NetworkFirewallManager(envProps, firewallObject, fileHandler)
- const syncStates = await firewallMgr.firewallOperations()
- Logger.log(LOG_LEVEL.INFO, syncStates)
- Logger.log(LOG_LEVEL.INFO, `Creating route to firewall endpoint.`)
+ Logger.log(LOG_LEVEL.INFO, `Processing ${filePath}`);
+ let firewallObject = fileHandler.convertFileToObject(filePath);
+ Logger.log(LOG_LEVEL.INFO, firewallObject);
+ let firewallMgr = new NetworkFirewallManager(envProps, firewallObject, fileHandler);
+ const syncStates = await firewallMgr.firewallOperations();
+ Logger.log(LOG_LEVEL.INFO, syncStates);
+ Logger.log(LOG_LEVEL.INFO, `Creating route to firewall endpoint.`);
if (syncStates) {
- const ec2Mgr = new Ec2Manager(ec2EnvProps, syncStates)
- await ec2Mgr.routeTableOperations()
+ const ec2Mgr = new Ec2Manager(ec2EnvProps, syncStates);
+ await ec2Mgr.routeTableOperations();
}
}
} catch (error) {
- Logger.log(LOG_LEVEL.ERROR, `Failed to deploy/update Network Firewall`, error)
- process.exit(1)
+ Logger.log(LOG_LEVEL.ERROR, `Failed to deploy/update Network Firewall`, error);
+ process.exit(1);
}
}
// Initiating Network Firewall Manager Solution
-firewallManager()
\ No newline at end of file
+firewallManager();
diff --git a/source/networkFirewallAutomation/jest.config.js b/source/networkFirewallAutomation/jest.config.js
index 43ca25f..fc18292 100644
--- a/source/networkFirewallAutomation/jest.config.js
+++ b/source/networkFirewallAutomation/jest.config.js
@@ -1,14 +1,39 @@
-module.exports = {
- "roots": [
- "/__tests__"
- ],
- testMatch: [ '**/*.spec.ts', '**/*.test.ts'],
- "transform": {
- "^.+\\.tsx?$": "ts-jest"
- },
- coverageReporters: [
- "text",
- ["lcov", {"projectRoot": "../../"}]
- ],
- testTimeout: 30000
- }
+'use strict';
+Object.defineProperty(exports, '__esModule', { value: true });
+const config = {
+ clearMocks: false,
+ collectCoverage: true,
+ // The directory where Jest should output its coverage files
+ coverageDirectory: 'coverage',
+ // An array of regexp pattern strings used to skip coverage collection
+ coveragePathIgnorePatterns: ['/node_modules/'],
+ // An array of directory names to be searched recursively up from the requiring module's location
+ moduleDirectories: ['node_modules'],
+ // An array of file extensions your modules use
+ moduleFileExtensions: ['ts', 'json', 'jsx', 'js', 'tsx', 'node'],
+ // Automatically reset mock state between every test
+ resetMocks: false,
+ // The glob patterns Jest uses to detect test files
+ testMatch: ['**/?(*.)+(spec|test).[t]s?(x)'],
+ // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
+ testPathIgnorePatterns: ['/node_modules/'],
+ // A map from regular expressions to paths to transformers
+ transform: {
+ '^.+\\.(t)sx?$': 'ts-jest',
+ },
+ // Indicates whether each individual test should be reported during the run
+ verbose: false,
+ // An array of glob patterns indicating a set of files for which coverage information should be collected
+ collectCoverageFrom: [
+ '**/*.ts',
+ '!**/*.d.ts',
+ '!**/*.spec.ts',
+ '!./bin/network-firewall-auto-solution.ts',
+ '!./build.ts',
+ '!./index.ts',
+ ],
+ coverageReporters: [['lcov', { projectRoot: '../' }], 'text'],
+ rootDir: './',
+ testTimeout: 30000,
+};
+exports.default = config;
diff --git a/source/networkFirewallAutomation/lib/common/configReader/config-reader.ts b/source/networkFirewallAutomation/lib/common/configReader/config-reader.ts
index 488ae6d..2dfdf08 100644
--- a/source/networkFirewallAutomation/lib/common/configReader/config-reader.ts
+++ b/source/networkFirewallAutomation/lib/common/configReader/config-reader.ts
@@ -1,37 +1,29 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import * as fs from 'fs'
-import * as path from 'path'
-import { Logger, LOG_LEVEL } from '../logger'
+import * as fs from 'fs';
+import * as path from 'path';
+import { Logger, LOG_LEVEL } from '../logger';
export enum ConfigPath {
- firewallDirectory = '/firewalls'
+ firewallDirectory = '/firewalls',
}
/**
- * @description This class reads the json files and return file objects
- */
+ * @description This class reads the json files and return file objects
+ */
export class ConfigReader {
-
- /**
- * @description This method will return the json file names in the path.
- * @param directoryPath string value of the file system path.
- * @returns Array of file names.
- */
+ /**
+ * @description This method will return the json file names in the path.
+ * @param directoryPath string value of the file system path.
+ * @returns Array of file names.
+ */
getJSONFileNames(directoryPath: string): string[] {
- Logger.log(LOG_LEVEL.DEBUG, `Config directory path: ${directoryPath}`)
- return fs.readdirSync(directoryPath)
+ Logger.log(LOG_LEVEL.DEBUG, `Config directory path: ${directoryPath}`);
+ return fs
+ .readdirSync(directoryPath)
.filter((name: any) => path.extname(name) === '.json')
- .map((name: any) => (path.join(directoryPath, name)))
+ .map((name: any) => path.join(directoryPath, name));
}
/**
@@ -40,8 +32,8 @@ export class ConfigReader {
* @param filePath string value of absolute file path.
*/
convertFileToObject(filePath: string): any {
- Logger.log(LOG_LEVEL.DEBUG, `Returning object for file: ${filePath}`)
- return JSON.parse(fs.readFileSync(filePath).toString())
+ Logger.log(LOG_LEVEL.DEBUG, `Returning object for file: ${filePath}`);
+ return JSON.parse(fs.readFileSync(filePath).toString());
}
/**
@@ -51,13 +43,12 @@ export class ConfigReader {
* @param filePath string value of absolute file path.
*/
copyFileContentToString(filePath: string): any {
- Logger.log(LOG_LEVEL.DEBUG, `Returning string content for file: ${filePath}`)
+ Logger.log(LOG_LEVEL.DEBUG, `Returning string content for file: ${filePath}`);
try {
- return fs.readFileSync(filePath).toString()
- } catch(error) {
- Logger.log(LOG_LEVEL.DEBUG, `Error converting the file content to string:`, error)
- return "";
+ return fs.readFileSync(filePath).toString();
+ } catch (error) {
+ Logger.log(LOG_LEVEL.DEBUG, `Error converting the file content to string:`, error);
+ return '';
}
}
-
-}
\ No newline at end of file
+}
diff --git a/source/networkFirewallAutomation/lib/common/firewall-config-validation.ts b/source/networkFirewallAutomation/lib/common/firewall-config-validation.ts
index 15be7fa..3023641 100644
--- a/source/networkFirewallAutomation/lib/common/firewall-config-validation.ts
+++ b/source/networkFirewallAutomation/lib/common/firewall-config-validation.ts
@@ -1,214 +1,241 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { NetworkFirewall } from "aws-sdk";
-import { Logger, LOG_LEVEL } from "./logger";
-import { ConfigReader, ConfigPath } from "./configReader/config-reader";
-import { MetricsManager, NetworkFirewallMetrics } from "./send-metrics";
+import { NetworkFirewall } from 'aws-sdk';
+import { Logger, LOG_LEVEL } from './logger';
+import { ConfigReader, ConfigPath } from './configReader/config-reader';
+import { MetricsManager, NetworkFirewallMetrics } from './send-metrics';
interface InvalidConfigFiles {
- path: string;
- referencedInFile?: any;
- error?: any;
+ path: string;
+ referencedInFile?: any;
+ error?: any;
}
export class FirewallConfigValidation {
+ private invalidFiles: InvalidConfigFiles[];
+ private service: NetworkFirewall;
+ private fileHandler: ConfigReader;
- private invalidFiles: InvalidConfigFiles[];
- private service: NetworkFirewall;
- private fileHandler: ConfigReader;
+ constructor() {
+ this.invalidFiles = [];
+ this.service = new NetworkFirewall({
+ customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
+ });
+ this.fileHandler = new ConfigReader();
+ }
- constructor() {
- this.invalidFiles = []
- this.service = new NetworkFirewall()
- this.fileHandler = new ConfigReader()
+ getInvalidFiles() {
+ return this.invalidFiles;
+ }
+
+ /**
+ * This method will validate all the files in starting with firewall, firewall policy and rule groups, all the invalid
+ * files will be output to the console and an error is thrown,
+ * if there no invalid files the validation will exit without any error.
+ * @param rootDir optional if the value is not provided the path configured in the ConfigPath is taken as directory.
+ */
+ async validate(rootDir: string = ConfigPath.firewallDirectory) {
+ const metrics: NetworkFirewallMetrics = {
+ numberOfFirewalls: 0,
+ numberOfPolicies: 0,
+ numberOfStatefulRuleGroups: 0,
+ numberOfStatelessRuleGroups: 0,
+ numberOfSuricataRules: 0,
+ };
+
+ Logger.log(LOG_LEVEL.INFO, `Starting firewall config validation`);
+ try {
+ const currentPath = process.cwd();
+ let directoryPath = currentPath.concat(rootDir);
+ Logger.log(LOG_LEVEL.INFO, `Config file path ${directoryPath}`);
+
+ const firewallFiles = this.fileHandler.getJSONFileNames(directoryPath);
+ metrics.numberOfFirewalls = firewallFiles.length;
+
+ for (let firewallFile of firewallFiles) {
+ await this.validateFirewallFile(firewallFile, metrics);
+ }
+ } catch (error) {
+ Logger.log(LOG_LEVEL.ERROR, error);
+ throw new Error('Validation failed.');
}
- getInvalidFiles() {
- return this.invalidFiles
+ this.checkInvalidFiles();
+
+ Logger.log(LOG_LEVEL.DEBUG, `Send metrics`, metrics);
+ await MetricsManager.sendMetrics(metrics);
+ }
+
+ private async validateFirewallFile(firewallFile: string, metrics: NetworkFirewallMetrics) {
+ Logger.log(LOG_LEVEL.INFO, `Validating the file paths for the firewall file named: ${firewallFile}`);
+ let firewall: NetworkFirewall.Types.CreateFirewallRequest = this.fileHandler.convertFileToObject(firewallFile);
+
+ this.validateFirewallFileNameAndArn(firewall);
+
+ let firewallPolicy: NetworkFirewall.Types.CreateFirewallPolicyRequest;
+
+ //verify firewall policy.
+ try {
+ firewallPolicy = this.fileHandler.convertFileToObject(firewall.FirewallPolicyArn);
+ metrics.numberOfPolicies += 1;
+ await this.validateFirewallPolicyFile(firewallPolicy, firewall.FirewallPolicyArn);
+
+ await this.validateFirewallPolicyStatefulRuleGroups(firewallPolicy, metrics, firewall);
+ await this.validateFirewallPolicyStatelessRuleGroups(firewallPolicy, metrics, firewall);
+ } catch (error) {
+ Logger.log(LOG_LEVEL.INFO, `Failed to validate the firewall policy`);
+ this.invalidFiles.push({
+ path: firewall.FirewallPolicyArn,
+ referencedInFile: firewall.FirewallPolicyArn,
+ error: 'The file in the attribute path is not available in the configuration.',
+ });
}
+ }
- /**
- * This method will validate all the files in starting with firewall, firewall policy and rule groups, all the invalid
- * files will be output to the console and an error is thrown,
- * if there no invalid files the validation will exit without any error.
- * @param rootDir optional if the value is not provided the path configured in the ConfigPath is taken as directory.
- */
- async execute(rootDir?: string) {
- const metrics: NetworkFirewallMetrics = {
- numberOfFirewalls: 0,
- numberOfPolicies: 0,
- numberOfStatefulRuleGroups: 0,
- numberOfStatelessRuleGroups: 0,
- numberOfSuricataRules: 0
- }
- Logger.log(LOG_LEVEL.INFO, `Starting firewall config validation`)
- try {
- const currentPath = process.cwd()
- let directoryPath;
- if (rootDir) {
- directoryPath = currentPath.concat(rootDir)
- } else {
- directoryPath = currentPath.concat(ConfigPath.firewallDirectory)
- }
- Logger.log(LOG_LEVEL.INFO, `Config file path ${directoryPath}`)
- const firewallFiles = this.fileHandler.getJSONFileNames(directoryPath)
- metrics.numberOfFirewalls = firewallFiles.length
-
- for (let firewallFile of firewallFiles) {
- Logger.log(LOG_LEVEL.INFO, `Validating the file paths for the firewall file named: ${firewallFile}`)
- let firewall: NetworkFirewall.Types.CreateFirewallRequest = this.fileHandler.convertFileToObject(firewallFile)
-
- this.validateFirewallFile(firewall)
-
- let firewallPolicy: NetworkFirewall.Types.CreateFirewallPolicyRequest;
-
- //verify firewall policy.
- try {
- firewallPolicy = this.fileHandler.convertFileToObject(firewall.FirewallPolicyArn)
- metrics.numberOfPolicies += 1
- await this.validateFirewallPolicyFile(firewallPolicy, firewall.FirewallPolicyArn)
- } catch (error) {
- Logger.log(LOG_LEVEL.INFO, `Failed to validate the firewall policy`)
- this.invalidFiles.push({
- path: firewall.FirewallPolicyArn,
- referencedInFile: firewall.FirewallPolicyArn,
- error: "The file in the attribute path is not available in the configuration."
- })
- break;
- }
-
- //loop through all the stateful rule groups and verify if the files compile to a valid json object.
- if (firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences) {
- metrics.numberOfStatefulRuleGroups += firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences.length
- Logger.log(LOG_LEVEL.DEBUG, `Firewall Policy StatefulRuleGroupReferences`, firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences)
- for (let statefulRuleGroup of firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences) {
- try {
- const ruleGroup: NetworkFirewall.Types.CreateRuleGroupRequest = this.fileHandler.convertFileToObject(statefulRuleGroup.ResourceArn);
- if (ruleGroup.Rules) {
- metrics.numberOfSuricataRules += 1;
- }
- await this.validateRuleGroupFile(ruleGroup, statefulRuleGroup.ResourceArn)
- } catch (error) {
- this.invalidFiles.push({
- path: statefulRuleGroup.ResourceArn,
- referencedInFile: firewall.FirewallPolicyArn,
- error: "The file in the attribute path is not available in the configuration."
- })
- }
- }
- }
- //loop through all the stateless rule groups and verify if the files compile to a valid json object.
- if (firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences) {
- metrics.numberOfStatelessRuleGroups += firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences.length
- Logger.log(LOG_LEVEL.DEBUG, `Firewall Policy StatelessRuleGroupReferences`, firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences)
- for (let statelessRuleGroup of firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences) {
- try {
- const ruleGroup = this.fileHandler.convertFileToObject(statelessRuleGroup.ResourceArn)
- await this.validateRuleGroupFile(ruleGroup, statelessRuleGroup.ResourceArn)
- } catch (error) {
- this.invalidFiles.push({
- path: statelessRuleGroup.ResourceArn,
- referencedInFile: firewall.FirewallPolicyArn,
- error: "The file in the attribute path is not available in the configuration."
- })
- }
- }
- }
- }
-
- } catch (error) {
- Logger.log(LOG_LEVEL.ERROR, error)
- throw new Error("Validation failed.");
- } finally {
- Logger.log(LOG_LEVEL.INFO, `Number of invalid files: ${this.invalidFiles.length}`)
- Logger.log(LOG_LEVEL.INFO, `-----------INVALID FILES START-----------`)
- this.getInvalidFiles().forEach((invalidFile) => {
- Logger.log(LOG_LEVEL.ERROR, invalidFile)
- })
- Logger.log(LOG_LEVEL.INFO, `-----------INVALID FILES END--------------`)
- if (this.invalidFiles.length > 0) {
- const error = "Validation failed."
- Logger.log(LOG_LEVEL.ERROR, error)
- throw error
- }
- Logger.log(LOG_LEVEL.DEBUG, `Send metrics`, metrics)
- MetricsManager.sendMetrics(metrics)
- }
+ private async validateFirewallPolicyStatefulRuleGroups(
+ firewallPolicy: NetworkFirewall.CreateFirewallPolicyRequest,
+ metrics: NetworkFirewallMetrics,
+ firewall: NetworkFirewall.CreateFirewallRequest
+ ) {
+ if (!firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences) {
+ return;
}
- async validateFirewallPolicyFile(firewallPolicy: NetworkFirewall.Types.CreateFirewallPolicyRequest, path: string) {
- firewallPolicy.DryRun = true;
- let response;
- try {
- response = await this.service.createFirewallPolicy(firewallPolicy).promise()
- } catch (error) {
- const errorCode: string = error["code"]
- Logger.log(LOG_LEVEL.DEBUG, `Error response from the create firewall policy dry run API`, error)
- if (errorCode === "MultipleValidationErrors" || errorCode === "UnexpectedParameter") {
- this.invalidFiles.push({
- path: path,
- error: error["message"]
- })
- }
+ metrics.numberOfStatefulRuleGroups += firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences.length;
+ Logger.log(
+ LOG_LEVEL.DEBUG,
+ `Firewall Policy StatefulRuleGroupReferences`,
+ firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences
+ );
+ for (let statefulRuleGroup of firewallPolicy.FirewallPolicy.StatefulRuleGroupReferences) {
+ try {
+ const ruleGroup: NetworkFirewall.Types.CreateRuleGroupRequest = this.fileHandler.convertFileToObject(
+ statefulRuleGroup.ResourceArn
+ );
+ if (ruleGroup.Rules) {
+ metrics.numberOfSuricataRules += 1;
}
- Logger.log(LOG_LEVEL.DEBUG, `Response from the create firewall policy dry run API`, response)
+ await this.validateRuleGroupFile(ruleGroup, statefulRuleGroup.ResourceArn);
+ } catch (error) {
+ this.invalidFiles.push({
+ path: statefulRuleGroup.ResourceArn,
+ referencedInFile: firewall.FirewallPolicyArn,
+ error: 'The file in the attribute path is not available in the configuration.',
+ });
+ }
}
- async validateRuleGroupFile(ruleGroup: NetworkFirewall.Types.CreateRuleGroupRequest, path: string) {
- //add code to check if this rule source is provided or rules file is being provided
- if (ruleGroup.Rules && ruleGroup.RuleGroup) {
- Logger.log(LOG_LEVEL.DEBUG, `Rule Group file has both Rules and RuleGroup fields.`, ruleGroup)
- this.invalidFiles.push({
- path: path,
- error: "Both RuleGroup and Rules have data, You must provide either the rule group setting or a Rules setting, but not both. "
- })
- return;
- } else if (ruleGroup.Rules) {
- const ruleString = this.fileHandler.copyFileContentToString(ruleGroup.Rules)
- if (!ruleString) {
- ruleGroup.Rules = ruleString
- this.invalidFiles.push({
- path: path,
- error: "Rules attribute has invalid file path. " + ruleGroup.Rules
- })
- }
- Logger.log(LOG_LEVEL.DEBUG, `Rule Group file has both Rules and RuleGroup fields.`, ruleGroup.Rules)
- }
+ }
- ruleGroup.DryRun = true;
- let response;
- try {
- response = await this.service.createRuleGroup(ruleGroup).promise();
- } catch(error) {
- Logger.log(LOG_LEVEL.DEBUG, `Error response from the create rule group dry run API`, error)
- const errorCode: string = error["code"]
- if (errorCode === "MultipleValidationErrors" || errorCode === "UnexpectedParameter") {
- this.invalidFiles.push({
- path: path,
- error: error["message"]
- })
- }
- }
- Logger.log(LOG_LEVEL.DEBUG, `Response from the create rule group dry run API`, response)
+ private async validateFirewallPolicyStatelessRuleGroups(
+ firewallPolicy: NetworkFirewall.CreateFirewallPolicyRequest,
+ metrics: NetworkFirewallMetrics,
+ firewall: NetworkFirewall.CreateFirewallRequest
+ ) {
+ if (!firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences) {
+ return;
}
- validateFirewallFile(firewall: NetworkFirewall.Types.CreateFirewallRequest) {
- if (!firewall.FirewallName || !firewall.FirewallPolicyArn) {
- this.invalidFiles.push({
- path: firewall.FirewallName,
- referencedInFile: firewall.FirewallName,
- error: "FirewallName and FirewallPolicyArn are required in the firewall."
- })
- }
- }
-}
\ No newline at end of file
+ metrics.numberOfStatelessRuleGroups += firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences.length;
+ Logger.log(
+ LOG_LEVEL.DEBUG,
+ `Firewall Policy StatelessRuleGroupReferences`,
+ firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences
+ );
+ for (let statelessRuleGroup of firewallPolicy.FirewallPolicy.StatelessRuleGroupReferences) {
+ try {
+ const ruleGroup = this.fileHandler.convertFileToObject(statelessRuleGroup.ResourceArn);
+ await this.validateRuleGroupFile(ruleGroup, statelessRuleGroup.ResourceArn);
+ } catch (error) {
+ this.invalidFiles.push({
+ path: statelessRuleGroup.ResourceArn,
+ referencedInFile: firewall.FirewallPolicyArn,
+ error: 'The file in the attribute path is not available in the configuration.',
+ });
+ }
+ }
+ }
+
+ private checkInvalidFiles() {
+ Logger.log(LOG_LEVEL.INFO, `Number of invalid files: ${this.invalidFiles.length}`);
+ Logger.log(LOG_LEVEL.INFO, `-----------INVALID FILES START-----------`);
+ this.getInvalidFiles().forEach(invalidFile => {
+ Logger.log(LOG_LEVEL.ERROR, invalidFile);
+ });
+ Logger.log(LOG_LEVEL.INFO, `-----------INVALID FILES END--------------`);
+ if (this.invalidFiles.length > 0) {
+ const error = 'Validation failed: Invalid Files.';
+ Logger.log(LOG_LEVEL.ERROR, error);
+ throw new Error(error);
+ }
+ }
+
+ async validateFirewallPolicyFile(firewallPolicy: NetworkFirewall.Types.CreateFirewallPolicyRequest, path: string) {
+ firewallPolicy.DryRun = true;
+ let response;
+ try {
+ response = await this.service.createFirewallPolicy(firewallPolicy).promise();
+ } catch (error: any) {
+ const errorCode: string = error['code'];
+ Logger.log(LOG_LEVEL.DEBUG, `Error response from the create firewall policy dry run API`, error);
+ if (errorCode === 'MultipleValidationErrors' || errorCode === 'UnexpectedParameter') {
+ this.invalidFiles.push({
+ path: path,
+ error: error['message'],
+ });
+ }
+ }
+ Logger.log(LOG_LEVEL.DEBUG, `Response from the create firewall policy dry run API`, response);
+ }
+
+ async validateRuleGroupFile(ruleGroup: NetworkFirewall.Types.CreateRuleGroupRequest, path: string) {
+ //add code to check if this rule source is provided or rules file is being provided
+ if (ruleGroup.Rules && ruleGroup.RuleGroup) {
+ Logger.log(LOG_LEVEL.DEBUG, `Rule Group file has both Rules and RuleGroup fields.`, ruleGroup);
+ this.invalidFiles.push({
+ path: path,
+ error:
+ 'Both RuleGroup and Rules have data, You must provide either the rule group setting or a Rules setting, but not both. ',
+ });
+ return;
+ } else if (ruleGroup.Rules) {
+ const ruleString = this.fileHandler.copyFileContentToString(ruleGroup.Rules);
+ if (!ruleString) {
+ ruleGroup.Rules = ruleString;
+ this.invalidFiles.push({
+ path: path,
+ error: 'Rules attribute has invalid file path. ' + ruleGroup.Rules,
+ });
+ return;
+ }
+ }
+
+ ruleGroup.DryRun = true;
+ let response;
+ try {
+ response = await this.service.createRuleGroup(ruleGroup).promise();
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.DEBUG, `Error response from the create rule group dry run API`, error);
+ const errorCode: string = error['code'];
+ if (errorCode === 'MultipleValidationErrors' || errorCode === 'UnexpectedParameter') {
+ this.invalidFiles.push({
+ path: path,
+ error: error['message'],
+ });
+ }
+ }
+ Logger.log(LOG_LEVEL.DEBUG, `Response from the create rule group dry run API`, response);
+ }
+
+ validateFirewallFileNameAndArn(firewall: NetworkFirewall.Types.CreateFirewallRequest) {
+ if (!firewall.FirewallName || !firewall.FirewallPolicyArn) {
+ this.invalidFiles.push({
+ path: firewall.FirewallName,
+ referencedInFile: firewall.FirewallName,
+ error: 'FirewallName and FirewallPolicyArn are required in the firewall.',
+ });
+ }
+ }
+}
diff --git a/source/networkFirewallAutomation/lib/common/logger.ts b/source/networkFirewallAutomation/lib/common/logger.ts
index f1c69f9..2e21f97 100644
--- a/source/networkFirewallAutomation/lib/common/logger.ts
+++ b/source/networkFirewallAutomation/lib/common/logger.ts
@@ -1,38 +1,32 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
export enum LOG_LEVEL {
- "ERROR",
- "WARN",
- "INFO",
- "DEBUG"
+ 'ERROR',
+ 'WARN',
+ 'INFO',
+ 'DEBUG',
}
export class Logger {
-
- private static readonly CONFIGURED_LOG_LEVEL = process.env.LOG_LEVEL && Object.values(LOG_LEVEL).indexOf(process.env.LOG_LEVEL.toUpperCase()) != -1 ? Object.values(LOG_LEVEL).indexOf(process.env.LOG_LEVEL.toUpperCase()) : LOG_LEVEL.ERROR;
+ private static readonly CONFIGURED_LOG_LEVEL =
+ process.env.LOG_LEVEL && Object.values(LOG_LEVEL).indexOf(process.env.LOG_LEVEL.toUpperCase()) != -1
+ ? Object.values(LOG_LEVEL).indexOf(process.env.LOG_LEVEL.toUpperCase())
+ : LOG_LEVEL.ERROR;
- constructor() { }
-
- static log(log_level: LOG_LEVEL, message: any, object?: any) {
- if (log_level <= this.CONFIGURED_LOG_LEVEL) {
- let currentDateTime = new Date()
- let formatted_date = `${currentDateTime.getFullYear()}-${(currentDateTime.getMinutes()-1)}-${currentDateTime.getDate()} ${currentDateTime.getHours()}:${currentDateTime.getMinutes()}:${currentDateTime.getSeconds()}`
- let log_message = `${formatted_date} : ${JSON.stringify(message, null, 2)}`
- if (object) {
- log_message = `${formatted_date} : ${JSON.stringify(message, null, 2)} : ${JSON.stringify(object, null, 2)}`
- }
- console.log(log_message)
- }
+ static log(log_level: LOG_LEVEL, message: any, object?: any) {
+ if (log_level <= this.CONFIGURED_LOG_LEVEL) {
+ let currentDateTime = new Date();
+ let formatted_date = `${currentDateTime.getFullYear()}-${
+ currentDateTime.getMinutes() - 1
+ }-${currentDateTime.getDate()} ${currentDateTime.getHours()}:${currentDateTime.getMinutes()}:${currentDateTime.getSeconds()}`;
+ let log_message = `${formatted_date} : ${JSON.stringify(message, null, 2)}`;
+ if (object) {
+ log_message = `${formatted_date} : ${JSON.stringify(message, null, 2)} : ${JSON.stringify(object, null, 2)}`;
+ }
+ console.log(log_message);
}
-}
\ No newline at end of file
+ }
+}
diff --git a/source/networkFirewallAutomation/lib/common/send-metrics.ts b/source/networkFirewallAutomation/lib/common/send-metrics.ts
index 527e357..38ea016 100644
--- a/source/networkFirewallAutomation/lib/common/send-metrics.ts
+++ b/source/networkFirewallAutomation/lib/common/send-metrics.ts
@@ -1,80 +1,85 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { v4 as uuidv4 } from "uuid"
-import { SSM } from "aws-sdk"
-import axios from "axios"
-import { Logger, LOG_LEVEL } from "./logger"
+import { v4 as uuidv4 } from 'uuid';
+import { SSM } from 'aws-sdk';
+import axios from 'axios';
+import { Logger, LOG_LEVEL } from './logger';
export interface NetworkFirewallMetrics {
- numberOfFirewalls: number,
- numberOfStatefulRuleGroups: number,
- numberOfStatelessRuleGroups: number,
- numberOfPolicies: number,
- numberOfSuricataRules: number,
- logType?: string
- logDestinationType?: string
+ numberOfFirewalls: number;
+ numberOfStatefulRuleGroups: number;
+ numberOfStatelessRuleGroups: number;
+ numberOfPolicies: number;
+ numberOfSuricataRules: number;
+ logType?: string;
+ logDestinationType?: string;
}
export class MetricsManager {
+ private constructor() { }
- private constructor() { }
-
- static async sendMetrics(data: NetworkFirewallMetrics) {
- const ssmParameterForUUID = process.env.SSM_PARAM_FOR_UUID ? process.env.SSM_PARAM_FOR_UUID : "network-firewall-solution-uuid"
- const stackId = process.env.STACK_ID ? process.env.STACK_ID.slice(process.env.STACK_ID.length - 36) : ""
- const sendAnonymousMetrics = process.env.SEND_ANONYMOUS_METRICS ? process.env.SEND_ANONYMOUS_METRICS : "No"
- let uuid = ""
- const ssmUUIDKey = `${ssmParameterForUUID}-${stackId}`
+ static async sendMetrics(data: NetworkFirewallMetrics) {
+ const ssmParameterForUUID = process.env.SSM_PARAM_FOR_UUID
+ ? process.env.SSM_PARAM_FOR_UUID
+ : 'network-firewall-solution-uuid';
+ const stackId = process.env.STACK_ID ? process.env.STACK_ID.slice(process.env.STACK_ID.length - 36) : '';
+ const sendAnonymousMetrics = process.env.SEND_ANONYMOUS_METRICS ? process.env.SEND_ANONYMOUS_METRICS : 'No';
+ let uuid = '';
+ Logger.log(LOG_LEVEL.DEBUG, `ssm parameter uuid key prefix ${ssmParameterForUUID}`)
+ const ssmUUIDKey = `${ssmParameterForUUID}-${stackId}`;
+ Logger.log(LOG_LEVEL.DEBUG, `ssm parameter uuid key ${ssmUUIDKey}`)
+ try {
+ if (sendAnonymousMetrics.toUpperCase() === 'YES') {
+ let ssmInstance = new SSM({
+ customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
+ });
+ let ssmGetParamResponse;
try {
- if (sendAnonymousMetrics.toUpperCase() === "YES") {
- let ssmInstance = new SSM();
- let ssmGetParamResponse;
- try {
- ssmGetParamResponse = await ssmInstance.getParameter({
- Name: ssmUUIDKey,
- }).promise();
- uuid = ssmGetParamResponse.Parameter?.Value ? ssmGetParamResponse.Parameter?.Value : uuidv4();
- } catch (error) {
- if (error["code"] = "ParameterNotFound") {
- uuid = uuidv4();
- await ssmInstance.putParameter({
- Name: ssmUUIDKey,
- Value: uuid,
- Type: "String"
- }).promise();
- }
- }
- Logger.log(LOG_LEVEL.DEBUG, "uuid: ", uuid)
- const metricsUrl: string = process.env.METRICS_URL ? process.env.METRICS_URL : ""
- const solutionId: string | undefined = process.env.SOLUTION_ID
- const timestamp = (new Date()).toISOString()
- data.logDestinationType = process.env.LOG_DESTINATION_TYPE
- data.logType = process.env.LOG_TYPE
- const metrics_data = {
- 'Solution': solutionId,
- 'TimeStamp': timestamp,
- 'UUID': uuid,
- 'Data': data
- }
- Logger.log(LOG_LEVEL.DEBUG, "metrics data: ", metrics_data)
- const response = await axios.post(metricsUrl, metrics_data, {
- headers: {
- 'Content-Type': 'application/json',
- 'Content-Length': JSON.stringify(data).length
- }
- })
- Logger.log(LOG_LEVEL.DEBUG, 'Response: ', response)
- }
- } catch (error) { }
+ ssmGetParamResponse = await ssmInstance
+ .getParameter({
+ Name: ssmUUIDKey,
+ })
+ .promise();
+ uuid = ssmGetParamResponse.Parameter?.Value ? ssmGetParamResponse.Parameter?.Value : uuidv4();
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.ERROR, "Error while getting the parameter ", error)
+ if (error['code'] === 'ParameterNotFound') {
+ uuid = uuidv4();
+ await ssmInstance
+ .putParameter({
+ Name: ssmUUIDKey,
+ Value: uuid,
+ Type: 'String',
+ })
+ .promise();
+ }
+ }
+ Logger.log(LOG_LEVEL.DEBUG, 'uuid: ', uuid);
+ const metricsUrl: string = process.env.METRICS_URL ? process.env.METRICS_URL : '';
+ const solutionId: string | undefined = process.env.SOLUTION_ID;
+ const timestamp = new Date().toISOString();
+ data.logDestinationType = process.env.LOG_DESTINATION_TYPE;
+ data.logType = process.env.LOG_TYPE;
+ const metrics_data = {
+ Solution: solutionId,
+ TimeStamp: timestamp,
+ UUID: uuid,
+ Data: data,
+ };
+ Logger.log(LOG_LEVEL.DEBUG, 'metrics data: ', metrics_data);
+ const response = await axios.post(metricsUrl, JSON.stringify(metrics_data), {
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Content-Length': JSON.stringify(data).length,
+ },
+ });
+ Logger.log(LOG_LEVEL.DEBUG, 'Response: ', response);
+
+ }
+ } catch (error) {
+ Logger.log(LOG_LEVEL.DEBUG, `Error in send-metrics: ${JSON.stringify(error)}`);
}
-}
\ No newline at end of file
+ }
+}
diff --git a/source/networkFirewallAutomation/lib/common/stringUtils.ts b/source/networkFirewallAutomation/lib/common/stringUtils.ts
index e2fcc6b..5394787 100644
--- a/source/networkFirewallAutomation/lib/common/stringUtils.ts
+++ b/source/networkFirewallAutomation/lib/common/stringUtils.ts
@@ -1,31 +1,20 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { Logger, LOG_LEVEL } from './logger'
+import { Logger, LOG_LEVEL } from './logger';
export enum Name {
maxCharacters = 128,
- delimiter= '-'
+ delimiter = '-',
}
/**
* @description This class performs string manipulation operations
*/
export class StringUtils {
-
- constructor(readonly stackId: string) {
- }
-
+ constructor(readonly stackId: string) {}
/**
* @description This method will return name of the resource with parsed
@@ -34,22 +23,23 @@ export class StringUtils {
* @returns modified resource name.
*/
getUniqueResourceName(resourceName: string) {
- Logger.log(LOG_LEVEL.DEBUG, `Resource name input: ${resourceName}`)
+ Logger.log(LOG_LEVEL.DEBUG, `Resource name input: ${resourceName}`);
if (this.stackId) {
- const splitStackId = this.stackId.split("-").pop()
- let customName = resourceName + Name.delimiter + splitStackId
+ const splitStackId = this.stackId.split('-').pop();
+ let customName = resourceName + Name.delimiter + splitStackId;
if (splitStackId && customName.length > Name.maxCharacters) {
- const sliceString = Name.maxCharacters - (splitStackId.length + Name.delimiter.length)
- Logger.log(LOG_LEVEL.INFO, `Modified name is larger than 128 characters, trimming the resource name and using only first ${sliceString.toString()} characters from the name.`)
- const trimmedResourceName = resourceName.substring(0, sliceString)
- customName = trimmedResourceName + Name.delimiter + splitStackId
+ const sliceString = Name.maxCharacters - (splitStackId.length + Name.delimiter.length);
+ Logger.log(
+ LOG_LEVEL.INFO,
+ `Modified name is larger than 128 characters, trimming the resource name and using only first ${sliceString.toString()} characters from the name.`
+ );
+ const trimmedResourceName = resourceName.substring(0, sliceString);
+ customName = trimmedResourceName + Name.delimiter + splitStackId;
}
- Logger.log(LOG_LEVEL.DEBUG, `Returning Custom name : ${resourceName}`)
- return customName
- }
- else {
- throw Error("The stack id environment variable is undefined in the" +
- " CodeBuild stage environment variables.")
+ Logger.log(LOG_LEVEL.DEBUG, `Returning Custom name : ${resourceName}`);
+ return customName;
+ } else {
+ throw Error('The stack id environment variable is undefined in the' + ' CodeBuild stage environment variables.');
}
}
-}
\ No newline at end of file
+}
diff --git a/source/networkFirewallAutomation/lib/ec2-manager.ts b/source/networkFirewallAutomation/lib/ec2-manager.ts
index 5d816e4..0b57f5b 100644
--- a/source/networkFirewallAutomation/lib/ec2-manager.ts
+++ b/source/networkFirewallAutomation/lib/ec2-manager.ts
@@ -1,48 +1,38 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { EC2, NetworkFirewall } from "aws-sdk"
-import { Ec2Service } from "./service/ec2-service"
-import { LOG_LEVEL, Logger } from "./common/logger"
+import { EC2, NetworkFirewall } from 'aws-sdk';
+import { Ec2Service } from './service/ec2-service';
+import { LOG_LEVEL, Logger } from './common/logger';
export interface Ec2EnvironmentProps {
- availabilityZone: string | undefined,
- routeTableId: string | undefined
+ availabilityZone: string | undefined;
+ routeTableId: string | undefined;
}
export enum Route {
default = '0.0.0.0/0',
- active = 'active'
+ active = 'active',
}
type routeStatus = {
- VpcEndpointId: string | undefined,
- RouteTableId: string,
- DefaultRouteCreated: boolean
-}
+ VpcEndpointId: string | undefined;
+ RouteTableId: string;
+ DefaultRouteCreated: boolean;
+};
/**
* @description This class contains all the methods to
* perform CRUD operations for the VPC route to Network Firewall.
*/
export class Ec2Manager {
+ private service: Ec2Service;
+ private vpcEndpoint: string | undefined;
- private service: Ec2Service
- private vpcEndpoint: string | undefined
-
- constructor(public envProps: Ec2EnvironmentProps[],
- public firewallSyncStates: NetworkFirewall.SyncStates) {
- this.service = new Ec2Service()
+ constructor(public envProps: Ec2EnvironmentProps[], public firewallSyncStates: NetworkFirewall.SyncStates) {
+ this.service = new Ec2Service();
}
/** this method will check if route exists, if not will start the process to
@@ -51,39 +41,40 @@ export class Ec2Manager {
*/
async routeTableOperations(): Promise {
try {
- let response: routeStatus[] = []
+ let response: routeStatus[] = [];
for (let endpoint of this.envProps) {
- Logger.log(LOG_LEVEL.INFO, `Processing `, endpoint)
+ Logger.log(LOG_LEVEL.INFO, `Processing `, endpoint);
// check if routes already exist
if (endpoint.routeTableId && endpoint.availabilityZone) {
- const attachmentProps = this.firewallSyncStates[endpoint.availabilityZone]
- this.vpcEndpoint = attachmentProps.Attachment?.EndpointId
- const foundExistingRoute = await this.checkRouteTable(endpoint.routeTableId)
+ const attachmentProps = this.firewallSyncStates[endpoint.availabilityZone];
+ this.vpcEndpoint = attachmentProps.Attachment?.EndpointId;
+ const foundExistingRoute = await this.checkRouteTable(endpoint.routeTableId);
if (!foundExistingRoute) {
- Logger.log(LOG_LEVEL.INFO, `Default route to Network Firewall does not exist. Creating a new default route using endpoint: ${this.vpcEndpoint} in the ready state.`)
+ Logger.log(
+ LOG_LEVEL.INFO,
+ `Default route to Network Firewall does not exist. Creating a new default route using endpoint: ${this.vpcEndpoint} in the ready state.`
+ );
await this.service.createRoute({
DestinationCidrBlock: Route.default,
VpcEndpointId: this.vpcEndpoint,
- RouteTableId: endpoint.routeTableId
- })
+ RouteTableId: endpoint.routeTableId,
+ });
}
let status = {
VpcEndpointId: this.vpcEndpoint,
RouteTableId: endpoint.routeTableId,
- DefaultRouteCreated: !foundExistingRoute
- }
- response.push(status)
+ DefaultRouteCreated: !foundExistingRoute,
+ };
+ response.push(status);
}
}
- return response
-
- } catch
- (error) {
- Logger.log(LOG_LEVEL.ERROR, error)
- throw new Error(error["message"])
+ return response;
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.ERROR, error);
+ throw new Error(error['message']);
}
}
@@ -92,26 +83,25 @@ export class Ec2Manager {
*/
async checkRouteTable(routeTableId: string) {
// get route table details to check route already exist
- const routeTables = await this.service.describeRouteTables(routeTableId)
- Logger.log(LOG_LEVEL.INFO, routeTables)
+ const routeTables = await this.service.describeRouteTables(routeTableId);
+ Logger.log(LOG_LEVEL.INFO, routeTables);
// the describe route table API should always return single value if using
// route table id
if (routeTables && routeTables.length > 1) {
- Logger.log(LOG_LEVEL.DEBUG, routeTables)
- throw Error(`Expected only one item in the route table array. Received : ${routeTables.length} `)
+ Logger.log(LOG_LEVEL.DEBUG, routeTables);
+ throw Error(`Expected only one item in the route table array. Received : ${routeTables.length} `);
}
- let foundExistingRoute: boolean = false
+ let foundExistingRoute: boolean = false;
// at least 1 value should be present before attempting the iteration
if (routeTables && routeTables.length == 1) {
-
// the for loop would iterate only once
for (let routeTable of routeTables) {
- foundExistingRoute = await this.checkExistingRoutes(routeTable)
+ foundExistingRoute = await this.checkExistingRoutes(routeTable);
}
}
- return foundExistingRoute
+ return foundExistingRoute;
}
/**
@@ -122,49 +112,58 @@ export class Ec2Manager {
* route already exists.
*/
async checkExistingRoutes(routeTable: EC2.RouteTable): Promise {
- const routes = routeTable.Routes
- Logger.log(LOG_LEVEL.DEBUG, `print routes`)
- Logger.log(LOG_LEVEL.DEBUG, routes)
+ const routes = routeTable.Routes;
+ Logger.log(LOG_LEVEL.DEBUG, `print routes`);
+ Logger.log(LOG_LEVEL.DEBUG, routes);
if (routes) {
for (let route of routes) {
- Logger.log(LOG_LEVEL.DEBUG, `Checking route below for VPC Endpoint: ${this.vpcEndpoint}`)
- Logger.log(LOG_LEVEL.DEBUG, route)
- if (route.GatewayId && route.GatewayId === this.vpcEndpoint &&
- route.DestinationCidrBlock === Route.default && route.State === Route.active) {
- Logger.log(LOG_LEVEL.INFO, `Found Firewall VPC Endpoint ${route.GatewayId}`)
- Logger.log(LOG_LEVEL.INFO, `setting foundExistingRoute to TRUE`)
- return Promise.resolve(true)
- } else if (route.GatewayId && route.GatewayId != this.vpcEndpoint && route.DestinationCidrBlock === Route.default && route.State === Route.active) {
+ Logger.log(LOG_LEVEL.DEBUG, `Checking route below for VPC Endpoint: ${this.vpcEndpoint}`);
+ Logger.log(LOG_LEVEL.DEBUG, route);
+ if (
+ route.GatewayId &&
+ route.GatewayId === this.vpcEndpoint &&
+ route.DestinationCidrBlock === Route.default &&
+ route.State === Route.active
+ ) {
+ Logger.log(LOG_LEVEL.INFO, `Found Firewall VPC Endpoint ${route.GatewayId}`);
+ Logger.log(LOG_LEVEL.INFO, `setting foundExistingRoute to TRUE`);
+ return Promise.resolve(true);
+ } else if (
+ route.GatewayId &&
+ route.GatewayId != this.vpcEndpoint &&
+ route.DestinationCidrBlock === Route.default &&
+ route.State === Route.active
+ ) {
//remove the route entry as possibly the firewall end point is no longer the same as it was earlier.
if (routeTable.RouteTableId) {
await this.service.deleteRoute({
DestinationCidrBlock: Route.default,
- RouteTableId: routeTable.RouteTableId
- })
+ RouteTableId: routeTable.RouteTableId,
+ });
}
}
}
}
// return false - could not find existing route
- Logger.log(LOG_LEVEL.INFO, `Firewall VPC Endpoint not found as destination in the route table.`)
- return Promise.resolve(false)
+ Logger.log(LOG_LEVEL.INFO, `Firewall VPC Endpoint not found as destination in the route table.`);
+ return Promise.resolve(false);
}
/**
- * Method will update the transit gateway attachement appliance mode.
+ * Method will update the transit gateway attachement appliance mode.
* https://docs.aws.amazon.com/cli/latest/reference/ec2/modify-transit-gateway-vpc-attachment.html
- * @param transitGatewayAttachmentId
- * @param applianceMode
+ * @param transitGatewayAttachmentId
+ * @param applianceMode
*/
static async updateTransitGatewayAttachementApplianceMode(transitGatewayAttachmentId: string, applianceMode: string) {
if (transitGatewayAttachmentId && applianceMode) {
- const response = await new Ec2Service().modifyTransitGatewayAttachement({
+ const response = await new Ec2Service().modifyTransitGatewayAttachment({
TransitGatewayAttachmentId: transitGatewayAttachmentId,
Options: {
- ApplianceModeSupport: applianceMode
- }
- })
- Logger.log(LOG_LEVEL.INFO, `Response from modifyTransitGatewayAttachement API: `, response)
+ ApplianceModeSupport: applianceMode,
+ },
+ });
+ Logger.log(LOG_LEVEL.INFO, `Response from modifyTransitGatewayAttachement API: `, response);
}
}
}
diff --git a/source/networkFirewallAutomation/lib/network-firewall-manager.ts b/source/networkFirewallAutomation/lib/network-firewall-manager.ts
index 184b005..8ff79e8 100644
--- a/source/networkFirewallAutomation/lib/network-firewall-manager.ts
+++ b/source/networkFirewallAutomation/lib/network-firewall-manager.ts
@@ -1,42 +1,33 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-
-import { NetworkFirewall } from "aws-sdk"
-import { NetworkFirewallService } from "./service/network-firewall-service"
-import { ConfigReader } from "./common/configReader/config-reader"
-import { Time } from "./service/awsClientConfig";
-import { LOG_LEVEL, Logger } from "./common/logger"
-import { StringUtils } from "./common/stringUtils";
+import { NetworkFirewall } from 'aws-sdk';
+import { NetworkFirewallService } from './service/network-firewall-service';
+import { ConfigReader } from './common/configReader/config-reader';
+import { Time } from './service/awsClientConfig';
+import { LOG_LEVEL, Logger } from './common/logger';
+import { StringUtils } from './common/stringUtils';
enum LogType {
- alert = "ALERT",
- flow = "FLOW"
+ alert = 'ALERT',
+ flow = 'FLOW',
}
export interface EnvironmentProps {
vpcId: string | undefined;
subnetIds: string | undefined;
- logDestinationType: "S3" | "CloudWatchLogs" | string | undefined;
+ logDestinationType: 'S3' | 'CloudWatchLogs' | string | undefined;
logDestination: string | undefined; //bucket name or cloudwatch log group name.
- logType: "Alert" | "Flow" | "EnableBoth" | string | undefined;
+ logType: 'Alert' | 'Flow' | 'EnableBoth' | string | undefined;
logRetentionPeriod: string | undefined;
stackId: string;
}
enum RuleGroupType {
Stateless = 'STATELESS',
- Stateful = 'STATEFUL'
+ Stateful = 'STATEFUL',
}
/**
@@ -49,49 +40,50 @@ export enum FirewallStatus {
}
export class NetworkFirewallManager {
-
- private stringUtils: StringUtils
- private service: NetworkFirewallService
- private ruleGroupArnsInFirewall: string[] = []
-
- constructor(public envProps: EnvironmentProps,
- public firewallObject: NetworkFirewall.Types.CreateFirewallRequest,
- public fileHandler: ConfigReader) {
- this.service = new NetworkFirewallService()
- this.stringUtils = new StringUtils(envProps.stackId)
+ private stringUtils: StringUtils;
+ private service: NetworkFirewallService;
+ private ruleGroupArnsInFirewall: string[] = [];
+
+ constructor(
+ public envProps: EnvironmentProps,
+ public firewallObject: NetworkFirewall.Types.CreateFirewallRequest,
+ public fileHandler: ConfigReader
+ ) {
+ this.service = new NetworkFirewallService();
+ this.stringUtils = new StringUtils(envProps.stackId);
}
/** get vpc id */
getVpcId(): NetworkFirewall.VpcId {
- let vpcId
+ let vpcId;
if (this.envProps.vpcId) {
- vpcId = this.envProps.vpcId
+ vpcId = this.envProps.vpcId;
} else {
- const error_msg = "VPC ID must be in the environment variables"
- Logger.log(LOG_LEVEL.ERROR, error_msg)
- throw Error(error_msg)
+ const error_msg = 'VPC ID must be in the environment variables';
+ Logger.log(LOG_LEVEL.ERROR, error_msg);
+ throw Error(error_msg);
}
- return vpcId
+ return vpcId;
}
/** get subnet mapping */
getSubnetMapping(): NetworkFirewall.SubnetMappings {
- let subnetIdArray
- let subnetMappings
+ let subnetIdArray;
+ let subnetMappings;
if (this.envProps.subnetIds) {
- subnetIdArray = this.envProps.subnetIds.split(",")
+ subnetIdArray = this.envProps.subnetIds.split(',');
subnetMappings = subnetIdArray.map((subnetId: string) => {
return {
- SubnetId: subnetId
- }
- })
+ SubnetId: subnetId,
+ };
+ });
} else {
- const error_msg = "Subnet IDs must be in the environment variables"
- Logger.log(LOG_LEVEL.ERROR, error_msg)
- throw Error(error_msg)
+ const error_msg = 'Subnet IDs must be in the environment variables';
+ Logger.log(LOG_LEVEL.ERROR, error_msg);
+ throw Error(error_msg);
}
- return subnetMappings
+ return subnetMappings;
}
/** Function to add delay for waiting on process. */
@@ -99,21 +91,19 @@ export class NetworkFirewallManager {
return new Promise(resolve => setTimeout(resolve, ms));
}
-
/** Function will create network firewall and wait until the status of the firewall is provisioned before returning the response to the calling
* function.
*/
async createNetworkFirewall(firewallPolicyArn: string): Promise {
- this.firewallObject['VpcId'] = this.getVpcId() || ''
- this.firewallObject['SubnetMappings'] = this.getSubnetMapping()
- this.firewallObject.FirewallPolicyArn = firewallPolicyArn
+ this.firewallObject['VpcId'] = this.getVpcId() || '';
+ this.firewallObject['SubnetMappings'] = this.getSubnetMapping();
+ this.firewallObject.FirewallPolicyArn = firewallPolicyArn;
// create network firewall
- await this.service.createFirewall(this.firewallObject)
+ await this.service.createFirewall(this.firewallObject);
// check
- return await this.checkFirewallStatus()
-
+ return this.checkFirewallStatus();
}
/** Function will check if firewall exists, if not will start the process to create rule groups, create the firewall policy
@@ -123,27 +113,27 @@ export class NetworkFirewallManager {
let response;
try {
// update firewall name to unique firewall name
- this.firewallObject.FirewallName = this.stringUtils.getUniqueResourceName(this.firewallObject.FirewallName)
+ this.firewallObject.FirewallName = this.stringUtils.getUniqueResourceName(this.firewallObject.FirewallName);
const firewallName = this.firewallObject.FirewallName;
- const firewallResponse = await this.service.describeFirewall(firewallName)
+ const firewallResponse = await this.service.describeFirewall(firewallName);
if (firewallResponse && firewallResponse.Firewall) {
- Logger.log(LOG_LEVEL.INFO, `Updating existing firewall: ${firewallName}`)
- const firewallPolicyArn = await this.firewallPolicyOperations(this.firewallObject.FirewallPolicyArn)
- Logger.log(LOG_LEVEL.INFO, `Checking Firewall Status: ${firewallPolicyArn}`)
- response = await this.checkFirewallStatus()
- await this.updateFirewall(firewallResponse, firewallPolicyArn)
+ Logger.log(LOG_LEVEL.INFO, `Updating existing firewall: ${firewallName}`);
+ const firewallPolicyArn = await this.firewallPolicyOperations(this.firewallObject.FirewallPolicyArn);
+ Logger.log(LOG_LEVEL.INFO, `Checking Firewall Status: ${firewallPolicyArn}`);
+ response = await this.checkFirewallStatus();
+ await this.updateFirewall(firewallResponse, firewallPolicyArn);
} else {
- Logger.log(LOG_LEVEL.INFO, `Firewall does not exist: ${firewallName}`)
- Logger.log(LOG_LEVEL.INFO, `Checking if firewall policy exist`)
- const firewallPolicyArn = await this.firewallPolicyOperations(this.firewallObject.FirewallPolicyArn)
- Logger.log(LOG_LEVEL.INFO, `Creating Firewall: ${firewallName}`)
- response = await this.createNetworkFirewall(firewallPolicyArn)
+ Logger.log(LOG_LEVEL.INFO, `Firewall does not exist: ${firewallName}`);
+ Logger.log(LOG_LEVEL.INFO, `Checking if firewall policy exist`);
+ const firewallPolicyArn = await this.firewallPolicyOperations(this.firewallObject.FirewallPolicyArn);
+ Logger.log(LOG_LEVEL.INFO, `Creating Firewall: ${firewallName}`);
+ response = await this.createNetworkFirewall(firewallPolicyArn);
}
- await this.setupLoggingConfigurations(firewallName)
+ await this.setupLoggingConfigurations(firewallName);
return response;
- } catch (error) {
- Logger.log(LOG_LEVEL.ERROR, error)
- throw new Error(error)
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.ERROR, error);
+ throw new Error(error);
}
}
@@ -153,181 +143,232 @@ export class NetworkFirewallManager {
*/
async checkFirewallStatus(): Promise {
- let firewallStatus: string | undefined = ''
- let firewallConfigSyncState: string | undefined = ''
+ let firewallStatus: string | undefined = '';
+ let firewallConfigSyncState: string | undefined = '';
let syncStates: NetworkFirewall.SyncStates | undefined = {};
let areAttachmentsInReadyStatus = false;
do {
// sleep
- await this.delay(Time.Seconds15)
- let attachmentStatus = []
+ await this.delay(Time.Seconds15);
+ let attachmentStatus = [];
//describe firewall
- const firewallResponse = await this.service.describeFirewall(this.firewallObject.FirewallName)
+ const firewallResponse = await this.service.describeFirewall(this.firewallObject.FirewallName);
if (firewallResponse && firewallResponse.FirewallStatus) {
- firewallStatus = firewallResponse.FirewallStatus.Status
- firewallConfigSyncState = firewallResponse.FirewallStatus.ConfigurationSyncStateSummary
- syncStates = firewallResponse.FirewallStatus.SyncStates
- Logger.log(LOG_LEVEL.INFO, firewallResponse.FirewallStatus)
+ firewallStatus = firewallResponse.FirewallStatus.Status;
+ firewallConfigSyncState = firewallResponse.FirewallStatus.ConfigurationSyncStateSummary;
+ syncStates = firewallResponse.FirewallStatus.SyncStates;
+ Logger.log(LOG_LEVEL.INFO, firewallResponse.FirewallStatus);
}
if (syncStates) {
- Logger.log(LOG_LEVEL.INFO, `Sync States for the firewall. `, syncStates)
+ Logger.log(LOG_LEVEL.INFO, `Sync States for the firewall. `, syncStates);
for (let availabilityZone in syncStates) {
if (syncStates[availabilityZone].Attachment) {
- attachmentStatus.push(syncStates[availabilityZone].Attachment?.Status)
+ attachmentStatus.push(syncStates[availabilityZone].Attachment?.Status);
}
}
}
- areAttachmentsInReadyStatus = attachmentStatus.every(status => status === 'READY')
-
- }
- while (firewallStatus != FirewallStatus.Ready || firewallConfigSyncState != FirewallStatus.ConfigInSync || !areAttachmentsInReadyStatus)
-
- Logger.log(LOG_LEVEL.INFO, "Firewall is ready and configuration is in sync across" +
- " all the availability zones. Returning the sync states for all" +
- " the availability zones.")
- return syncStates
+ areAttachmentsInReadyStatus = attachmentStatus.every(status => status === 'READY');
+ } while (
+ firewallStatus != FirewallStatus.Ready ||
+ firewallConfigSyncState != FirewallStatus.ConfigInSync ||
+ !areAttachmentsInReadyStatus
+ );
+
+ Logger.log(
+ LOG_LEVEL.INFO,
+ 'Firewall is ready and configuration is in sync across' +
+ ' all the availability zones. Returning the sync states for all' +
+ ' the availability zones.'
+ );
+ return syncStates;
}
/** Function to create/update firewall policy */
async firewallPolicyOperations(policyPath: string): Promise {
let describePolicyResponse;
try {
- Logger.log(LOG_LEVEL.INFO, `Getting Firewall Policy Object`)
- const policyObject: NetworkFirewall.CreateFirewallPolicyRequest = await this.ruleGroupOperations(this.fileHandler.convertFileToObject(policyPath))
+ Logger.log(LOG_LEVEL.INFO, `Getting Firewall Policy Object`);
+ const policyObject: NetworkFirewall.CreateFirewallPolicyRequest = await this.ruleGroupOperations(
+ this.fileHandler.convertFileToObject(policyPath)
+ );
// update policy name to unique policy name
- policyObject.FirewallPolicyName = this.stringUtils.getUniqueResourceName(policyObject.FirewallPolicyName)
- Logger.log(LOG_LEVEL.INFO, `Checking if Firewall Policy exist: ${policyObject.FirewallPolicyName}`)
- Logger.log(LOG_LEVEL.INFO, `Found Firewall Policy, trying to update the policy.`)
- describePolicyResponse = await this.service.describeFirewallPolicy(policyObject.FirewallPolicyName)
- Logger.log(LOG_LEVEL.INFO, `Describe policy response`, describePolicyResponse)
+ policyObject.FirewallPolicyName = this.stringUtils.getUniqueResourceName(policyObject.FirewallPolicyName);
+ Logger.log(LOG_LEVEL.INFO, `Checking if Firewall Policy exist: ${policyObject.FirewallPolicyName}`);
+ Logger.log(LOG_LEVEL.INFO, `Found Firewall Policy, trying to update the policy.`);
+ describePolicyResponse = await this.service.describeFirewallPolicy(policyObject.FirewallPolicyName);
+ Logger.log(LOG_LEVEL.INFO, `Describe policy response`, describePolicyResponse);
if (describePolicyResponse && describePolicyResponse.FirewallPolicyResponse.FirewallPolicyArn) {
- describePolicyResponse.FirewallPolicy = policyObject.FirewallPolicy
- describePolicyResponse.FirewallPolicyResponse.Description = policyObject.Description
- describePolicyResponse.FirewallPolicyResponse.Tags = policyObject.Tags
+ describePolicyResponse.FirewallPolicy = policyObject.FirewallPolicy;
+ describePolicyResponse.FirewallPolicyResponse.Description = policyObject.Description;
+ describePolicyResponse.FirewallPolicyResponse.Tags = policyObject.Tags;
let firewallPolicyUpdateResponse = await this.service.updateFirewallPolicy({
FirewallPolicyArn: describePolicyResponse.FirewallPolicyResponse.FirewallPolicyArn,
FirewallPolicy: policyObject.FirewallPolicy,
UpdateToken: describePolicyResponse.UpdateToken,
Description: policyObject.Description,
- FirewallPolicyName: describePolicyResponse.FirewallPolicyResponse.FirewallPolicyName
- })
- Logger.log(LOG_LEVEL.INFO, `Firewall update policy response:`, firewallPolicyUpdateResponse)
+ FirewallPolicyName: describePolicyResponse.FirewallPolicyResponse.FirewallPolicyName,
+ });
+ Logger.log(LOG_LEVEL.INFO, `Firewall update policy response:`, firewallPolicyUpdateResponse);
//delete the rule groups which are currently in the firewall but not in the new firewall policy file
await this.deleteRuleGroups(policyObject);
- return describePolicyResponse.FirewallPolicyResponse.FirewallPolicyArn
-
+ return describePolicyResponse.FirewallPolicyResponse.FirewallPolicyArn;
} else {
- Logger.log(LOG_LEVEL.INFO, `Firewall Policy does not exist, trying to create the policy.`)
- const responseCreateFirewallPolicy = await this.service.createFirewallPolicy(policyObject)
- return responseCreateFirewallPolicy.FirewallPolicyResponse.FirewallPolicyArn
+ Logger.log(LOG_LEVEL.INFO, `Firewall Policy does not exist, trying to create the policy.`);
+ const responseCreateFirewallPolicy = await this.service.createFirewallPolicy(policyObject);
+ return responseCreateFirewallPolicy.FirewallPolicyResponse.FirewallPolicyArn;
}
- } catch (error) {
- Logger.log(LOG_LEVEL.INFO, error)
- throw new Error(error)
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.INFO, error);
+ throw new Error(error);
}
}
/** Function to create/update Rule Groups with a back out feature in case there is a failure. */
- async ruleGroupOperations(policyObject: NetworkFirewall.CreateFirewallPolicyRequest): Promise {
- Logger.log(LOG_LEVEL.INFO, `Checking rule groups found in the firewall policy`)
- let statelessRuleGroupsForRollback = []
- let statefulRuleGroupsForRollback = []
+ async ruleGroupOperations(
+ policyObject: NetworkFirewall.CreateFirewallPolicyRequest
+ ): Promise {
+ Logger.log(LOG_LEVEL.INFO, `Checking rule groups found in the firewall policy`);
+ let statelessRuleGroupsForRollback: NetworkFirewall.DescribeRuleGroupResponse[] = [];
+ let statefulRuleGroupsForRollback: NetworkFirewall.DescribeRuleGroupResponse[] = [];
this.ruleGroupArnsInFirewall = await this.service.listRuleGroupsForPolicy(policyObject.FirewallPolicyName);
try {
-
if (policyObject.FirewallPolicy.StatelessRuleGroupReferences) {
- for (let statelessRuleGroupReference of policyObject.FirewallPolicy.StatelessRuleGroupReferences) {
- let statelessRuleGroupObject: NetworkFirewall.CreateRuleGroupRequest = await this.fileHandler.convertFileToObject(statelessRuleGroupReference.ResourceArn)
- Logger.log(LOG_LEVEL.INFO, `Checking if stateless rule group exists: ${statelessRuleGroupObject.RuleGroupName}`)
- let describeRuleGroupResponse = await this.service.describeRuleGroup(
- statelessRuleGroupObject.RuleGroupName,
- RuleGroupType.Stateless
- )
- Logger.log(LOG_LEVEL.INFO, `Describe Rule group response`, describeRuleGroupResponse)
- if (describeRuleGroupResponse) {
- statelessRuleGroupsForRollback.push(describeRuleGroupResponse)
- Logger.log(LOG_LEVEL.INFO, `Found existing stateless rule group, trying to update it.`)
- await this.service.updateRuleGroup({
- UpdateToken: describeRuleGroupResponse.UpdateToken,
- Description: statelessRuleGroupObject.Description,
- RuleGroup: statelessRuleGroupObject.RuleGroup,
- RuleGroupArn: describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn,
- Type: statelessRuleGroupObject.Type
- })
- statelessRuleGroupReference.ResourceArn = describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn
- } else {
- Logger.log(LOG_LEVEL.INFO, `Creating rule group: ${statelessRuleGroupObject.RuleGroupName}`)
- let createRuleGroupResponse = await this.service.createRuleGroup(statelessRuleGroupObject)
- statelessRuleGroupReference.ResourceArn = createRuleGroupResponse.RuleGroupResponse.RuleGroupArn
- Logger.log(LOG_LEVEL.INFO, statelessRuleGroupReference)
- Logger.log(LOG_LEVEL.INFO, `Create Rule group response`, createRuleGroupResponse)
- }
- }
+ await this.handleStatelessRuleGroupReferences(policyObject, statelessRuleGroupsForRollback);
}
if (policyObject.FirewallPolicy.StatefulRuleGroupReferences) {
- for (let statefulRuleGroupReference of policyObject.FirewallPolicy.StatefulRuleGroupReferences) {
- let statefulRuleGroupObject: NetworkFirewall.CreateRuleGroupRequest = this.fileHandler.convertFileToObject(statefulRuleGroupReference.ResourceArn)
- if (statefulRuleGroupObject.Rules) {
- statefulRuleGroupObject.Rules = this.fileHandler.copyFileContentToString(statefulRuleGroupObject.Rules)
- }
- Logger.log(LOG_LEVEL.INFO, `Checking if stateful rule group exists: ${statefulRuleGroupObject.RuleGroupName}`)
- let describeRuleGroupResponse = await this.service.describeRuleGroup(
- statefulRuleGroupObject.RuleGroupName,
- RuleGroupType.Stateful
- )
- Logger.log(LOG_LEVEL.INFO, `Describe Rule group response`, describeRuleGroupResponse)
- if (describeRuleGroupResponse) {
- statefulRuleGroupsForRollback.push(describeRuleGroupResponse)
- //if its a suricata rule group just update the statefulRuleGroupObject.Rules
- if (statefulRuleGroupObject.Rules) {
- await this.service.updateRuleGroup({
- UpdateToken: describeRuleGroupResponse.UpdateToken,
- Description: statefulRuleGroupObject.Description,
- RuleGroupArn: describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn,
- Rules: statefulRuleGroupObject.Rules,
- Type: statefulRuleGroupObject.Type
- })
- } else {
- await this.service.updateRuleGroup({
- UpdateToken: describeRuleGroupResponse.UpdateToken,
- Description: statefulRuleGroupObject.Description,
- RuleGroup: statefulRuleGroupObject.RuleGroup,
- RuleGroupArn: describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn,
- Type: statefulRuleGroupObject.Type
- })
- }
-
- statefulRuleGroupReference.ResourceArn = describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn
- Logger.log(LOG_LEVEL.INFO, `Found existing stateful rule group, trying to update it.`)
- } else {
- Logger.log(LOG_LEVEL.INFO, `Creating rule group`)
- let createRuleGroupResponse = await this.service.createRuleGroup(statefulRuleGroupObject)
- statefulRuleGroupReference.ResourceArn = createRuleGroupResponse.RuleGroupResponse.RuleGroupArn
- Logger.log(LOG_LEVEL.INFO, statefulRuleGroupReference)
- Logger.log(LOG_LEVEL.INFO, `Create Rule group response`, createRuleGroupResponse)
- }
- }
+ await this.handleStatefulRuleGroupReferences(policyObject, statefulRuleGroupsForRollback);
}
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.ERROR, error);
+ await this.rollbackRuleGroups(statelessRuleGroupsForRollback, statefulRuleGroupsForRollback);
+ throw Error(error);
+ }
- } catch (error) {
- Logger.log(LOG_LEVEL.ERROR, error)
- for (let statelessRuleGroup of statelessRuleGroupsForRollback) {
- Logger.log(LOG_LEVEL.WARN, `Rolling back stateless rule group`, statelessRuleGroup)
- await this.service.updateRuleGroup(statelessRuleGroup)
+ return policyObject;
+ }
+
+ private async handleStatelessRuleGroupReferences(
+ policyObject: NetworkFirewall.CreateFirewallPolicyRequest,
+ statelessRuleGroupsForRollback: NetworkFirewall.DescribeRuleGroupResponse[]
+ ) {
+ if (!policyObject.FirewallPolicy.StatelessRuleGroupReferences) {
+ return;
+ }
+
+ for (let statelessRuleGroupReference of policyObject.FirewallPolicy.StatelessRuleGroupReferences) {
+ let statelessRuleGroupObject: NetworkFirewall.CreateRuleGroupRequest = await this.fileHandler.convertFileToObject(
+ statelessRuleGroupReference.ResourceArn
+ );
+ Logger.log(LOG_LEVEL.INFO, `Checking if stateless rule group exists: ${statelessRuleGroupObject.RuleGroupName}`);
+ let describeRuleGroupResponse = await this.service.describeRuleGroup(
+ statelessRuleGroupObject.RuleGroupName,
+ RuleGroupType.Stateless
+ );
+ Logger.log(LOG_LEVEL.INFO, `Describe Rule group response`, describeRuleGroupResponse);
+ if (describeRuleGroupResponse) {
+ statelessRuleGroupsForRollback.push(describeRuleGroupResponse);
+ Logger.log(LOG_LEVEL.INFO, `Found existing stateless rule group, trying to update it.`);
+ await this.service.updateRuleGroup({
+ UpdateToken: describeRuleGroupResponse.UpdateToken,
+ Description: statelessRuleGroupObject.Description,
+ RuleGroup: statelessRuleGroupObject.RuleGroup,
+ RuleGroupArn: describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn,
+ Type: statelessRuleGroupObject.Type,
+ });
+ statelessRuleGroupReference.ResourceArn = describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn;
+ } else {
+ await this.createStatelessRuleGroup(statelessRuleGroupObject, statelessRuleGroupReference);
}
- Logger.log(LOG_LEVEL.WARN, `Rolling back stateful rule groups`, statefulRuleGroupsForRollback)
- for (let statefulRuleGroup of statefulRuleGroupsForRollback) {
- Logger.log(LOG_LEVEL.WARN, `Rolling back stateful rule group`, statefulRuleGroup)
- await this.service.updateRuleGroup(statefulRuleGroup)
+ }
+ }
+
+ private async createStatelessRuleGroup(
+ ruleGroupObject: NetworkFirewall.CreateRuleGroupRequest,
+ ruleGroupReference: NetworkFirewall.StatelessRuleGroupReference
+ ) {
+ Logger.log(LOG_LEVEL.INFO, `Creating rule group: ${ruleGroupObject.RuleGroupName}`);
+ let createRuleGroupResponse = await this.service.createRuleGroup(ruleGroupObject);
+ ruleGroupReference.ResourceArn = createRuleGroupResponse.RuleGroupResponse.RuleGroupArn;
+ Logger.log(LOG_LEVEL.INFO, ruleGroupReference);
+ Logger.log(LOG_LEVEL.INFO, `Create Rule group response`, createRuleGroupResponse);
+ }
+
+ private async handleStatefulRuleGroupReferences(
+ policyObject: NetworkFirewall.CreateFirewallPolicyRequest,
+ statefulRuleGroupsForRollback: NetworkFirewall.DescribeRuleGroupResponse[]
+ ) {
+ if (!policyObject.FirewallPolicy.StatefulRuleGroupReferences) {
+ return;
+ }
+ for (let statefulRuleGroupReference of policyObject.FirewallPolicy.StatefulRuleGroupReferences) {
+ let statefulRuleGroupObject: NetworkFirewall.CreateRuleGroupRequest = this.fileHandler.convertFileToObject(
+ statefulRuleGroupReference.ResourceArn
+ );
+ if (statefulRuleGroupObject.Rules) {
+ statefulRuleGroupObject.Rules = this.fileHandler.copyFileContentToString(statefulRuleGroupObject.Rules);
+ }
+ Logger.log(LOG_LEVEL.INFO, `Checking if stateful rule group exists: ${statefulRuleGroupObject.RuleGroupName}`);
+ let describeRuleGroupResponse = await this.service.describeRuleGroup(
+ statefulRuleGroupObject.RuleGroupName,
+ RuleGroupType.Stateful
+ );
+ Logger.log(LOG_LEVEL.INFO, `Describe Rule group response`, describeRuleGroupResponse);
+ if (describeRuleGroupResponse) {
+ statefulRuleGroupsForRollback.push(describeRuleGroupResponse);
+ //if its a suricata rule group just update the statefulRuleGroupObject.Rules
+ if (statefulRuleGroupObject.Rules) {
+ await this.service.updateRuleGroup({
+ UpdateToken: describeRuleGroupResponse.UpdateToken,
+ Description: statefulRuleGroupObject.Description,
+ RuleGroupArn: describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn,
+ Rules: statefulRuleGroupObject.Rules,
+ Type: statefulRuleGroupObject.Type,
+ });
+ } else {
+ await this.service.updateRuleGroup({
+ UpdateToken: describeRuleGroupResponse.UpdateToken,
+ Description: statefulRuleGroupObject.Description,
+ RuleGroup: statefulRuleGroupObject.RuleGroup,
+ RuleGroupArn: describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn,
+ Type: statefulRuleGroupObject.Type,
+ });
+ }
+
+ statefulRuleGroupReference.ResourceArn = describeRuleGroupResponse.RuleGroupResponse.RuleGroupArn;
+ Logger.log(LOG_LEVEL.INFO, `Found existing stateful rule group, trying to update it.`);
+ } else {
+ await this.createStatefulRuleGroup(statefulRuleGroupObject, statefulRuleGroupReference);
}
- Logger.log(LOG_LEVEL.ERROR, error)
- throw Error(error)
}
+ }
- return policyObject;
+ private async createStatefulRuleGroup(
+ statefulRuleGroupObject: NetworkFirewall.CreateRuleGroupRequest,
+ statefulRuleGroupReference: NetworkFirewall.StatefulRuleGroupReference
+ ) {
+ Logger.log(LOG_LEVEL.INFO, `Creating rule group`);
+ let createRuleGroupResponse = await this.service.createRuleGroup(statefulRuleGroupObject);
+ statefulRuleGroupReference.ResourceArn = createRuleGroupResponse.RuleGroupResponse.RuleGroupArn;
+ Logger.log(LOG_LEVEL.INFO, statefulRuleGroupReference);
+ Logger.log(LOG_LEVEL.INFO, `Create Rule group response`, createRuleGroupResponse);
+ }
+
+ private async rollbackRuleGroups(
+ statelessRuleGroupsForRollback: NetworkFirewall.DescribeRuleGroupResponse[],
+ statefulRuleGroupsForRollback: NetworkFirewall.DescribeRuleGroupResponse[]
+ ) {
+ for (let statelessRuleGroup of statelessRuleGroupsForRollback) {
+ Logger.log(LOG_LEVEL.WARN, `Rolling back stateless rule group`, statelessRuleGroup);
+ await this.service.updateRuleGroup(statelessRuleGroup);
+ }
+ Logger.log(LOG_LEVEL.WARN, `Rolling back stateful rule groups`, statefulRuleGroupsForRollback);
+ for (let statefulRuleGroup of statefulRuleGroupsForRollback) {
+ Logger.log(LOG_LEVEL.WARN, `Rolling back stateful rule group`, statefulRuleGroup);
+ await this.service.updateRuleGroup(statefulRuleGroup);
+ }
}
/**
@@ -337,22 +378,26 @@ export class NetworkFirewallManager {
* @param policyObject -- NetworkFirewall.CreateFirewallPolicyRequest
*/
async deleteRuleGroups(policyObject: NetworkFirewall.CreateFirewallPolicyRequest) {
- await this.delay(Time.Seconds15)
- Logger.log(LOG_LEVEL.DEBUG, `The rule groups currently configured in the firewall `, this.ruleGroupArnsInFirewall)
+ await this.delay(Time.Seconds15);
+ Logger.log(LOG_LEVEL.DEBUG, `The rule groups currently configured in the firewall `, this.ruleGroupArnsInFirewall);
//retrieve the rule groups in policy Object
let ruleGroupsInFirewallPolicyFile: { [key: string]: string } = {};
if (policyObject.FirewallPolicy.StatefulRuleGroupReferences) {
for (let ruleGroup of policyObject.FirewallPolicy.StatefulRuleGroupReferences) {
- ruleGroupsInFirewallPolicyFile[ruleGroup.ResourceArn] = ruleGroup.ResourceArn
+ ruleGroupsInFirewallPolicyFile[ruleGroup.ResourceArn] = ruleGroup.ResourceArn;
}
}
if (policyObject.FirewallPolicy.StatelessRuleGroupReferences) {
for (let ruleGroup of policyObject.FirewallPolicy.StatelessRuleGroupReferences) {
- ruleGroupsInFirewallPolicyFile[ruleGroup.ResourceArn] = ruleGroup.ResourceArn
+ ruleGroupsInFirewallPolicyFile[ruleGroup.ResourceArn] = ruleGroup.ResourceArn;
}
}
- Logger.log(LOG_LEVEL.DEBUG, `The rule groups configured in the new firewall policy file `, ruleGroupsInFirewallPolicyFile)
+ Logger.log(
+ LOG_LEVEL.DEBUG,
+ `The rule groups configured in the new firewall policy file `,
+ ruleGroupsInFirewallPolicyFile
+ );
for (let oldRuleGroupArn of this.ruleGroupArnsInFirewall) {
if (!ruleGroupsInFirewallPolicyFile[oldRuleGroupArn]) {
await this.service.deleteRuleGroup(oldRuleGroupArn);
@@ -361,65 +406,65 @@ export class NetworkFirewallManager {
}
/*
- * This method will setup the logging configuration for the firewall, based on the environment properties in EnvironmentProps.
- * If there is any error in updating the logging configurations it will log a warning and still continue the rest of the process.
- */
+ * This method will setup the logging configuration for the firewall, based on the environment properties in EnvironmentProps.
+ * If there is any error in updating the logging configurations it will log a warning and still continue the rest of the process.
+ */
async setupLoggingConfigurations(firewallName: string) {
let loggingConfiguration = await this.createLoggingConfigurations();
try {
await this.service.updateLoggingConfiguration(firewallName, {
- "LogDestinationConfigs": loggingConfiguration
- })
+ LogDestinationConfigs: loggingConfiguration,
+ });
} catch (error) {
Logger.log(LOG_LEVEL.INFO, `Logging configuration: `, loggingConfiguration);
- Logger.log(LOG_LEVEL.ERROR, `Failed to update logging configuration`, error)
+ Logger.log(LOG_LEVEL.ERROR, `Failed to update logging configuration`, error);
}
}
async createLoggingConfigurations() {
- let loggingConfiguration = []
- Logger.log(LOG_LEVEL.INFO, this.envProps)
- if (this.envProps.logType && this.envProps.logType.toUpperCase() === "ENABLEBOTH") {
+ let loggingConfiguration = [];
+ Logger.log(LOG_LEVEL.INFO, this.envProps);
+ if (this.envProps.logType && this.envProps.logType.toUpperCase() === 'ENABLEBOTH') {
let alertConfig = {
LogType: LogType.alert,
LogDestinationType: '',
- LogDestination: {}
- }
+ LogDestination: {},
+ };
let flowConfig = {
LogType: LogType.flow,
LogDestinationType: '',
- LogDestination: {}
- }
- loggingConfiguration.push(alertConfig)
- loggingConfiguration.push(flowConfig)
+ LogDestination: {},
+ };
+ loggingConfiguration.push(alertConfig);
+ loggingConfiguration.push(flowConfig);
} else {
let config = {
LogType: this.envProps.logType ? this.envProps.logType.toUpperCase() : LogType.alert,
LogDestinationType: '',
- LogDestination: {}
- }
- loggingConfiguration.push(config)
+ LogDestination: {},
+ };
+ loggingConfiguration.push(config);
}
loggingConfiguration.forEach(config => {
switch (this.envProps.logDestinationType?.toUpperCase()) {
- case "S3":
- config.LogDestinationType = "S3"
+ case 'S3':
+ config.LogDestinationType = 'S3';
config.LogDestination = {
- "bucketName": this.envProps.logDestination,
- "prefix": config.LogType === LogType.alert ? "alerts" : "flow"
- }
+ bucketName: this.envProps.logDestination,
+ prefix: config.LogType === LogType.alert ? 'alerts' : 'flow',
+ };
break;
- case "CLOUDWATCHLOGS":
- config.LogDestinationType = "CloudWatchLogs"
+ case 'CLOUDWATCHLOGS':
+ config.LogDestinationType = 'CloudWatchLogs';
config.LogDestination = {
- "logGroup": this.envProps.logDestination
- }
+ logGroup: this.envProps.logDestination,
+ };
break;
}
- })
- Logger.log(LOG_LEVEL.INFO, loggingConfiguration)
- return Promise.resolve(loggingConfiguration)
+ });
+ Logger.log(LOG_LEVEL.INFO, loggingConfiguration);
+ return Promise.resolve(loggingConfiguration);
}
/**
@@ -429,63 +474,104 @@ export class NetworkFirewallManager {
* Associates a new firewall policy arn if the describeFirewallResponse
* and the firewallPolicyArn parameter are not same.
*/
- async updateFirewall(describeFirewallResponse: NetworkFirewall.Types.DescribeFirewallResponse, firewallPolicyArn: string) {
+ async updateFirewall(
+ describeFirewallResponse: NetworkFirewall.Types.DescribeFirewallResponse,
+ firewallPolicyArn: string
+ ) {
+ if (!describeFirewallResponse.Firewall) {
+ return;
+ }
- if (describeFirewallResponse.Firewall) {
+ await this.updateFirewallDeleteProtection(describeFirewallResponse);
- //update firewall delete protection attribute
- if (describeFirewallResponse.Firewall.DeleteProtection !== this.firewallObject.DeleteProtection) {
- const response = await this.service.updateFirewallDeleteProtection({
- FirewallName: this.firewallObject.FirewallName,
- DeleteProtection: this.firewallObject.DeleteProtection ? this.firewallObject.DeleteProtection : false
- })
- Logger.log(LOG_LEVEL.INFO, 'Update firewall delete protection response: ', response)
+ await this.updateFirewallPolicyChangeProtection(describeFirewallResponse);
- }
+ await this.updateSubnetChangeProtection(describeFirewallResponse);
- //update firewall policy change protection.
- if (describeFirewallResponse.Firewall.FirewallPolicyChangeProtection !== this.firewallObject.FirewallPolicyChangeProtection) {
- const response = await this.service.updateFirewallPolicyChangeProtection({
- FirewallName: this.firewallObject.FirewallName,
- FirewallPolicyChangeProtection: this.firewallObject.FirewallPolicyChangeProtection ? this.firewallObject.FirewallPolicyChangeProtection : false
- })
- Logger.log(LOG_LEVEL.INFO, 'Update firewall policy change protection response: ', response)
- }
- //update subnet change protection.
- if (describeFirewallResponse.Firewall.SubnetChangeProtection !== this.firewallObject.SubnetChangeProtection) {
- const response = await this.service.updateSubnetChangeProtection({
- FirewallName: this.firewallObject.FirewallName,
- SubnetChangeProtection: this.firewallObject.SubnetChangeProtection ? this.firewallObject.SubnetChangeProtection : false
- })
- Logger.log(LOG_LEVEL.INFO, 'Update firewall policy change protection response: ', response)
- }
- //update firewall description
- if (describeFirewallResponse.Firewall.Description !== this.firewallObject.Description) {
- const response = await this.service.updateFirewallDescription({
- Description: this.firewallObject.Description,
- FirewallName: this.firewallObject.FirewallName
- })
- Logger.log(LOG_LEVEL.INFO, 'Update firewall description response: ', response)
- }
+ await this.updateFirewallDescription(describeFirewallResponse);
- //associate firewall policy arn to the firewall.
- if (describeFirewallResponse.Firewall.FirewallPolicyArn !== firewallPolicyArn) {
- const response = await this.service.associateFirewallPolicy({
- FirewallPolicyArn: firewallPolicyArn,
- FirewallName: this.firewallObject.FirewallName
- })
- Logger.log(LOG_LEVEL.INFO, `associate/update new firewall policy ${this.firewallObject.FirewallPolicyArn} for the firewall name: ${this.firewallObject.FirewallName} response:`, response)
- }
+ await this.associateFirewallPolicyArn(describeFirewallResponse, firewallPolicyArn);
- if (this.firewallObject.Tags && describeFirewallResponse.Firewall.FirewallArn) {
- const response = await this.service.tagResource({
- ResourceArn: describeFirewallResponse.Firewall.FirewallArn,
- Tags: this.firewallObject.Tags
- })
- Logger.log(LOG_LEVEL.INFO, `Update Tags for firewall ${this.firewallObject.FirewallPolicyArn} for the firewall name: ${this.firewallObject.FirewallName} response:`, response)
- }
+ await this.addTagsToFirewall(describeFirewallResponse);
+ }
+
+ private async addTagsToFirewall(describeFirewallResponse: NetworkFirewall.DescribeFirewallResponse) {
+ if (this.firewallObject.Tags && describeFirewallResponse.Firewall?.FirewallArn) {
+ const response = await this.service.tagResource({
+ ResourceArn: describeFirewallResponse.Firewall.FirewallArn,
+ Tags: this.firewallObject.Tags,
+ });
+ Logger.log(
+ LOG_LEVEL.INFO,
+ `Update Tags for firewall ${this.firewallObject.FirewallPolicyArn} for the firewall name: ${this.firewallObject.FirewallName} response:`,
+ response
+ );
+ }
+ }
+
+ private async updateFirewallDeleteProtection(describeFirewallResponse: NetworkFirewall.DescribeFirewallResponse) {
+ if (describeFirewallResponse.Firewall?.DeleteProtection !== this.firewallObject.DeleteProtection) {
+ const response = await this.service.updateFirewallDeleteProtection({
+ FirewallName: this.firewallObject.FirewallName,
+ DeleteProtection: this.firewallObject.DeleteProtection ? this.firewallObject.DeleteProtection : false,
+ });
+ Logger.log(LOG_LEVEL.INFO, 'Update firewall delete protection response: ', response);
+ }
+ }
+ private async updateFirewallPolicyChangeProtection(
+ describeFirewallResponse: NetworkFirewall.DescribeFirewallResponse
+ ) {
+ if (
+ describeFirewallResponse.Firewall?.FirewallPolicyChangeProtection !==
+ this.firewallObject.FirewallPolicyChangeProtection
+ ) {
+ const response = await this.service.updateFirewallPolicyChangeProtection({
+ FirewallName: this.firewallObject.FirewallName,
+ FirewallPolicyChangeProtection: this.firewallObject.FirewallPolicyChangeProtection
+ ? this.firewallObject.FirewallPolicyChangeProtection
+ : false,
+ });
+ Logger.log(LOG_LEVEL.INFO, 'Update firewall policy change protection response: ', response);
+ }
+ }
+
+ private async updateSubnetChangeProtection(describeFirewallResponse: NetworkFirewall.DescribeFirewallResponse) {
+ if (describeFirewallResponse.Firewall?.SubnetChangeProtection !== this.firewallObject.SubnetChangeProtection) {
+ const response = await this.service.updateSubnetChangeProtection({
+ FirewallName: this.firewallObject.FirewallName,
+ SubnetChangeProtection: this.firewallObject.SubnetChangeProtection
+ ? this.firewallObject.SubnetChangeProtection
+ : false,
+ });
+ Logger.log(LOG_LEVEL.INFO, 'Update firewall policy change protection response: ', response);
+ }
+ }
+ private async updateFirewallDescription(describeFirewallResponse: NetworkFirewall.DescribeFirewallResponse) {
+ if (describeFirewallResponse.Firewall?.Description !== this.firewallObject.Description) {
+ const response = await this.service.updateFirewallDescription({
+ Description: this.firewallObject.Description,
+ FirewallName: this.firewallObject.FirewallName,
+ });
+ Logger.log(LOG_LEVEL.INFO, 'Update firewall description response: ', response);
}
}
-}
\ No newline at end of file
+
+ private async associateFirewallPolicyArn(
+ describeFirewallResponse: NetworkFirewall.DescribeFirewallResponse,
+ firewallPolicyArn: string
+ ) {
+ if (describeFirewallResponse.Firewall?.FirewallPolicyArn !== firewallPolicyArn) {
+ const response = await this.service.associateFirewallPolicy({
+ FirewallPolicyArn: firewallPolicyArn,
+ FirewallName: this.firewallObject.FirewallName,
+ });
+ Logger.log(
+ LOG_LEVEL.INFO,
+ `associate/update new firewall policy ${this.firewallObject.FirewallPolicyArn} for the firewall name: ${this.firewallObject.FirewallName} response:`,
+ response
+ );
+ }
+ }
+}
diff --git a/source/networkFirewallAutomation/lib/service/awsClientConfig.ts b/source/networkFirewallAutomation/lib/service/awsClientConfig.ts
index 31b92cb..91c84b9 100644
--- a/source/networkFirewallAutomation/lib/service/awsClientConfig.ts
+++ b/source/networkFirewallAutomation/lib/service/awsClientConfig.ts
@@ -1,40 +1,32 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import {ConfigurationOptions} from 'aws-sdk'
+import { ConfigurationOptions } from 'aws-sdk';
export enum Time {
Seconds5 = 5000,
- Seconds15 = 15000
+ Seconds15 = 15000,
}
export enum Count {
minRetry = 3,
- maxRetry = 10
+ maxRetry = 10,
}
/**
* @description This class setup the retry options for AWS APIs
*/
export class AwsClientConfig {
-
/**
* @description Retry method returns the ConfigurationOptions instances with retryDelayOptions and maxRetries options set.
- * @returns ConfigurationOptions
+ * @returns ConfigurationOptions
*/
- retry(): ConfigurationOptions {
+ getRetryConfigurationOptions(): ConfigurationOptions {
return {
- retryDelayOptions: {base: Time.Seconds5},
- maxRetries: Count.maxRetry
- }
+ retryDelayOptions: { base: Time.Seconds5 },
+ maxRetries: Count.maxRetry,
+ customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
+ };
}
-}
\ No newline at end of file
+}
diff --git a/source/networkFirewallAutomation/lib/service/ec2-service.ts b/source/networkFirewallAutomation/lib/service/ec2-service.ts
index 37b6cd8..732dc85 100644
--- a/source/networkFirewallAutomation/lib/service/ec2-service.ts
+++ b/source/networkFirewallAutomation/lib/service/ec2-service.ts
@@ -1,97 +1,86 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { ConfigurationOptions, EC2 } from 'aws-sdk'
-import { AwsClientConfig } from './awsClientConfig'
-import { Logger, LOG_LEVEL } from '../common/logger'
+import { ConfigurationOptions, EC2 } from 'aws-sdk';
+import { AwsClientConfig } from './awsClientConfig';
+import { Logger, LOG_LEVEL } from '../common/logger';
/**
* Service class which handles all the EC2 API integrations.
*/
export class Ec2Service {
-
- private Ec2Client: EC2
- config: ConfigurationOptions
+ private Ec2Client: EC2;
+ config: ConfigurationOptions;
constructor() {
- this.config = new AwsClientConfig().retry()
+ this.config = new AwsClientConfig().getRetryConfigurationOptions();
this.Ec2Client = new EC2(this.config);
}
/** Describes the route. */
async describeRouteTables(routeTableId: string): Promise {
- Logger.log(LOG_LEVEL.INFO, 'Describe Route Table')
- Logger.log(LOG_LEVEL.INFO, `Print Route Table Id: ${routeTableId}`)
- let response: EC2.DescribeRouteTablesResult
+ Logger.log(LOG_LEVEL.INFO, 'Describe Route Table');
+ Logger.log(LOG_LEVEL.INFO, `Print Route Table Id: ${routeTableId}`);
+ let response: EC2.DescribeRouteTablesResult;
try {
response = await this.Ec2Client.describeRouteTables({
- RouteTableIds: [routeTableId]
- }
- ).promise()
+ RouteTableIds: [routeTableId],
+ }).promise();
- let nextToken = response.NextToken
- let routeTables = response.RouteTables
+ let nextToken = response.NextToken;
+ let routeTables = response.RouteTables;
// handle next token
while (nextToken) {
response = await this.Ec2Client.describeRouteTables({
- RouteTableIds: [routeTableId],
- NextToken: nextToken
- }
- ).promise()
+ RouteTableIds: [routeTableId],
+ NextToken: nextToken,
+ }).promise();
if (response.RouteTables) {
- routeTables?.concat(response.RouteTables)
+ routeTables = routeTables?.concat(response.RouteTables);
}
- nextToken = response.NextToken
+ nextToken = response.NextToken;
}
- return Promise.resolve(routeTables)
+ return Promise.resolve(routeTables);
} catch (error) {
- Logger.log(LOG_LEVEL.INFO, JSON.stringify(error))
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.INFO, JSON.stringify(error));
+ return Promise.reject(error);
}
}
/** Creates route in the given route table. */
async createRoute(props: EC2.CreateRouteRequest): Promise {
- Logger.log(LOG_LEVEL.INFO, 'Create Route')
- Logger.log(LOG_LEVEL.INFO, `Print Props: `, props)
+ Logger.log(LOG_LEVEL.INFO, 'Create Route');
+ Logger.log(LOG_LEVEL.INFO, `Print Props: `, props);
try {
- const response = await this.Ec2Client.createRoute(props).promise()
- return Promise.resolve(response)
+ const response = await this.Ec2Client.createRoute(props).promise();
+ return Promise.resolve(response);
} catch (e) {
- return Promise.reject(e)
+ return Promise.reject(e);
}
}
- async deleteRoute(props: EC2.DeleteRouteRequest): Promise {
- Logger.log(LOG_LEVEL.INFO, 'delete Route')
- Logger.log(LOG_LEVEL.INFO, `Print Props: `, props)
+ async deleteRoute(props: EC2.DeleteRouteRequest): Promise {
+ Logger.log(LOG_LEVEL.INFO, 'delete Route');
+ Logger.log(LOG_LEVEL.INFO, `Print Props: `, props);
try {
- await this.Ec2Client.deleteRoute(props).promise()
- return Promise.resolve()
- } catch (error) {
- return Promise.reject(error)
+ await this.Ec2Client.deleteRoute(props).promise();
+ return Promise.resolve();
+ } catch (error) {
+ return Promise.reject(error);
}
}
- async modifyTransitGatewayAttachement(props: EC2.ModifyTransitGatewayVpcAttachmentRequest) {
- Logger.log(LOG_LEVEL.INFO, `modify the transit gateway attachment`)
- Logger.log(LOG_LEVEL.INFO, `Print Props: `, props)
+ async modifyTransitGatewayAttachment(props: EC2.ModifyTransitGatewayVpcAttachmentRequest) {
+ Logger.log(LOG_LEVEL.INFO, `modify the transit gateway attachment`);
+ Logger.log(LOG_LEVEL.INFO, `Print Props: `, props);
try {
- const response = await this.Ec2Client.modifyTransitGatewayVpcAttachment(props).promise()
- return Promise.resolve(response)
+ const response = await this.Ec2Client.modifyTransitGatewayVpcAttachment(props).promise();
+ return Promise.resolve(response);
} catch (error) {
- return Promise.resolve(error)
+ return Promise.resolve(error);
}
}
-}
\ No newline at end of file
+}
diff --git a/source/networkFirewallAutomation/lib/service/network-firewall-service.ts b/source/networkFirewallAutomation/lib/service/network-firewall-service.ts
index 9c7a0d6..7e2d3a8 100644
--- a/source/networkFirewallAutomation/lib/service/network-firewall-service.ts
+++ b/source/networkFirewallAutomation/lib/service/network-firewall-service.ts
@@ -1,173 +1,170 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import { ConfigurationOptions, NetworkFirewall } from 'aws-sdk'
-import { AwsClientConfig, Count } from './awsClientConfig'
-import { LOG_LEVEL, Logger } from '../common/logger'
+import { ConfigurationOptions, NetworkFirewall } from 'aws-sdk';
+import { AwsClientConfig, Count } from './awsClientConfig';
+import { LOG_LEVEL, Logger } from '../common/logger';
/**
* Service class which handles all the Network Firewall API integrations.
*/
export class NetworkFirewallService {
-
- private NetworkFirewallInstance: NetworkFirewall
- config: ConfigurationOptions
- count: number
+ private NetworkFirewallInstance: NetworkFirewall;
+ config: ConfigurationOptions;
+ count: number;
constructor() {
- this.config = new AwsClientConfig().retry()
- this.count = 0
+ this.config = new AwsClientConfig().getRetryConfigurationOptions();
+ this.count = 0;
this.NetworkFirewallInstance = new NetworkFirewall(this.config);
}
/** Creates Firewall configurations returns an void/undefined if the firewall doesn't not exist. */
async createFirewall(props: NetworkFirewall.CreateFirewallRequest) {
- Logger.log(LOG_LEVEL.INFO, 'Creating Firewall')
- Logger.log(LOG_LEVEL.INFO, `Print Props: ${JSON.stringify(props)}`)
+ Logger.log(LOG_LEVEL.INFO, 'Creating Firewall');
+ Logger.log(LOG_LEVEL.INFO, `Print Props: ${JSON.stringify(props)}`);
try {
- const response = await this.NetworkFirewallInstance.createFirewall(props).promise()
- return Promise.resolve(response)
- } catch (e) {
- if (e.code === "ResourceNotFoundException") {
- Logger.log(LOG_LEVEL.INFO, "Firewall Not Found")
- return
+ const response = await this.NetworkFirewallInstance.createFirewall(props).promise();
+ return Promise.resolve(response);
+ } catch (e: any) {
+ if (e.code === 'ResourceNotFoundException') {
+ Logger.log(LOG_LEVEL.INFO, 'Firewall Not Found');
+ return;
}
- return Promise.reject(e)
+ return Promise.reject(e);
}
}
/** Creates a firewall policy and returns the response object received
* from the Network Firewall API. */
async createFirewallPolicy(props: NetworkFirewall.CreateFirewallPolicyRequest) {
- Logger.log(LOG_LEVEL.INFO, 'Creating Firewall Policy')
- Logger.log(LOG_LEVEL.INFO, `Print Props: ${JSON.stringify(props)}`)
- return await this.NetworkFirewallInstance.createFirewallPolicy(props).promise()
+ Logger.log(LOG_LEVEL.INFO, 'Creating Firewall Policy');
+ Logger.log(LOG_LEVEL.INFO, `Print Props: ${JSON.stringify(props)}`);
+ return this.NetworkFirewallInstance.createFirewallPolicy(props).promise();
}
/** Creates a rule group and returns the response object received from the Network Firewall API */
async createRuleGroup(props: NetworkFirewall.CreateRuleGroupRequest) {
- Logger.log(LOG_LEVEL.INFO, 'Creating Firewall Rule Group')
- Logger.log(LOG_LEVEL.INFO, `Print createRuleGroup Props`)
- Logger.log(LOG_LEVEL.INFO, props)
- return await this.NetworkFirewallInstance.createRuleGroup(props).promise()
+ Logger.log(LOG_LEVEL.INFO, 'Creating Firewall Rule Group');
+ Logger.log(LOG_LEVEL.INFO, `Print createRuleGroup Props`);
+ Logger.log(LOG_LEVEL.INFO, props);
+ return this.NetworkFirewallInstance.createRuleGroup(props).promise();
}
/** Describes the firewall based on the input param firewallName, return void/undefined if there is not firewall with the firewall Name defined. */
async describeFirewall(firewallName: string): Promise {
- Logger.log(LOG_LEVEL.INFO, 'Describe Firewall')
- Logger.log(LOG_LEVEL.INFO, `Print Firewall Name: ${firewallName}`)
+ Logger.log(LOG_LEVEL.INFO, 'Describe Firewall');
+ Logger.log(LOG_LEVEL.INFO, `Print Firewall Name: ${firewallName}`);
try {
const response = await this.NetworkFirewallInstance.describeFirewall({
- FirewallName: firewallName
- }
- ).promise()
- return Promise.resolve(response)
- } catch (error) {
- Logger.log(LOG_LEVEL.INFO, JSON.stringify(error))
- if (error.code === "ResourceNotFoundException") {
- Logger.log(LOG_LEVEL.INFO, "Firewall Not Found.")
- return Promise.resolve()
+ FirewallName: firewallName,
+ }).promise();
+ return Promise.resolve(response);
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.INFO, JSON.stringify(error));
+ if (error.code === 'ResourceNotFoundException') {
+ Logger.log(LOG_LEVEL.INFO, 'Firewall Not Found.');
+ return Promise.resolve();
}
- return Promise.reject(error)
+ return Promise.reject(error);
}
}
/** Describes the firewall policy and returns void/undefined if there is no firewall policy with the Name and/or Arn defined */
- async describeFirewallPolicy(firewallPolicyName: string): Promise {
+ async describeFirewallPolicy(
+ firewallPolicyName: string
+ ): Promise {
try {
const response = await this.NetworkFirewallInstance.describeFirewallPolicy({
- FirewallPolicyName: firewallPolicyName
+ FirewallPolicyName: firewallPolicyName,
}).promise();
- return Promise.resolve(response)
- } catch (error) {
- Logger.log(LOG_LEVEL.INFO, JSON.stringify(error))
- if (error.code === "ResourceNotFoundException") {
- Logger.log(LOG_LEVEL.INFO, "Firewall Policy Not Found.")
- return Promise.resolve()
+ return Promise.resolve(response);
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.INFO, JSON.stringify(error));
+ if (error.code === 'ResourceNotFoundException') {
+ Logger.log(LOG_LEVEL.INFO, 'Firewall Policy Not Found.');
+ return Promise.resolve();
}
- return Promise.reject(error)
+ return Promise.reject(error);
}
}
/** Describes the rule group and returns an rule response object from the api, return void/undefined in case none is found, the
* method will retry API calls for a maximum of Count.minRetry value.
*/
- async describeRuleGroup(RuleGroupName: string, Type: string): Promise {
+ async describeRuleGroup(
+ RuleGroupName: string,
+ Type: string
+ ): Promise {
+ // reset the count to 0 in case anyother call has been made
+ this.count = 0;
do {
try {
- Logger.log(LOG_LEVEL.INFO, `Describing Rule Group: ${RuleGroupName} | Type: ${Type}`)
+ Logger.log(LOG_LEVEL.INFO, `Describing Rule Group: ${RuleGroupName} | Type: ${Type}`);
const response = await this.NetworkFirewallInstance.describeRuleGroup({
RuleGroupName: RuleGroupName,
- Type: Type
- }
- ).promise()
- return Promise.resolve(response)
- } catch (error) {
- Logger.log(LOG_LEVEL.INFO, JSON.stringify(error))
- if (error.message === "ThrottlingException") {
- this.count++ //increment the count
- Logger.log(LOG_LEVEL.INFO, `Caught throttling exception, trying count: ${this.count}`)
+ Type: Type,
+ }).promise();
+ return Promise.resolve(response);
+ } catch (error: any) {
+ Logger.log(LOG_LEVEL.INFO, JSON.stringify(error));
+ if (error.message === 'ThrottlingException') {
+ this.count++; //increment the count
+ Logger.log(LOG_LEVEL.INFO, `Caught throttling exception, trying count: ${this.count}`);
}
- if (error.code === "ResourceNotFoundException") {
- Logger.log(LOG_LEVEL.INFO, "Rule Group Not Found.")
- return Promise.resolve()
+ if (error.code === 'ResourceNotFoundException') {
+ Logger.log(LOG_LEVEL.INFO, 'Rule Group Not Found.');
+ return Promise.resolve();
}
- return Promise.reject(error)
}
- } while (this.count == Count.minRetry)
+ } while (this.count < Count.minRetry);
+ Logger.log(LOG_LEVEL.ERROR, `Unable to retrieve rule group and exceeded the retry count`);
+ return Promise.reject({ message: 'Unable to resolve request and completed retries.' });
}
/** Associates the firewall policy to the firewall. */
async associateFirewallPolicy(request: NetworkFirewall.AssociateFirewallPolicyRequest) {
try {
- return await this.NetworkFirewallInstance.associateFirewallPolicy(request).promise()
+ return this.NetworkFirewallInstance.associateFirewallPolicy(request).promise();
} catch (error) {
- Logger.log(LOG_LEVEL.DEBUG, error)
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.DEBUG, error);
+ return Promise.reject(error);
}
}
/** associate tags to the firewall resource. */
async tagResource(request: NetworkFirewall.Types.TagResourceRequest) {
try {
- return await this.NetworkFirewallInstance.tagResource(request).promise()
+ return this.NetworkFirewallInstance.tagResource(request).promise();
} catch (error) {
- Logger.log(LOG_LEVEL.ERROR, `Failed to update tags for the firewall ${error}`)
+ Logger.log(LOG_LEVEL.ERROR, `Failed to update tags for the firewall ${error}`);
// returning resolve to avoid pipeline failure due to tag change failure.
- return Promise.resolve()
+ return Promise.resolve();
}
}
/** Updates the firewall policy and will override any configurations done to the firewall policy in the AWS console. Method will attempt multiple updates to the
* firewall policy until successful.
- */
+ */
async updateFirewallPolicy(request: NetworkFirewall.Types.UpdateFirewallPolicyRequest) {
do {
try {
- return await this.NetworkFirewallInstance.updateFirewallPolicy(request).promise()
- } catch (error) {
+ return await this.NetworkFirewallInstance.updateFirewallPolicy(request).promise();
+ } catch (error: any) {
if (error['message'] === 'Update token is invalid.') {
const describeResponse = await this.NetworkFirewallInstance.describeFirewallPolicy({
- FirewallPolicyName: request.FirewallPolicyName
- }).promise()
- request.UpdateToken = describeResponse.UpdateToken
+ FirewallPolicyName: request.FirewallPolicyName,
+ }).promise();
+ request.UpdateToken = describeResponse.UpdateToken;
} else {
- Logger.log(LOG_LEVEL.DEBUG, error)
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.DEBUG, error);
+ return Promise.reject(error);
}
}
- } while (request.UpdateToken)
- return Promise.resolve()
+ } while (request.UpdateToken);
+ return Promise.resolve();
}
async updateRuleGroup(updateRuleGroupRequest: NetworkFirewall.Types.UpdateRuleGroupRequest) {
@@ -175,18 +172,20 @@ export class NetworkFirewallService {
do {
try {
updateResponse = await this.NetworkFirewallInstance.updateRuleGroup(updateRuleGroupRequest).promise();
- updateRuleGroupRequest.UpdateToken = ''
- } catch (error) {
+ updateRuleGroupRequest.UpdateToken = '';
+ } catch (error: any) {
if (error['message'] == 'Update token is invalid.') {
- const describeResponse = await this.NetworkFirewallInstance.describeRuleGroup({ RuleGroupArn: updateRuleGroupRequest.RuleGroupArn }).promise()
- updateRuleGroupRequest.UpdateToken = describeResponse.UpdateToken
+ const describeResponse = await this.NetworkFirewallInstance.describeRuleGroup({
+ RuleGroupArn: updateRuleGroupRequest.RuleGroupArn,
+ }).promise();
+ updateRuleGroupRequest.UpdateToken = describeResponse.UpdateToken;
} else {
- Logger.log(LOG_LEVEL.INFO, `Error while trying to update the rule group ${updateRuleGroupRequest}: ${error}`)
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.INFO, `Error while trying to update the rule group ${updateRuleGroupRequest}: ${error}`);
+ return Promise.reject(error);
}
}
- } while (updateRuleGroupRequest.UpdateToken)
- Logger.log(LOG_LEVEL.INFO, `update response ${JSON.stringify(updateResponse)}`)
+ } while (updateRuleGroupRequest.UpdateToken);
+ Logger.log(LOG_LEVEL.INFO, `update response ${JSON.stringify(updateResponse)}`);
return Promise.resolve(updateResponse);
}
@@ -198,8 +197,8 @@ export class NetworkFirewallService {
try {
return await this.NetworkFirewallInstance.updateFirewallDescription(request).promise();
} catch (error) {
- Logger.log(LOG_LEVEL.DEBUG, error)
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.DEBUG, error);
+ return Promise.reject(error);
}
}
/**
@@ -210,8 +209,8 @@ export class NetworkFirewallService {
try {
return await this.NetworkFirewallInstance.updateFirewallDeleteProtection(request).promise();
} catch (error) {
- Logger.log(LOG_LEVEL.DEBUG, error)
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.DEBUG, error);
+ return Promise.reject(error);
}
}
@@ -219,12 +218,14 @@ export class NetworkFirewallService {
* Update the firewall policy change protection attribute.
* @param request NetworkFirewall.Types.UpdateFirewallPolicyChangeProtectionRequest
*/
- async updateFirewallPolicyChangeProtection(request: NetworkFirewall.Types.UpdateFirewallPolicyChangeProtectionRequest) {
+ async updateFirewallPolicyChangeProtection(
+ request: NetworkFirewall.Types.UpdateFirewallPolicyChangeProtectionRequest
+ ) {
try {
return await this.NetworkFirewallInstance.updateFirewallPolicyChangeProtection(request).promise();
} catch (error) {
- Logger.log(LOG_LEVEL.DEBUG, error)
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.DEBUG, error);
+ return Promise.reject(error);
}
}
/**
@@ -235,41 +236,50 @@ export class NetworkFirewallService {
try {
return await this.NetworkFirewallInstance.updateSubnetChangeProtection(request).promise();
} catch (error) {
- Logger.log(LOG_LEVEL.DEBUG, error)
- return Promise.reject(error)
+ Logger.log(LOG_LEVEL.DEBUG, error);
+ return Promise.reject(error);
}
}
- async updateLoggingConfiguration(firewallName: string, loggingConfiguration: NetworkFirewall.Types.LoggingConfiguration) {
- Logger.log(LOG_LEVEL.INFO, loggingConfiguration)
- let describeFirewallLoggingResponse
+ async updateLoggingConfiguration(
+ firewallName: string,
+ loggingConfiguration: NetworkFirewall.Types.LoggingConfiguration
+ ) {
+ Logger.log(LOG_LEVEL.INFO, loggingConfiguration);
+ let describeFirewallLoggingResponse;
try {
describeFirewallLoggingResponse = await this.NetworkFirewallInstance.describeLoggingConfiguration({
- FirewallName: firewallName
- }).promise()
+ FirewallName: firewallName,
+ }).promise();
Logger.log(LOG_LEVEL.INFO, describeFirewallLoggingResponse);
//cleaning up the configuration stack currently in the firewall.
- while (describeFirewallLoggingResponse.LoggingConfiguration && describeFirewallLoggingResponse.LoggingConfiguration.LogDestinationConfigs.length > 0) {
-
- Logger.log(LOG_LEVEL.INFO, describeFirewallLoggingResponse)
+ while (
+ describeFirewallLoggingResponse.LoggingConfiguration &&
+ describeFirewallLoggingResponse.LoggingConfiguration.LogDestinationConfigs.length > 0
+ ) {
+ Logger.log(LOG_LEVEL.INFO, describeFirewallLoggingResponse);
if (describeFirewallLoggingResponse.LoggingConfiguration) {
- describeFirewallLoggingResponse.LoggingConfiguration.LogDestinationConfigs.pop()
+ describeFirewallLoggingResponse.LoggingConfiguration.LogDestinationConfigs.pop();
}
- describeFirewallLoggingResponse = await this.NetworkFirewallInstance.updateLoggingConfiguration(describeFirewallLoggingResponse).promise()
+ describeFirewallLoggingResponse = await this.NetworkFirewallInstance.updateLoggingConfiguration(
+ describeFirewallLoggingResponse
+ ).promise();
}
for (let config of loggingConfiguration.LogDestinationConfigs) {
- describeFirewallLoggingResponse.LoggingConfiguration?.LogDestinationConfigs.push(config)
- describeFirewallLoggingResponse = await this.NetworkFirewallInstance.updateLoggingConfiguration(describeFirewallLoggingResponse).promise()
+ describeFirewallLoggingResponse.LoggingConfiguration?.LogDestinationConfigs.push(config);
+ describeFirewallLoggingResponse = await this.NetworkFirewallInstance.updateLoggingConfiguration(
+ describeFirewallLoggingResponse
+ ).promise();
}
- Logger.log(LOG_LEVEL.INFO, describeFirewallLoggingResponse)
+ Logger.log(LOG_LEVEL.INFO, describeFirewallLoggingResponse);
} catch (error) {
- Logger.log(LOG_LEVEL.INFO, `Failed to update firewall logging configuration`, error)
- return Promise.resolve()
+ Logger.log(LOG_LEVEL.INFO, `Failed to update firewall logging configuration`, error);
+ return Promise.resolve();
}
- return Promise.resolve(describeFirewallLoggingResponse)
+ return Promise.resolve(describeFirewallLoggingResponse);
}
async listRuleGroupsForPolicy(firewallPolicyName: string): Promise {
@@ -277,32 +287,32 @@ export class NetworkFirewallService {
let response;
try {
- response = await this.NetworkFirewallInstance.describeFirewallPolicy({ FirewallPolicyName: firewallPolicyName }).promise();
+ response = await this.NetworkFirewallInstance.describeFirewallPolicy({
+ FirewallPolicyName: firewallPolicyName,
+ }).promise();
if (response && response.FirewallPolicy) {
- response.FirewallPolicy?.StatefulRuleGroupReferences?.forEach((ruleGroup) => {
- ruleGroupArns.push(ruleGroup.ResourceArn)
- })
- response.FirewallPolicy?.StatelessRuleGroupReferences?.forEach((ruleGroup) => {
- ruleGroupArns.push(ruleGroup.ResourceArn)
- })
+ response.FirewallPolicy?.StatefulRuleGroupReferences?.forEach(ruleGroup => {
+ ruleGroupArns.push(ruleGroup.ResourceArn);
+ });
+ response.FirewallPolicy?.StatelessRuleGroupReferences?.forEach(ruleGroup => {
+ ruleGroupArns.push(ruleGroup.ResourceArn);
+ });
} else {
- Logger.log(LOG_LEVEL.INFO, `No firewall policy of the name: ${firewallPolicyName}`)
- return Promise.resolve([])
+ Logger.log(LOG_LEVEL.INFO, `No firewall policy of the name: ${firewallPolicyName}`);
+ return Promise.resolve([]);
}
- return Promise.resolve(ruleGroupArns)
+ return Promise.resolve(ruleGroupArns);
} catch (error) {
- Logger.log(LOG_LEVEL.INFO, `Error trying to retrieve current rule groups configured ${JSON.stringify(error)}`)
- return Promise.resolve([])
+ Logger.log(LOG_LEVEL.INFO, `Error trying to retrieve current rule groups configured ${JSON.stringify(error)}`);
+ return Promise.resolve([]);
}
-
}
async deleteRuleGroup(ruleGroupArn: string) {
try {
- await this.NetworkFirewallInstance.deleteRuleGroup({ RuleGroupArn: ruleGroupArn }).promise()
+ await this.NetworkFirewallInstance.deleteRuleGroup({ RuleGroupArn: ruleGroupArn }).promise();
} catch (error) {
- Logger.log(LOG_LEVEL.INFO, `Unable to delete rule group ${JSON.stringify(error)}`)
+ Logger.log(LOG_LEVEL.INFO, `Unable to delete rule group ${JSON.stringify(error)}`);
}
}
-
}
diff --git a/source/networkFirewallAutomation/package-lock.json b/source/networkFirewallAutomation/package-lock.json
new file mode 100644
index 0000000..01b2003
--- /dev/null
+++ b/source/networkFirewallAutomation/package-lock.json
@@ -0,0 +1,7962 @@
+{
+ "name": "network-firewall",
+ "version": "1.0.2",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "network-firewall",
+ "version": "1.0.2",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "aws-sdk": "^2.804.0",
+ "axios": "^0.21.1",
+ "moment": "^2.27.0",
+ "uuid": "^8.3.2"
+ },
+ "devDependencies": {
+ "@types/jest": "~27.0.1",
+ "@types/moment": "^2.13.0",
+ "@types/node": "~16.7.2",
+ "@types/uuid": "^8.3.0",
+ "aws-sdk-mock": "^5.1.0",
+ "jest": "~29.3.1",
+ "ts-jest": "~29.0.3",
+ "ts-node": "~10.2.1",
+ "typescript": "~4.4.2"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.20.10",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz",
+ "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz",
+ "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helpers": "^7.20.7",
+ "@babel/parser": "^7.20.7",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.12",
+ "@babel/types": "^7.20.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.2",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz",
+ "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.20.7",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+ "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.20.5",
+ "@babel/helper-validator-option": "^7.18.6",
+ "browserslist": "^4.21.3",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
+ "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.18.10",
+ "@babel/types": "^7.19.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+ "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+ "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
+ "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-simple-access": "^7.20.2",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.10",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+ "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+ "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.19.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+ "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
+ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz",
+ "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz",
+ "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
+ "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.19.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+ "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
+ "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
+ "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.19.4",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "node_modules/@cspotcode/source-map-consumer": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
+ "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
+ "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-consumer": "0.8.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz",
+ "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz",
+ "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^29.3.1",
+ "@jest/reporters": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.2.0",
+ "jest-config": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-resolve-dependencies": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/core/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@jest/core/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/core/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/@jest/environment": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz",
+ "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==",
+ "dev": true,
+ "dependencies": {
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==",
+ "dev": true,
+ "dependencies": {
+ "expect": "^29.3.1",
+ "jest-snapshot": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
+ "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
+ "dev": true,
+ "dependencies": {
+ "jest-get-type": "^29.2.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz",
+ "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@sinonjs/fake-timers": "^9.1.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers/node_modules/@sinonjs/fake-timers": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
+ "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz",
+ "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "jest-mock": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz",
+ "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==",
+ "dev": true,
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^5.1.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.0.0",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
+ "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
+ "dev": true,
+ "dependencies": {
+ "@sinclair/typebox": "^0.24.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz",
+ "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz",
+ "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz",
+ "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/test-result": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz",
+ "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
+ "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.24.51",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+ "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
+ "dev": true
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
+ "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==",
+ "dev": true,
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "node_modules/@sinonjs/formatio": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz",
+ "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1",
+ "@sinonjs/samsam": "^5.0.2"
+ }
+ },
+ "node_modules/@sinonjs/samsam": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.2.0.tgz",
+ "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.6.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/text-encoding": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
+ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
+ "dev": true
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.1.20",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
+ "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+ "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
+ "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
+ "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz",
+ "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==",
+ "dev": true,
+ "dependencies": {
+ "jest-diff": "^27.0.0",
+ "pretty-format": "^27.0.0"
+ }
+ },
+ "node_modules/@types/moment": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/@types/moment/-/moment-2.13.0.tgz",
+ "integrity": "sha1-YE69GJvDvDShVIaJQE5hoqSqyJY=",
+ "dev": true,
+ "dependencies": {
+ "moment": "*"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "16.7.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.13.tgz",
+ "integrity": "sha512-pLUPDn+YG3FYEt/pHI74HmnJOWzeR+tOIQzUx93pi9M7D8OE7PSLr97HboXwk5F+JS+TLtWuzCOW97AHjmOXXA==",
+ "dev": true
+ },
+ "node_modules/@types/prettier": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
+ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
+ "dev": true
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+ "dev": true
+ },
+ "node_modules/@types/uuid": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==",
+ "dev": true
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.19",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
+ "integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/aws-sdk": {
+ "version": "2.1261.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1261.0.tgz",
+ "integrity": "sha512-Lumifi52Vj6ss1tlZ9Z+BvJ+Yk2MTwPQyrDCZh79xggFgXYoDU/g4rZUr47/1AXBZje3mVkLeRM15hvUwKlTaA==",
+ "dependencies": {
+ "buffer": "4.9.2",
+ "events": "1.1.1",
+ "ieee754": "1.1.13",
+ "jmespath": "0.16.0",
+ "querystring": "0.2.0",
+ "sax": "1.2.1",
+ "url": "0.10.3",
+ "util": "^0.12.4",
+ "uuid": "8.0.0",
+ "xml2js": "0.4.19"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/aws-sdk-mock": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk-mock/-/aws-sdk-mock-5.1.0.tgz",
+ "integrity": "sha512-Wa5eCSo8HX0Snqb7FdBylaXMmfrAWoWZ+d7MFhiYsgHPvNvMEGjV945FF2qqE1U0Tolr1ALzik1fcwgaOhqUWQ==",
+ "dev": true,
+ "dependencies": {
+ "aws-sdk": "^2.637.0",
+ "sinon": "^9.0.1",
+ "traverse": "^0.6.6"
+ }
+ },
+ "node_modules/aws-sdk/node_modules/uuid": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz",
+ "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/axios": {
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+ "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+ "dependencies": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
+ "node_modules/babel-jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz",
+ "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/transform": "^29.3.1",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.2.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz",
+ "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz",
+ "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==",
+ "dev": true,
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^29.2.0",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "dependencies": {
+ "fast-json-stable-stringify": "2.x"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "4.9.2",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+ "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+ "dependencies": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4",
+ "isarray": "^1.0.0"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001442",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz",
+ "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz",
+ "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
+ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
+ "dev": true
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
+ "dev": true
+ },
+ "node_modules/deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
+ "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.284",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
+ "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
+ "dev": true
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/events": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/expect-utils": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/expect/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+ "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "dependencies": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "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"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "dependencies": {
+ "has-symbols": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
+ },
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/is-arguments": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+ "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "node_modules/is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "dependencies": {
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-typed-array": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+ "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz",
+ "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/core": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz",
+ "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==",
+ "dev": true,
+ "dependencies": {
+ "execa": "^5.0.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz",
+ "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-circus/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-cli": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz",
+ "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/core": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "prompts": "^2.0.1",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz",
+ "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "babel-jest": "^29.3.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.3.1",
+ "jest-environment-node": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-config/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-config/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-config/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-diff": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz",
+ "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.5.1",
+ "jest-get-type": "^27.5.1",
+ "pretty-format": "^27.5.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-docblock": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz",
+ "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==",
+ "dev": true,
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz",
+ "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-each/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-environment-node": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz",
+ "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-get-type": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz",
+ "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz",
+ "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz",
+ "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==",
+ "dev": true,
+ "dependencies": {
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
+ "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-message-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
+ "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.3.1",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-mock": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz",
+ "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz",
+ "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz",
+ "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^1.1.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz",
+ "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==",
+ "dev": true,
+ "dependencies": {
+ "jest-regex-util": "^29.2.0",
+ "jest-snapshot": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz",
+ "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^29.3.1",
+ "@jest/environment": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.2.0",
+ "jest-environment-node": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-leak-detector": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-resolve": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz",
+ "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/globals": "^29.3.1",
+ "@jest/source-map": "^29.2.0",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz",
+ "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/babel__traverse": "^7.0.6",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-haste-map": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.3.1",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-snapshot/node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
+ "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz",
+ "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-validate/node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-watcher": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz",
+ "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.3.1",
+ "string-length": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz",
+ "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.3.1",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/jmespath": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
+ "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/just-extend": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz",
+ "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==",
+ "dev": true
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "dev": true
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/nise": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz",
+ "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0",
+ "@sinonjs/fake-timers": "^6.0.0",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
+ "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==",
+ "dev": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "dev": true,
+ "dependencies": {
+ "isarray": "0.0.1"
+ }
+ },
+ "node_modules/path-to-regexp/node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+ "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+ },
+ "node_modules/querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve.exports": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz",
+ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/sax": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
+ "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
+ },
+ "node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/sinon": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz",
+ "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.8.1",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@sinonjs/formatio": "^5.0.1",
+ "@sinonjs/samsam": "^5.2.0",
+ "diff": "^4.0.2",
+ "nise": "^4.0.4",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/traverse": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
+ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=",
+ "dev": true
+ },
+ "node_modules/ts-jest": {
+ "version": "29.0.3",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
+ "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "dev": true,
+ "dependencies": {
+ "bs-logger": "0.x",
+ "fast-json-stable-stringify": "2.x",
+ "jest-util": "^29.0.0",
+ "json5": "^2.2.1",
+ "lodash.memoize": "4.x",
+ "make-error": "1.x",
+ "semver": "7.x",
+ "yargs-parser": "^21.0.1"
+ },
+ "bin": {
+ "ts-jest": "cli.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7.0.0-beta.0 <8",
+ "@jest/types": "^29.0.0",
+ "babel-jest": "^29.0.0",
+ "jest": "^29.0.0",
+ "typescript": ">=4.3"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@jest/types": {
+ "optional": true
+ },
+ "babel-jest": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-jest/node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz",
+ "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-support": "0.6.1",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-node/node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
+ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist-lint": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/url": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
+ "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
+ "dependencies": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ }
+ },
+ "node_modules/util": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+ "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+ "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/xml2js": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+ "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+ "dependencies": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~9.0.1"
+ }
+ },
+ "node_modules/xmlbuilder": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/yargs": {
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.18.6"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.20.10",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz",
+ "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz",
+ "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helpers": "^7.20.7",
+ "@babel/parser": "^7.20.7",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.12",
+ "@babel/types": "^7.20.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.2",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz",
+ "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.20.7",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "jsesc": "^2.5.1"
+ },
+ "dependencies": {
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ }
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+ "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.20.5",
+ "@babel/helper-validator-option": "^7.18.6",
+ "browserslist": "^4.21.3",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-environment-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "dev": true
+ },
+ "@babel/helper-function-name": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
+ "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.18.10",
+ "@babel/types": "^7.19.0"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+ "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+ "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
+ "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-simple-access": "^7.20.2",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.10",
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+ "dev": true
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+ "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.20.2"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+ "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.19.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+ "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "dev": true
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "dev": true
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
+ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
+ "dev": true
+ },
+ "@babel/helpers": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz",
+ "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@babel/parser": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz",
+ "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==",
+ "dev": true
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ }
+ },
+ "@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ }
+ },
+ "@babel/plugin-syntax-typescript": {
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
+ "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.19.0"
+ }
+ },
+ "@babel/template": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+ "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
+ "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/types": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
+ "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-string-parser": "^7.19.4",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "@cspotcode/source-map-consumer": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
+ "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
+ "dev": true
+ },
+ "@cspotcode/source-map-support": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
+ "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
+ "dev": true,
+ "requires": {
+ "@cspotcode/source-map-consumer": "0.8.0"
+ }
+ },
+ "@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true
+ },
+ "@jest/console": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz",
+ "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0"
+ }
+ },
+ "@jest/core": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz",
+ "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^29.3.1",
+ "@jest/reporters": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.2.0",
+ "jest-config": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-resolve-dependencies": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/environment": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz",
+ "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==",
+ "dev": true,
+ "requires": {
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1"
+ }
+ },
+ "@jest/expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==",
+ "dev": true,
+ "requires": {
+ "expect": "^29.3.1",
+ "jest-snapshot": "^29.3.1"
+ }
+ },
+ "@jest/expect-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
+ "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^29.2.0"
+ },
+ "dependencies": {
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz",
+ "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@sinonjs/fake-timers": "^9.1.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "dependencies": {
+ "@sinonjs/fake-timers": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
+ "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ }
+ }
+ },
+ "@jest/globals": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz",
+ "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "jest-mock": "^29.3.1"
+ }
+ },
+ "@jest/reporters": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz",
+ "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==",
+ "dev": true,
+ "requires": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^5.1.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ }
+ },
+ "@jest/schemas": {
+ "version": "29.0.0",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
+ "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
+ "dev": true,
+ "requires": {
+ "@sinclair/typebox": "^0.24.1"
+ }
+ },
+ "@jest/source-map": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz",
+ "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ }
+ },
+ "@jest/test-result": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz",
+ "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ }
+ },
+ "@jest/test-sequencer": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz",
+ "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "slash": "^3.0.0"
+ }
+ },
+ "@jest/transform": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz",
+ "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.1"
+ }
+ },
+ "@jest/types": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
+ "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "@sinclair/typebox": {
+ "version": "0.24.51",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+ "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
+ "dev": true
+ },
+ "@sinonjs/commons": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz",
+ "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@sinonjs/fake-timers": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz",
+ "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "@sinonjs/formatio": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz",
+ "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1",
+ "@sinonjs/samsam": "^5.0.2"
+ }
+ },
+ "@sinonjs/samsam": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.2.0.tgz",
+ "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.6.0",
+ "lodash.get": "^4.4.2",
+ "type-detect": "^4.0.8"
+ }
+ },
+ "@sinonjs/text-encoding": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz",
+ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==",
+ "dev": true
+ },
+ "@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "@tsconfig/node16": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
+ "dev": true
+ },
+ "@types/babel__core": {
+ "version": "7.1.20",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
+ "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "@types/babel__generator": {
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+ "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__template": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__traverse": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
+ "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "@types/graceful-fs": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
+ "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
+ "@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "@types/jest": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz",
+ "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==",
+ "dev": true,
+ "requires": {
+ "jest-diff": "^27.0.0",
+ "pretty-format": "^27.0.0"
+ }
+ },
+ "@types/moment": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/@types/moment/-/moment-2.13.0.tgz",
+ "integrity": "sha1-YE69GJvDvDShVIaJQE5hoqSqyJY=",
+ "dev": true,
+ "requires": {
+ "moment": "*"
+ }
+ },
+ "@types/node": {
+ "version": "16.7.13",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.7.13.tgz",
+ "integrity": "sha512-pLUPDn+YG3FYEt/pHI74HmnJOWzeR+tOIQzUx93pi9M7D8OE7PSLr97HboXwk5F+JS+TLtWuzCOW97AHjmOXXA==",
+ "dev": true
+ },
+ "@types/prettier": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
+ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
+ "dev": true
+ },
+ "@types/stack-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+ "dev": true
+ },
+ "@types/uuid": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.0.tgz",
+ "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==",
+ "dev": true
+ },
+ "@types/yargs": {
+ "version": "17.0.19",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
+ "integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "@types/yargs-parser": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.21.3"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
+ },
+ "aws-sdk": {
+ "version": "2.1261.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1261.0.tgz",
+ "integrity": "sha512-Lumifi52Vj6ss1tlZ9Z+BvJ+Yk2MTwPQyrDCZh79xggFgXYoDU/g4rZUr47/1AXBZje3mVkLeRM15hvUwKlTaA==",
+ "requires": {
+ "buffer": "4.9.2",
+ "events": "1.1.1",
+ "ieee754": "1.1.13",
+ "jmespath": "0.16.0",
+ "querystring": "0.2.0",
+ "sax": "1.2.1",
+ "url": "0.10.3",
+ "util": "^0.12.4",
+ "uuid": "8.0.0",
+ "xml2js": "0.4.19"
+ },
+ "dependencies": {
+ "uuid": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz",
+ "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw=="
+ }
+ }
+ },
+ "aws-sdk-mock": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk-mock/-/aws-sdk-mock-5.1.0.tgz",
+ "integrity": "sha512-Wa5eCSo8HX0Snqb7FdBylaXMmfrAWoWZ+d7MFhiYsgHPvNvMEGjV945FF2qqE1U0Tolr1ALzik1fcwgaOhqUWQ==",
+ "dev": true,
+ "requires": {
+ "aws-sdk": "^2.637.0",
+ "sinon": "^9.0.1",
+ "traverse": "^0.6.6"
+ }
+ },
+ "axios": {
+ "version": "0.21.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
+ "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
+ "requires": {
+ "follow-redirects": "^1.14.0"
+ }
+ },
+ "babel-jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz",
+ "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==",
+ "dev": true,
+ "requires": {
+ "@jest/transform": "^29.3.1",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.2.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ }
+ },
+ "babel-plugin-jest-hoist": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz",
+ "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ }
+ },
+ "babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ }
+ },
+ "babel-preset-jest": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz",
+ "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-jest-hoist": "^29.2.0",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ }
+ },
+ "bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "requires": {
+ "fast-json-stable-stringify": "2.x"
+ }
+ },
+ "bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "requires": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "buffer": {
+ "version": "4.9.2",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
+ "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4",
+ "isarray": "^1.0.0"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001442",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz",
+ "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz",
+ "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==",
+ "dev": true
+ },
+ "cjs-module-lexer": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
+ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true
+ },
+ "collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
+ },
+ "detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
+ "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==",
+ "dev": true
+ },
+ "electron-to-chromium": {
+ "version": "1.4.284",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
+ "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
+ "dev": true
+ },
+ "emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "events": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
+ },
+ "execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true
+ },
+ "expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
+ "dev": true,
+ "requires": {
+ "@jest/expect-utils": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "dependencies": {
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ }
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "requires": {
+ "bser": "2.1.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.15.2",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
+ "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
+ },
+ "for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "requires": {
+ "is-callable": "^1.1.3"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-intrinsic": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
+ "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
+ "gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "requires": {
+ "get-intrinsic": "^1.1.3"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+ },
+ "has-tostringtag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
+ "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
+ "requires": {
+ "has-symbols": "^1.0.2"
+ }
+ },
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true
+ },
+ "ieee754": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
+ },
+ "import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "is-arguments": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
+ "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+ "requires": {
+ "call-bind": "^1.0.2",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "is-callable": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
+ "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="
+ },
+ "is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true
+ },
+ "is-generator-function": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
+ "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "requires": {
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "is-typed-array": {
+ "version": "1.1.10",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
+ "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "requires": {
+ "@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"
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ }
+ },
+ "istanbul-reports": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ }
+ },
+ "jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz",
+ "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.3.1"
+ }
+ },
+ "jest-changed-files": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz",
+ "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==",
+ "dev": true,
+ "requires": {
+ "execa": "^5.0.0",
+ "p-limit": "^3.1.0"
+ }
+ },
+ "jest-circus": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz",
+ "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-cli": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz",
+ "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "prompts": "^2.0.1",
+ "yargs": "^17.3.1"
+ }
+ },
+ "jest-config": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz",
+ "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "babel-jest": "^29.3.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.3.1",
+ "jest-environment-node": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-diff": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz",
+ "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.5.1",
+ "jest-get-type": "^27.5.1",
+ "pretty-format": "^27.5.1"
+ }
+ },
+ "jest-docblock": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz",
+ "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "^3.0.0"
+ }
+ },
+ "jest-each": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz",
+ "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-environment-node": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz",
+ "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ }
+ },
+ "jest-get-type": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz",
+ "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==",
+ "dev": true
+ },
+ "jest-haste-map": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz",
+ "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ }
+ },
+ "jest-leak-detector": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz",
+ "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-matcher-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
+ "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true
+ },
+ "jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ }
+ },
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-message-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
+ "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.3.1",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-mock": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz",
+ "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-util": "^29.3.1"
+ }
+ },
+ "jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "requires": {}
+ },
+ "jest-regex-util": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz",
+ "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==",
+ "dev": true
+ },
+ "jest-resolve": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz",
+ "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^1.1.0",
+ "slash": "^3.0.0"
+ }
+ },
+ "jest-resolve-dependencies": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz",
+ "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==",
+ "dev": true,
+ "requires": {
+ "jest-regex-util": "^29.2.0",
+ "jest-snapshot": "^29.3.1"
+ }
+ },
+ "jest-runner": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz",
+ "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^29.3.1",
+ "@jest/environment": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.2.0",
+ "jest-environment-node": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-leak-detector": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-resolve": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ }
+ },
+ "jest-runtime": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz",
+ "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/globals": "^29.3.1",
+ "@jest/source-map": "^29.2.0",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ }
+ },
+ "jest-snapshot": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz",
+ "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/babel__traverse": "^7.0.6",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-haste-map": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.3.1",
+ "semver": "^7.3.5"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true
+ },
+ "jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ }
+ },
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "jest-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
+ "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "jest-validate": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz",
+ "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true
+ },
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-watcher": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz",
+ "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.3.1",
+ "string-length": "^4.0.1"
+ }
+ },
+ "jest-worker": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz",
+ "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "jest-util": "^29.3.1",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "jmespath": {
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
+ "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw=="
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true
+ },
+ "just-extend": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz",
+ "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==",
+ "dev": true
+ },
+ "kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true
+ },
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
+ },
+ "lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "dev": true
+ },
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ }
+ },
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "requires": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "nise": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz",
+ "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0",
+ "@sinonjs/fake-timers": "^6.0.0",
+ "@sinonjs/text-encoding": "^0.7.1",
+ "just-extend": "^4.0.2",
+ "path-to-regexp": "^1.7.0"
+ }
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true
+ },
+ "node-releases": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
+ "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ },
+ "dependencies": {
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ }
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "path-to-regexp": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
+ "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
+ "dev": true,
+ "requires": {
+ "isarray": "0.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ }
+ }
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "pirates": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+ "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ }
+ },
+ "pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "requires": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "resolve.exports": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz",
+ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==",
+ "dev": true
+ },
+ "sax": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
+ "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "sinon": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz",
+ "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.8.1",
+ "@sinonjs/fake-timers": "^6.0.1",
+ "@sinonjs/formatio": "^5.0.1",
+ "@sinonjs/samsam": "^5.2.0",
+ "diff": "^4.0.2",
+ "nise": "^4.0.4",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ }
+ },
+ "string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "requires": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true
+ },
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "traverse": {
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz",
+ "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=",
+ "dev": true
+ },
+ "ts-jest": {
+ "version": "29.0.3",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
+ "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "dev": true,
+ "requires": {
+ "bs-logger": "0.x",
+ "fast-json-stable-stringify": "2.x",
+ "jest-util": "^29.0.0",
+ "json5": "^2.2.1",
+ "lodash.memoize": "4.x",
+ "make-error": "1.x",
+ "semver": "7.x",
+ "yargs-parser": "^21.0.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "ts-node": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz",
+ "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==",
+ "dev": true,
+ "requires": {
+ "@cspotcode/source-map-support": "0.6.1",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "yn": "3.1.1"
+ },
+ "dependencies": {
+ "acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true
+ }
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
+ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+ "dev": true
+ },
+ "update-browserslist-db": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "dev": true,
+ "requires": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ }
+ },
+ "url": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
+ "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ }
+ },
+ "util": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
+ "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "is-arguments": "^1.0.4",
+ "is-generator-function": "^1.0.7",
+ "is-typed-array": "^1.1.3",
+ "which-typed-array": "^1.1.2"
+ }
+ },
+ "uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="
+ },
+ "v8-to-istanbul": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ }
+ }
+ },
+ "walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "requires": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-typed-array": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
+ "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
+ "requires": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0",
+ "is-typed-array": "^1.1.10"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ }
+ },
+ "xml2js": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+ "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+ "requires": {
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~9.0.1"
+ }
+ },
+ "xmlbuilder": {
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ }
+ },
+ "yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true
+ },
+ "yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true
+ }
+ }
+}
diff --git a/source/networkFirewallAutomation/package.json b/source/networkFirewallAutomation/package.json
index 73cf13e..14de8a3 100644
--- a/source/networkFirewallAutomation/package.json
+++ b/source/networkFirewallAutomation/package.json
@@ -1,7 +1,7 @@
{
"name": "network-firewall",
- "version": "1.0.0",
- "description": "Network Firewall Manager",
+ "version": "1.0.2",
+ "description": "Firewall Automation for Network Traffic on AWS",
"main": "index.js",
"types": "index.d.ts",
"author": "@aws-solutions",
@@ -19,7 +19,7 @@
"watch": "tsc -w",
"test": "jest --coverage --silent",
"test-debug": "jest --coverage",
- "cdk": "cdk",
+ "cdk": "npx cdk",
"build:tsc": "tsc",
"build-init": "rm -rf dist && rm -f archive.zip && rm -rf coverage && mkdir -p dist/lib/service && mkdir -p dist/lib/common/configReader",
"build:copy": "for file in `find . -name '*.js' | egrep -v '__tests__|node_modules'`;do echo \"Copying $file\"; cp $file dist/$file; done",
@@ -28,15 +28,14 @@
"zip": "cd dist && zip -rq network-firewall-automation.zip ."
},
"devDependencies": {
- "@types/jest": "^26.0.0",
"@types/moment": "^2.13.0",
- "@types/node": "^14.14.10",
"@types/uuid": "^8.3.0",
"aws-sdk-mock": "^5.1.0",
- "jest": "^25.0.0",
- "jest-sonar-reporter": "^2.0.0",
- "ts-jest": "^25.3.1",
- "ts-node": "^9.0.0",
- "typescript": "^3.4.0"
+ "@types/jest": "~27.0.1",
+ "@types/node": "~16.7.2",
+ "jest": "~29.3.1",
+ "ts-jest": "~29.0.3",
+ "ts-node": "~10.2.1",
+ "typescript": "~4.4.2"
}
}
diff --git a/source/networkFirewallAutomation/tsconfig.json b/source/networkFirewallAutomation/tsconfig.json
index 07afb1f..6b99169 100644
--- a/source/networkFirewallAutomation/tsconfig.json
+++ b/source/networkFirewallAutomation/tsconfig.json
@@ -6,9 +6,7 @@
"experimentalDecorators": true,
"inlineSourceMap": true,
"inlineSources": true,
- "lib": [
- "es2018"
- ],
+ "lib": ["es2018"],
"module": "CommonJS",
"noEmitOnError": true,
"noFallthroughCasesInSwitch": true,
@@ -24,11 +22,7 @@
"stripInternal": true,
"target": "ES2018"
},
- "include": [
- "**/*.ts"
- ],
- "exclude": [
- "node_modules"
- ],
+ "include": ["**/*.ts", "jest.config.js"],
+ "exclude": ["node_modules"],
"_generated_by_jsii_": "Generated by jsii - safe to delete, and ideally should be in .gitignore"
}
diff --git a/source/package-lock.json b/source/package-lock.json
new file mode 100644
index 0000000..923fde9
--- /dev/null
+++ b/source/package-lock.json
@@ -0,0 +1,7484 @@
+{
+ "name": "network-firewall-automation-solution",
+ "version": "1.0.2",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "network-firewall-automation-solution",
+ "version": "1.0.2",
+ "license": "Apache-2.0",
+ "bin": {
+ "network-firewall-auto-solution": "bin/network-firewall-auto-solution.js"
+ },
+ "devDependencies": {
+ "@types/jest": "~27.0.1",
+ "@types/node": "~18.6.2",
+ "aws-cdk": "^2.55.0",
+ "aws-cdk-lib": "^2.55.0",
+ "constructs": "^10.0.0",
+ "jest": "~29.3.1",
+ "ts-jest": "~29.0.3",
+ "ts-node": "~10.9.1",
+ "typescript": "~4.7.4"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@aws-cdk/asset-awscli-v1": {
+ "version": "2.2.30",
+ "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.30.tgz",
+ "integrity": "sha512-mFRF5n1jxjKpX8ZZSCRhJc6Hj8BkeZFUPwK0j6jRcouQQZHsZyydbf4UuzMYQ4SZU6cCLM7DKmWO0Kx156ZSnw==",
+ "dev": true
+ },
+ "node_modules/@aws-cdk/asset-kubectl-v20": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.1.tgz",
+ "integrity": "sha512-U1ntiX8XiMRRRH5J1IdC+1t5CE89015cwyt5U63Cpk0GnMlN5+h9WsWMlKlPXZR4rdq/m806JRlBMRpBUB2Dhw==",
+ "dev": true
+ },
+ "node_modules/@aws-cdk/asset-node-proxy-agent-v5": {
+ "version": "2.0.38",
+ "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.38.tgz",
+ "integrity": "sha512-BBwAjORhuUkTGO3CxGS5Evcp5n20h9v06Sftn2R1DuSm8zIoUlPsNlI1HUk8XqYuoEI4aD7IKRQBLglv09ciJQ==",
+ "dev": true
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.20.10",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz",
+ "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz",
+ "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helpers": "^7.20.7",
+ "@babel/parser": "^7.20.7",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.12",
+ "@babel/types": "^7.20.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.2",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz",
+ "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.20.7",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+ "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.20.5",
+ "@babel/helper-validator-option": "^7.18.6",
+ "browserslist": "^4.21.3",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
+ "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.18.10",
+ "@babel/types": "^7.19.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+ "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+ "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
+ "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-simple-access": "^7.20.2",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.10",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+ "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.20.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+ "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.19.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+ "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
+ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz",
+ "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz",
+ "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
+ "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.19.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+ "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
+ "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
+ "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.19.4",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "node_modules/@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz",
+ "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz",
+ "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^29.3.1",
+ "@jest/reporters": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.2.0",
+ "jest-config": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-resolve-dependencies": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/core/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@jest/core/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/core/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/@jest/environment": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz",
+ "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==",
+ "dev": true,
+ "dependencies": {
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==",
+ "dev": true,
+ "dependencies": {
+ "expect": "^29.3.1",
+ "jest-snapshot": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
+ "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
+ "dev": true,
+ "dependencies": {
+ "jest-get-type": "^29.2.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz",
+ "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@sinonjs/fake-timers": "^9.1.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz",
+ "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "jest-mock": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz",
+ "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==",
+ "dev": true,
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^5.1.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.0.0",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
+ "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
+ "dev": true,
+ "dependencies": {
+ "@sinclair/typebox": "^0.24.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz",
+ "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz",
+ "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz",
+ "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/test-result": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz",
+ "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
+ "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.24.51",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+ "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
+ "dev": true
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+ "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
+ "dev": true,
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
+ "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
+ "dev": true,
+ "dependencies": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "node_modules/@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "node_modules/@tsconfig/node16": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
+ "dev": true
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.1.20",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
+ "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+ "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
+ "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
+ "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jest": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz",
+ "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==",
+ "dev": true,
+ "dependencies": {
+ "jest-diff": "^27.0.0",
+ "pretty-format": "^27.0.0"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "18.6.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.5.tgz",
+ "integrity": "sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==",
+ "dev": true
+ },
+ "node_modules/@types/prettier": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
+ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
+ "dev": true
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+ "dev": true
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.19",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
+ "integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
+ "dev": true
+ },
+ "node_modules/acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "dev": true,
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/aws-cdk": {
+ "version": "2.55.0",
+ "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.55.0.tgz",
+ "integrity": "sha512-SlsaKh1tEiFLWas99OffxoTLugkEZZHY552QeY4ZPXJaUx9kocGYc9s13IO8Y9/cBfoQVvh2KLev4J2+63vKyg==",
+ "dev": true,
+ "bin": {
+ "cdk": "bin/cdk"
+ },
+ "engines": {
+ "node": ">= 14.15.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "node_modules/aws-cdk-lib": {
+ "version": "2.55.0",
+ "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.55.0.tgz",
+ "integrity": "sha512-YCtfmMiITU5ncrrQmq5wls2EeCUOLOBDLWO2ZkaUozIS+VbEDChK8rT66OmgQSPwFntKNSJq0P65tR7kN5/i8g==",
+ "bundleDependencies": [
+ "@balena/dockerignore",
+ "case",
+ "fs-extra",
+ "ignore",
+ "jsonschema",
+ "minimatch",
+ "punycode",
+ "semver",
+ "yaml"
+ ],
+ "dev": true,
+ "dependencies": {
+ "@aws-cdk/asset-awscli-v1": "^2.2.30",
+ "@aws-cdk/asset-kubectl-v20": "^2.1.1",
+ "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.38",
+ "@balena/dockerignore": "^1.0.2",
+ "case": "1.6.3",
+ "fs-extra": "^9.1.0",
+ "ignore": "^5.2.1",
+ "jsonschema": "^1.4.1",
+ "minimatch": "^3.1.2",
+ "punycode": "^2.1.1",
+ "semver": "^7.3.8",
+ "yaml": "1.10.2"
+ },
+ "engines": {
+ "node": ">= 14.15.0"
+ },
+ "peerDependencies": {
+ "constructs": "^10.0.0"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": {
+ "version": "1.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/aws-cdk-lib/node_modules/at-least-node": {
+ "version": "1.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/aws-cdk-lib/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/case": {
+ "version": "1.6.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "(MIT OR GPL-3.0-or-later)",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/concat-map": {
+ "version": "0.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/aws-cdk-lib/node_modules/fs-extra": {
+ "version": "9.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/aws-cdk-lib/node_modules/ignore": {
+ "version": "5.2.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/jsonschema": {
+ "version": "1.4.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/minimatch": {
+ "version": "3.1.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/punycode": {
+ "version": "2.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/semver": {
+ "version": "7.3.8",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/universalify": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/aws-cdk-lib/node_modules/yallist": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/aws-cdk-lib/node_modules/yaml": {
+ "version": "1.10.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/babel-jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz",
+ "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/transform": "^29.3.1",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.2.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz",
+ "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz",
+ "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==",
+ "dev": true,
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^29.2.0",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "dependencies": {
+ "fast-json-stable-stringify": "2.x"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001442",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz",
+ "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ }
+ ]
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz",
+ "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
+ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
+ "dev": true
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "node_modules/constructs": {
+ "version": "10.1.190",
+ "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.1.190.tgz",
+ "integrity": "sha512-wGMEBsIKp/tP+b2q3XEtIh/KJPZ2uk7G2XyEbGVEatOo6OQHFhXfBi9BCk8725zuWYP/gZUQJfAvd7KZ+lY5Yw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 14.17.0"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
+ "dev": true
+ },
+ "node_modules/deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
+ "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.284",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
+ "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
+ "dev": true
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/expect-utils": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "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"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "node_modules/is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz",
+ "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/core": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz",
+ "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==",
+ "dev": true,
+ "dependencies": {
+ "execa": "^5.0.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz",
+ "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-circus/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-cli": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz",
+ "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/core": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "prompts": "^2.0.1",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz",
+ "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "babel-jest": "^29.3.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.3.1",
+ "jest-environment-node": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-config/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-config/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-diff": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz",
+ "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.5.1",
+ "jest-get-type": "^27.5.1",
+ "pretty-format": "^27.5.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-diff/node_modules/jest-get-type": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz",
+ "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==",
+ "dev": true,
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/jest-docblock": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz",
+ "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==",
+ "dev": true,
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz",
+ "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-each/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-environment-node": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz",
+ "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz",
+ "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz",
+ "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==",
+ "dev": true,
+ "dependencies": {
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-leak-detector/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
+ "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-message-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
+ "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.3.1",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-mock": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz",
+ "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-util": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz",
+ "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz",
+ "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^1.1.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz",
+ "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==",
+ "dev": true,
+ "dependencies": {
+ "jest-regex-util": "^29.2.0",
+ "jest-snapshot": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz",
+ "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==",
+ "dev": true,
+ "dependencies": {
+ "@jest/console": "^29.3.1",
+ "@jest/environment": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.2.0",
+ "jest-environment-node": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-leak-detector": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-resolve": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz",
+ "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==",
+ "dev": true,
+ "dependencies": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/globals": "^29.3.1",
+ "@jest/source-map": "^29.2.0",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz",
+ "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/babel__traverse": "^7.0.6",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-haste-map": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.3.1",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true,
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-snapshot/node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
+ "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz",
+ "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==",
+ "dev": true,
+ "dependencies": {
+ "@jest/types": "^29.3.1",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.3.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-validate/node_modules/pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "node_modules/jest-watcher": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz",
+ "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==",
+ "dev": true,
+ "dependencies": {
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.3.1",
+ "string-length": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz",
+ "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.3.1",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
+ "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==",
+ "dev": true
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+ "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "engines": {
+ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve.exports": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz",
+ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-jest": {
+ "version": "29.0.3",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
+ "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "dev": true,
+ "dependencies": {
+ "bs-logger": "0.x",
+ "fast-json-stable-stringify": "2.x",
+ "jest-util": "^29.0.0",
+ "json5": "^2.2.1",
+ "lodash.memoize": "4.x",
+ "make-error": "1.x",
+ "semver": "7.x",
+ "yargs-parser": "^21.0.1"
+ },
+ "bin": {
+ "ts-jest": "cli.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": ">=7.0.0-beta.0 <8",
+ "@jest/types": "^29.0.0",
+ "babel-jest": "^29.0.0",
+ "jest": "^29.0.0",
+ "typescript": ">=4.3"
+ },
+ "peerDependenciesMeta": {
+ "@babel/core": {
+ "optional": true
+ },
+ "@jest/types": {
+ "optional": true
+ },
+ "babel-jest": {
+ "optional": true
+ },
+ "esbuild": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/ts-jest/node_modules/semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
+ "dev": true,
+ "dependencies": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js",
+ "ts-node-cwd": "dist/bin-cwd.js",
+ "ts-node-esm": "dist/bin-esm.js",
+ "ts-node-script": "dist/bin-script.js",
+ "ts-node-transpile-only": "dist/bin-transpile.js",
+ "ts-script": "dist/bin-script-deprecated.js"
+ },
+ "peerDependencies": {
+ "@swc/core": ">=1.2.50",
+ "@swc/wasm": ">=1.2.50",
+ "@types/node": "*",
+ "typescript": ">=2.7"
+ },
+ "peerDependenciesMeta": {
+ "@swc/core": {
+ "optional": true
+ },
+ "@swc/wasm": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.7.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
+ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "browserslist-lint": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/v8-to-istanbul/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/yargs": {
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ },
+ "dependencies": {
+ "@ampproject/remapping": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
+ "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/gen-mapping": "^0.1.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ },
+ "@aws-cdk/asset-awscli-v1": {
+ "version": "2.2.30",
+ "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.30.tgz",
+ "integrity": "sha512-mFRF5n1jxjKpX8ZZSCRhJc6Hj8BkeZFUPwK0j6jRcouQQZHsZyydbf4UuzMYQ4SZU6cCLM7DKmWO0Kx156ZSnw==",
+ "dev": true
+ },
+ "@aws-cdk/asset-kubectl-v20": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.1.tgz",
+ "integrity": "sha512-U1ntiX8XiMRRRH5J1IdC+1t5CE89015cwyt5U63Cpk0GnMlN5+h9WsWMlKlPXZR4rdq/m806JRlBMRpBUB2Dhw==",
+ "dev": true
+ },
+ "@aws-cdk/asset-node-proxy-agent-v5": {
+ "version": "2.0.38",
+ "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v5/-/asset-node-proxy-agent-v5-2.0.38.tgz",
+ "integrity": "sha512-BBwAjORhuUkTGO3CxGS5Evcp5n20h9v06Sftn2R1DuSm8zIoUlPsNlI1HUk8XqYuoEI4aD7IKRQBLglv09ciJQ==",
+ "dev": true
+ },
+ "@babel/code-frame": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
+ "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.18.6"
+ }
+ },
+ "@babel/compat-data": {
+ "version": "7.20.10",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz",
+ "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==",
+ "dev": true
+ },
+ "@babel/core": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz",
+ "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==",
+ "dev": true,
+ "requires": {
+ "@ampproject/remapping": "^2.1.0",
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-compilation-targets": "^7.20.7",
+ "@babel/helper-module-transforms": "^7.20.11",
+ "@babel/helpers": "^7.20.7",
+ "@babel/parser": "^7.20.7",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.12",
+ "@babel/types": "^7.20.7",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.2",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz",
+ "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.20.7",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "jsesc": "^2.5.1"
+ },
+ "dependencies": {
+ "@jridgewell/gen-mapping": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
+ "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ }
+ }
+ }
+ },
+ "@babel/helper-compilation-targets": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz",
+ "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==",
+ "dev": true,
+ "requires": {
+ "@babel/compat-data": "^7.20.5",
+ "@babel/helper-validator-option": "^7.18.6",
+ "browserslist": "^4.21.3",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "requires": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-environment-visitor": {
+ "version": "7.18.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
+ "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "dev": true
+ },
+ "@babel/helper-function-name": {
+ "version": "7.19.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
+ "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.18.10",
+ "@babel/types": "^7.19.0"
+ }
+ },
+ "@babel/helper-hoist-variables": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
+ "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz",
+ "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.20.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz",
+ "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-module-imports": "^7.18.6",
+ "@babel/helper-simple-access": "^7.20.2",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.10",
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz",
+ "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==",
+ "dev": true
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.20.2",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz",
+ "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.20.2"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
+ "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.18.6"
+ }
+ },
+ "@babel/helper-string-parser": {
+ "version": "7.19.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
+ "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "dev": true
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.19.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
+ "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "dev": true
+ },
+ "@babel/helper-validator-option": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
+ "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
+ "dev": true
+ },
+ "@babel/helpers": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz",
+ "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.20.7",
+ "@babel/traverse": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
+ "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.18.6",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "@babel/parser": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz",
+ "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==",
+ "dev": true
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ }
+ },
+ "@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-jsx": {
+ "version": "7.18.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz",
+ "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.18.6"
+ }
+ },
+ "@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ }
+ },
+ "@babel/plugin-syntax-typescript": {
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz",
+ "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.19.0"
+ }
+ },
+ "@babel/template": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz",
+ "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.12.tgz",
+ "integrity": "sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.18.6",
+ "@babel/generator": "^7.20.7",
+ "@babel/helper-environment-visitor": "^7.18.9",
+ "@babel/helper-function-name": "^7.19.0",
+ "@babel/helper-hoist-variables": "^7.18.6",
+ "@babel/helper-split-export-declaration": "^7.18.6",
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0"
+ }
+ },
+ "@babel/types": {
+ "version": "7.20.7",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz",
+ "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-string-parser": "^7.19.4",
+ "@babel/helper-validator-identifier": "^7.19.1",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true
+ },
+ "@cspotcode/source-map-support": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
+ "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "0.3.9"
+ },
+ "dependencies": {
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.9",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
+ "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "^3.0.3",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ }
+ }
+ },
+ "@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true
+ },
+ "@jest/console": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz",
+ "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0"
+ }
+ },
+ "@jest/core": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz",
+ "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^29.3.1",
+ "@jest/reporters": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.2.0",
+ "jest-config": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-resolve-dependencies": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "@jest/environment": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz",
+ "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==",
+ "dev": true,
+ "requires": {
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1"
+ }
+ },
+ "@jest/expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==",
+ "dev": true,
+ "requires": {
+ "expect": "^29.3.1",
+ "jest-snapshot": "^29.3.1"
+ }
+ },
+ "@jest/expect-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz",
+ "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^29.2.0"
+ }
+ },
+ "@jest/fake-timers": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz",
+ "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@sinonjs/fake-timers": "^9.1.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ }
+ },
+ "@jest/globals": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz",
+ "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "jest-mock": "^29.3.1"
+ }
+ },
+ "@jest/reporters": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz",
+ "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==",
+ "dev": true,
+ "requires": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^5.1.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ }
+ },
+ "@jest/schemas": {
+ "version": "29.0.0",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
+ "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
+ "dev": true,
+ "requires": {
+ "@sinclair/typebox": "^0.24.1"
+ }
+ },
+ "@jest/source-map": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz",
+ "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ }
+ },
+ "@jest/test-result": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz",
+ "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ }
+ },
+ "@jest/test-sequencer": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz",
+ "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "slash": "^3.0.0"
+ }
+ },
+ "@jest/transform": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz",
+ "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.3.1",
+ "@jridgewell/trace-mapping": "^0.3.15",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.1"
+ }
+ },
+ "@jest/types": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
+ "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ }
+ },
+ "@jridgewell/gen-mapping": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
+ "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/set-array": "^1.0.0",
+ "@jridgewell/sourcemap-codec": "^1.4.10"
+ }
+ },
+ "@jridgewell/resolve-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
+ "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
+ "dev": true
+ },
+ "@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true
+ },
+ "@jridgewell/sourcemap-codec": {
+ "version": "1.4.14",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
+ "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
+ "dev": true
+ },
+ "@jridgewell/trace-mapping": {
+ "version": "0.3.17",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
+ "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/resolve-uri": "3.1.0",
+ "@jridgewell/sourcemap-codec": "1.4.14"
+ }
+ },
+ "@sinclair/typebox": {
+ "version": "0.24.51",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz",
+ "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==",
+ "dev": true
+ },
+ "@sinonjs/commons": {
+ "version": "1.8.6",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
+ "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
+ "dev": true,
+ "requires": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "@sinonjs/fake-timers": {
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
+ "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
+ "dev": true,
+ "requires": {
+ "@sinonjs/commons": "^1.7.0"
+ }
+ },
+ "@tsconfig/node10": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
+ "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
+ "dev": true
+ },
+ "@tsconfig/node12": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
+ "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
+ "dev": true
+ },
+ "@tsconfig/node14": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
+ "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
+ "dev": true
+ },
+ "@tsconfig/node16": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz",
+ "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==",
+ "dev": true
+ },
+ "@types/babel__core": {
+ "version": "7.1.20",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz",
+ "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "@types/babel__generator": {
+ "version": "7.6.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz",
+ "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__template": {
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz",
+ "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@types/babel__traverse": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz",
+ "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.3.0"
+ }
+ },
+ "@types/graceful-fs": {
+ "version": "4.1.6",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz",
+ "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
+ "@types/istanbul-lib-coverage": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz",
+ "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==",
+ "dev": true
+ },
+ "@types/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "@types/istanbul-reports": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz",
+ "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==",
+ "dev": true,
+ "requires": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "@types/jest": {
+ "version": "27.0.3",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.0.3.tgz",
+ "integrity": "sha512-cmmwv9t7gBYt7hNKH5Spu7Kuu/DotGa+Ff+JGRKZ4db5eh8PnKS4LuebJ3YLUoyOyIHraTGyULn23YtEAm0VSg==",
+ "dev": true,
+ "requires": {
+ "jest-diff": "^27.0.0",
+ "pretty-format": "^27.0.0"
+ }
+ },
+ "@types/node": {
+ "version": "18.6.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.5.tgz",
+ "integrity": "sha512-Xjt5ZGUa5WusGZJ4WJPbOT8QOqp6nDynVFRKcUt32bOgvXEoc6o085WNkYTMO7ifAj2isEfQQ2cseE+wT6jsRw==",
+ "dev": true
+ },
+ "@types/prettier": {
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz",
+ "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
+ "dev": true
+ },
+ "@types/stack-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
+ "dev": true
+ },
+ "@types/yargs": {
+ "version": "17.0.19",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.19.tgz",
+ "integrity": "sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ==",
+ "dev": true,
+ "requires": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "@types/yargs-parser": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "8.8.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
+ "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
+ "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.21.3"
+ }
+ },
+ "ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true
+ },
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ }
+ },
+ "arg": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
+ "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
+ "dev": true
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "aws-cdk": {
+ "version": "2.55.0",
+ "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.55.0.tgz",
+ "integrity": "sha512-SlsaKh1tEiFLWas99OffxoTLugkEZZHY552QeY4ZPXJaUx9kocGYc9s13IO8Y9/cBfoQVvh2KLev4J2+63vKyg==",
+ "dev": true,
+ "requires": {
+ "fsevents": "2.3.2"
+ }
+ },
+ "aws-cdk-lib": {
+ "version": "2.55.0",
+ "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.55.0.tgz",
+ "integrity": "sha512-YCtfmMiITU5ncrrQmq5wls2EeCUOLOBDLWO2ZkaUozIS+VbEDChK8rT66OmgQSPwFntKNSJq0P65tR7kN5/i8g==",
+ "dev": true,
+ "requires": {
+ "@aws-cdk/asset-awscli-v1": "^2.2.30",
+ "@aws-cdk/asset-kubectl-v20": "^2.1.1",
+ "@aws-cdk/asset-node-proxy-agent-v5": "^2.0.38",
+ "@balena/dockerignore": "^1.0.2",
+ "case": "1.6.3",
+ "fs-extra": "^9.1.0",
+ "ignore": "^5.2.1",
+ "jsonschema": "^1.4.1",
+ "minimatch": "^3.1.2",
+ "punycode": "^2.1.1",
+ "semver": "^7.3.8",
+ "yaml": "1.10.2"
+ },
+ "dependencies": {
+ "@balena/dockerignore": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "at-least-node": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "case": {
+ "version": "1.6.3",
+ "bundled": true,
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "fs-extra": {
+ "version": "9.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "at-least-node": "^1.0.0",
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "bundled": true,
+ "dev": true
+ },
+ "ignore": {
+ "version": "5.2.1",
+ "bundled": true,
+ "dev": true
+ },
+ "jsonfile": {
+ "version": "6.1.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "jsonschema": {
+ "version": "1.4.1",
+ "bundled": true,
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "bundled": true,
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.8",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "bundled": true,
+ "dev": true
+ },
+ "yaml": {
+ "version": "1.10.2",
+ "bundled": true,
+ "dev": true
+ }
+ }
+ },
+ "babel-jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz",
+ "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==",
+ "dev": true,
+ "requires": {
+ "@jest/transform": "^29.3.1",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.2.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ }
+ },
+ "babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ }
+ },
+ "babel-plugin-jest-hoist": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz",
+ "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ }
+ },
+ "babel-preset-current-node-syntax": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz",
+ "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==",
+ "dev": true,
+ "requires": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.8.3",
+ "@babel/plugin-syntax-import-meta": "^7.8.3",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.8.3",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-top-level-await": "^7.8.3"
+ }
+ },
+ "babel-preset-jest": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz",
+ "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-jest-hoist": "^29.2.0",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "browserslist": {
+ "version": "4.21.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz",
+ "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30001400",
+ "electron-to-chromium": "^1.4.251",
+ "node-releases": "^2.0.6",
+ "update-browserslist-db": "^1.0.9"
+ }
+ },
+ "bs-logger": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz",
+ "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==",
+ "dev": true,
+ "requires": {
+ "fast-json-stable-stringify": "2.x"
+ }
+ },
+ "bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "requires": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true
+ },
+ "caniuse-lite": {
+ "version": "1.0.30001442",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001442.tgz",
+ "integrity": "sha512-239m03Pqy0hwxYPYR5JwOIxRJfLTWtle9FV8zosfV5pHg+/51uD4nxcUlM8+mWWGfwKtt8lJNHnD3cWw9VZ6ow==",
+ "dev": true
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true
+ },
+ "ci-info": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz",
+ "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==",
+ "dev": true
+ },
+ "cjs-module-lexer": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz",
+ "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==",
+ "dev": true
+ },
+ "cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true
+ },
+ "collect-v8-coverage": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz",
+ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==",
+ "dev": true
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true
+ },
+ "constructs": {
+ "version": "10.1.190",
+ "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.1.190.tgz",
+ "integrity": "sha512-wGMEBsIKp/tP+b2q3XEtIh/KJPZ2uk7G2XyEbGVEatOo6OQHFhXfBi9BCk8725zuWYP/gZUQJfAvd7KZ+lY5Yw==",
+ "dev": true
+ },
+ "convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "create-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
+ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
+ "dev": true
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ }
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "dedent": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
+ "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
+ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
+ "dev": true
+ },
+ "detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true
+ },
+ "diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz",
+ "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==",
+ "dev": true
+ },
+ "electron-to-chromium": {
+ "version": "1.4.284",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
+ "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==",
+ "dev": true
+ },
+ "emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true
+ },
+ "expect": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz",
+ "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==",
+ "dev": true,
+ "requires": {
+ "@jest/expect-utils": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1"
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true
+ },
+ "fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "requires": {
+ "bser": "2.1.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "dev": true,
+ "optional": true
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true
+ },
+ "get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true
+ },
+ "get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dev": true,
+ "requires": {
+ "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"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true
+ },
+ "html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true
+ },
+ "import-local": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
+ "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ }
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "is-core-module": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "istanbul-lib-coverage": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz",
+ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==",
+ "dev": true
+ },
+ "istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "requires": {
+ "@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"
+ }
+ },
+ "istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "requires": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ }
+ },
+ "istanbul-reports": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz",
+ "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==",
+ "dev": true,
+ "requires": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ }
+ },
+ "jest": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz",
+ "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.3.1"
+ }
+ },
+ "jest-changed-files": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz",
+ "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==",
+ "dev": true,
+ "requires": {
+ "execa": "^5.0.0",
+ "p-limit": "^3.1.0"
+ }
+ },
+ "jest-circus": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz",
+ "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/expect": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^0.7.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-cli": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz",
+ "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==",
+ "dev": true,
+ "requires": {
+ "@jest/core": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "prompts": "^2.0.1",
+ "yargs": "^17.3.1"
+ }
+ },
+ "jest-config": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz",
+ "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "babel-jest": "^29.3.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.3.1",
+ "jest-environment-node": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-runner": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-diff": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz",
+ "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^27.5.1",
+ "jest-get-type": "^27.5.1",
+ "pretty-format": "^27.5.1"
+ },
+ "dependencies": {
+ "jest-get-type": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz",
+ "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==",
+ "dev": true
+ }
+ }
+ },
+ "jest-docblock": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz",
+ "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==",
+ "dev": true,
+ "requires": {
+ "detect-newline": "^3.0.0"
+ }
+ },
+ "jest-each": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz",
+ "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-environment-node": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz",
+ "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-mock": "^29.3.1",
+ "jest-util": "^29.3.1"
+ }
+ },
+ "jest-get-type": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz",
+ "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==",
+ "dev": true
+ },
+ "jest-haste-map": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz",
+ "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "fsevents": "^2.3.2",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.2.0",
+ "jest-util": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ }
+ },
+ "jest-leak-detector": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz",
+ "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==",
+ "dev": true,
+ "requires": {
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-matcher-utils": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz",
+ "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true
+ },
+ "jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ }
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-message-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
+ "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.3.1",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.3.1",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-mock": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz",
+ "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "jest-util": "^29.3.1"
+ }
+ },
+ "jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "requires": {}
+ },
+ "jest-regex-util": {
+ "version": "29.2.0",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz",
+ "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==",
+ "dev": true
+ },
+ "jest-resolve": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz",
+ "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.3.1",
+ "jest-validate": "^29.3.1",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^1.1.0",
+ "slash": "^3.0.0"
+ }
+ },
+ "jest-resolve-dependencies": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz",
+ "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==",
+ "dev": true,
+ "requires": {
+ "jest-regex-util": "^29.2.0",
+ "jest-snapshot": "^29.3.1"
+ }
+ },
+ "jest-runner": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz",
+ "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==",
+ "dev": true,
+ "requires": {
+ "@jest/console": "^29.3.1",
+ "@jest/environment": "^29.3.1",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.2.0",
+ "jest-environment-node": "^29.3.1",
+ "jest-haste-map": "^29.3.1",
+ "jest-leak-detector": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-resolve": "^29.3.1",
+ "jest-runtime": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "jest-watcher": "^29.3.1",
+ "jest-worker": "^29.3.1",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ }
+ },
+ "jest-runtime": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz",
+ "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==",
+ "dev": true,
+ "requires": {
+ "@jest/environment": "^29.3.1",
+ "@jest/fake-timers": "^29.3.1",
+ "@jest/globals": "^29.3.1",
+ "@jest/source-map": "^29.2.0",
+ "@jest/test-result": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-mock": "^29.3.1",
+ "jest-regex-util": "^29.2.0",
+ "jest-resolve": "^29.3.1",
+ "jest-snapshot": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ }
+ },
+ "jest-snapshot": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz",
+ "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/traverse": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.3.1",
+ "@jest/transform": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/babel__traverse": "^7.0.6",
+ "@types/prettier": "^2.1.5",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.3.1",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "jest-haste-map": "^29.3.1",
+ "jest-matcher-utils": "^29.3.1",
+ "jest-message-util": "^29.3.1",
+ "jest-util": "^29.3.1",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.3.1",
+ "semver": "^7.3.5"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "diff-sequences": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz",
+ "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==",
+ "dev": true
+ },
+ "jest-diff": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz",
+ "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.3.1",
+ "jest-get-type": "^29.2.0",
+ "pretty-format": "^29.3.1"
+ }
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ },
+ "semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "jest-util": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
+ "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ }
+ },
+ "jest-validate": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz",
+ "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==",
+ "dev": true,
+ "requires": {
+ "@jest/types": "^29.3.1",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.2.0",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.3.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true
+ },
+ "pretty-format": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
+ "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
+ "dev": true,
+ "requires": {
+ "@jest/schemas": "^29.0.0",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ }
+ },
+ "react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
+ "dev": true
+ }
+ }
+ },
+ "jest-watcher": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz",
+ "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==",
+ "dev": true,
+ "requires": {
+ "@jest/test-result": "^29.3.1",
+ "@jest/types": "^29.3.1",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.3.1",
+ "string-length": "^4.0.1"
+ }
+ },
+ "jest-worker": {
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz",
+ "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "jest-util": "^29.3.1",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true
+ },
+ "kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true
+ },
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
+ },
+ "lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "requires": {
+ "yallist": "^4.0.0"
+ }
+ },
+ "make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "requires": {
+ "semver": "^6.0.0"
+ }
+ },
+ "make-error": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
+ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
+ "dev": true
+ },
+ "makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "requires": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true
+ },
+ "node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true
+ },
+ "node-releases": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz",
+ "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==",
+ "dev": true
+ },
+ "normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "requires": {
+ "yocto-queue": "^0.1.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ },
+ "dependencies": {
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ }
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ }
+ },
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true
+ },
+ "pirates": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
+ "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==",
+ "dev": true
+ },
+ "pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0"
+ }
+ },
+ "pretty-format": {
+ "version": "27.5.1",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
+ "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^17.0.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true
+ }
+ }
+ },
+ "prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "requires": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
+ "dev": true
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^5.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "resolve.exports": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz",
+ "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==",
+ "dev": true
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true
+ },
+ "stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^2.0.0"
+ }
+ },
+ "string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "requires": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ }
+ },
+ "strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^5.0.1"
+ }
+ },
+ "strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true
+ },
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true
+ },
+ "test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "requires": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ }
+ },
+ "tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "ts-jest": {
+ "version": "29.0.3",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
+ "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "dev": true,
+ "requires": {
+ "bs-logger": "0.x",
+ "fast-json-stable-stringify": "2.x",
+ "jest-util": "^29.0.0",
+ "json5": "^2.2.1",
+ "lodash.memoize": "4.x",
+ "make-error": "1.x",
+ "semver": "7.x",
+ "yargs-parser": "^21.0.1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "7.3.8",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
+ "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^6.0.0"
+ }
+ }
+ }
+ },
+ "ts-node": {
+ "version": "10.9.1",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
+ "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
+ "dev": true,
+ "requires": {
+ "@cspotcode/source-map-support": "^0.8.0",
+ "@tsconfig/node10": "^1.0.7",
+ "@tsconfig/node12": "^1.0.7",
+ "@tsconfig/node14": "^1.0.0",
+ "@tsconfig/node16": "^1.0.2",
+ "acorn": "^8.4.1",
+ "acorn-walk": "^8.1.1",
+ "arg": "^4.1.0",
+ "create-require": "^1.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "v8-compile-cache-lib": "^3.0.1",
+ "yn": "3.1.1"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true
+ },
+ "typescript": {
+ "version": "4.7.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
+ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
+ "dev": true
+ },
+ "update-browserslist-db": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz",
+ "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==",
+ "dev": true,
+ "requires": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ }
+ },
+ "v8-compile-cache-lib": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
+ "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
+ "dev": true
+ },
+ "v8-to-istanbul": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
+ "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==",
+ "dev": true,
+ "requires": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^1.6.0"
+ },
+ "dependencies": {
+ "convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+ "dev": true
+ }
+ }
+ },
+ "walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "requires": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "requires": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ }
+ },
+ "y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true
+ },
+ "yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "yargs": {
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
+ "dev": true,
+ "requires": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ }
+ },
+ "yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true
+ },
+ "yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true
+ },
+ "yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true
+ }
+ }
+}
diff --git a/source/package.json b/source/package.json
index 4f3a656..0a79379 100755
--- a/source/package.json
+++ b/source/package.json
@@ -1,7 +1,7 @@
{
"name": "network-firewall-automation-solution",
- "version": "1.0.0",
- "description": "Network Firewall Automation solution.",
+ "version": "1.0.2",
+ "description": "Firewall Automation for Network Traffic on AWS",
"bin": {
"network-firewall-auto-solution": "bin/network-firewall-auto-solution.js"
},
@@ -21,29 +21,14 @@
},
"license": "Apache-2.0",
"devDependencies": {
- "@aws-cdk/assert": "1.77.0",
- "@types/jest": "^26.0.20",
- "@types/node": "10.17.5",
- "@types/source-map-support": "^0.5.3",
- "aws-cdk": "^1.77.0",
- "jest": "^26.6.3",
- "ts-jest": "^26.5.1",
- "ts-node": "^8.1.0",
- "typescript": "^3.9.9"
- },
- "dependencies": {
- "@aws-cdk/aws-codebuild": "1.77.0",
- "@aws-cdk/aws-codecommit": "1.77.0",
- "@aws-cdk/aws-codedeploy": "1.77.0",
- "@aws-cdk/aws-codepipeline": "1.77.0",
- "@aws-cdk/aws-codepipeline-actions": "1.77.0",
- "@aws-cdk/aws-ec2": "1.77.0",
- "@aws-cdk/aws-events-targets": "1.77.0",
- "@aws-cdk/aws-kms": "1.77.0",
- "@aws-cdk/aws-lambda": "1.77.0",
- "@aws-cdk/aws-s3": "1.77.0",
- "@aws-cdk/aws-ssm": "1.77.0",
- "@aws-cdk/core": "1.77.0",
- "source-map-support": "^0.5.16"
+ "@types/jest": "~27.0.1",
+ "@types/node": "~18.6.2",
+ "aws-cdk": "^2.55.0",
+ "aws-cdk-lib": "^2.55.0",
+ "constructs": "^10.0.0",
+ "jest": "~29.3.1",
+ "ts-jest": "~29.0.3",
+ "ts-node": "~10.9.1",
+ "typescript": "~4.7.4"
}
}
diff --git a/source/test/__snapshots__/network-firewall-automation-solution.test.ts.snap b/source/test/__snapshots__/network-firewall-automation-solution.test.ts.snap
index ead70ad..ca57b28 100644
--- a/source/test/__snapshots__/network-firewall-automation-solution.test.ts.snap
+++ b/source/test/__snapshots__/network-firewall-automation-solution.test.ts.snap
@@ -1,16 +1,16 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`NetworkFirewallAutomationStack Snapshot test 1`] = `
-Object {
+exports[`Firewall Automation for Network Traffic on AWS NetworkFirewallAutomationStack Snapshot test 1`] = `
+{
"AWSTemplateFormatVersion": "2010-09-09",
- "Conditions": Object {
- "CreateDefaultRouteFirewallRT": Object {
- "Fn::And": Array [
- Object {
- "Fn::Not": Array [
- Object {
- "Fn::Equals": Array [
- Object {
+ "Conditions": {
+ "CreateDefaultRouteFirewallRT": {
+ "Fn::And": [
+ {
+ "Fn::Not": [
+ {
+ "Fn::Equals": [
+ {
"Ref": "TransitGatewayRTIdForDefaultRoute",
},
"",
@@ -18,16 +18,16 @@ Object {
},
],
},
- Object {
+ {
"Condition": "CreateTransitGatewayAttachment",
},
],
},
- "CreateTransitGatewayAttachment": Object {
- "Fn::Not": Array [
- Object {
- "Fn::Equals": Array [
- Object {
+ "CreateTransitGatewayAttachment": {
+ "Fn::Not": [
+ {
+ "Fn::Equals": [
+ {
"Ref": "ExistingTransitGateway",
},
"",
@@ -35,13 +35,13 @@ Object {
},
],
},
- "CreateTransitGatewayRTAssociation": Object {
- "Fn::And": Array [
- Object {
- "Fn::Not": Array [
- Object {
- "Fn::Equals": Array [
- Object {
+ "CreateTransitGatewayRTAssociation": {
+ "Fn::And": [
+ {
+ "Fn::Not": [
+ {
+ "Fn::Equals": [
+ {
"Ref": "TransitGatewayRouteTableIdForAssociation",
},
"",
@@ -49,32 +49,32 @@ Object {
},
],
},
- Object {
+ {
"Condition": "CreateTransitGatewayAttachment",
},
],
},
- "LoggingInCloudWatch": Object {
- "Fn::Equals": Array [
- Object {
+ "LoggingInCloudWatch": {
+ "Fn::Equals": [
+ {
"Ref": "logDestinationType",
},
"CloudWatchLogs",
],
},
- "LoggingInS3": Object {
- "Fn::Equals": Array [
- Object {
+ "LoggingInS3": {
+ "Fn::Equals": [
+ {
"Ref": "logDestinationType",
},
"S3",
],
},
- "NotLoggingConfigureManually": Object {
- "Fn::Not": Array [
- Object {
- "Fn::Equals": Array [
- Object {
+ "NotLoggingConfigureManually": {
+ "Fn::Not": [
+ {
+ "Fn::Equals": [
+ {
"Ref": "logDestinationType",
},
"ConfigureManually",
@@ -83,190 +83,196 @@ Object {
],
},
},
- "Mappings": Object {
- "Send": Object {
- "AnonymousUsage": Object {
+ "Mappings": {
+ "Send": {
+ "AnonymousUsage": {
"Data": "Yes",
},
- "ParameterKey": Object {
- "UniqueId": "/Solutions/network-firewall-automation/UUID",
+ "ParameterKey": {
+ "UniqueId": "Solutions/network-firewall-automation/UUID",
},
},
- "SolutionMapping": Object {
- "CodeCommitRepo": Object {
+ "SolutionMapping": {
+ "CodeCommitRepo": {
"Name": "network-firewall-config-repo-",
},
- "Log": Object {
+ "Log": {
"Level": "info",
},
- "Metrics": Object {
+ "Metrics": {
"URL": "https://metrics.awssolutionsbuilder.com/generic",
},
- "Route": Object {
+ "Route": {
"QuadZero": "0.0.0.0/0",
},
- "Solution": Object {
+ "Solution": {
"Identifier": "SO0108",
+ "Version": "v1.0.2",
},
- "TransitGatewayAttachment": Object {
+ "TransitGatewayAttachment": {
"ApplianceMode": "enable",
},
- "Version": Object {
+ "Version": {
"Latest": "latest",
},
},
},
- "Metadata": Object {
- "AWS::CloudFormation::Interface": Object {
- "ParameterGroups": Array [
- Object {
- "Label": Object {
+ "Metadata": {
+ "AWS::CloudFormation::Interface": {
+ "ParameterGroups": [
+ {
+ "Label": {
"default": "VPC Configuration",
},
- "Parameters": Array [
+ "Parameters": [
"cidrBlock",
],
},
- Object {
- "Label": Object {
+ {
+ "Label": {
"default": "Transit Gateway Configuration",
},
- "Parameters": Array [
+ "Parameters": [
"ExistingTransitGateway",
"TransitGatewayRouteTableIdForAssociation",
"TransitGatewayRTIdForDefaultRoute",
],
},
- Object {
- "Label": Object {
+ {
+ "Label": {
"default": "Firewall Logging Configuration",
},
- "Parameters": Array [
+ "Parameters": [
"logDestinationType",
"logType",
"LogRetentionPeriod",
],
},
],
- "ParameterLabels": Object {
- "ExistingTransitGateway": Object {
+ "ParameterLabels": {
+ "ExistingTransitGateway": {
"default": "Provide the existing AWS Transit Gateway ID you wish to attach to the Inspection VPC",
},
- "LogRetentionPeriod": Object {
+ "LogRetentionPeriod": {
"default": "Select the log retention period for Network Firewall Logs.",
},
- "TransitGatewayRTIdForDefaultRoute": Object {
+ "TransitGatewayRTIdForDefaultRoute": {
"default": "Provide the AWS Transit Gateway Route Table to receive 0.0.0.0/0 route to the Inspection VPC TGW Attachment.",
},
- "TransitGatewayRouteTableIdForAssociation": Object {
+ "TransitGatewayRouteTableIdForAssociation": {
"default": "Provide AWS Transit Gateway Route Table to be associated with the Inspection VPC TGW Attachment.",
},
- "cidrBlock": Object {
+ "cidrBlock": {
"default": "Provide the CIDR block for the Inspection VPC",
},
- "logDestinationType": Object {
+ "logDestinationType": {
"default": "Select the type of log destination for the Network Firewall",
},
- "logType": Object {
+ "logType": {
"default": "Select the type of log to send to the defined log destination.",
},
},
},
},
- "Outputs": Object {
- "ArtifactBucketforCodePipeline": Object {
+ "Outputs": {
+ "ArtifactBucketforCodePipeline": {
"Description": "Artifact bucket name configured for the CodePipeline.",
- "Value": Object {
+ "Value": {
"Ref": "NetworkFirewallCodePipelineArtifactsBucketF2569455",
},
},
- "CloudWatchLogGroupforFirewallLogs": Object {
+ "CloudWatchLogGroupforFirewallLogs": {
"Description": "CloudWatch Log Group used as the log destination for Firewall Logs.",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"LoggingInCloudWatch",
- Object {
+ {
"Ref": "CloudWatchLogGroup",
},
"NotConfigured",
],
},
},
- "CodeBuildsourcecodebucket": Object {
+ "CodeBuildsourcecodebucket": {
"Description": "Code Build source code bucket",
- "Value": Object {
+ "Value": {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
},
- "FirewallSubnet1ID": Object {
+ "FirewallSubnet1ID": {
"Description": "Subnet 1 associated with Network Firewall.",
- "Value": Object {
+ "Value": {
"Ref": "NetworkFirewallSubnet1",
},
},
- "FirewallSubnet2ID": Object {
+ "FirewallSubnet2ID": {
"Description": "Subnet 2 associated with Network Firewall.",
- "Value": Object {
+ "Value": {
"Ref": "NetworkFirewallSubnet2",
},
},
- "InspectionVPCID": Object {
+ "InspectionVPCID": {
"Description": "Inspection VPC ID to create Network Firewall.",
- "Value": Object {
+ "Value": {
"Ref": "VPC",
},
},
- "NetworkFirewallAvailabilityZone1": Object {
+ "NetworkFirewallAvailabilityZone1": {
"Description": "Availability Zone configured for Network Firewall subnet 1",
- "Value": Object {
- "Fn::GetAtt": Array [
+ "Value": {
+ "Fn::GetAtt": [
"NetworkFirewallSubnet1",
"AvailabilityZone",
],
},
},
- "NetworkFirewallAvailabilityZone2": Object {
+ "NetworkFirewallAvailabilityZone2": {
"Description": "Availability Zone configured for Network Firewall subnet 2",
- "Value": Object {
- "Fn::GetAtt": Array [
+ "Value": {
+ "Fn::GetAtt": [
"NetworkFirewallSubnet2",
"AvailabilityZone",
],
},
},
- "S3BucketforFirewallLogs": Object {
+ "S3BucketforFirewallLogs": {
"Description": "S3 Bucket used as the log destination for Firewall Logs.",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"LoggingInS3",
- Object {
+ {
"Ref": "Logs6819BB44",
},
"NotConfigured",
],
},
},
- "TransitGatewaySubnet1ID": Object {
+ "TransitGatewaySubnet1ID": {
"Description": "Subnet 1 associated with Transit Gateway.",
- "Value": Object {
+ "Value": {
"Ref": "VPCTGWSubnet1",
},
},
- "TransitGatewaySubnet2ID": Object {
+ "TransitGatewaySubnet2ID": {
"Description": "Subnet 1 associated with Transit Gateway.",
- "Value": Object {
+ "Value": {
"Ref": "VPCTGWSubnet2",
},
},
},
- "Parameters": Object {
- "ExistingTransitGateway": Object {
+ "Parameters": {
+ "BootstrapVersion": {
+ "Default": "/cdk-bootstrap/hnb659fds/version",
+ "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]",
+ "Type": "AWS::SSM::Parameter::Value",
+ },
+ "ExistingTransitGateway": {
"Default": "",
"Description": "Existing AWS Transit Gateway id.",
"Type": "String",
},
- "LogRetentionPeriod": Object {
- "AllowedValues": Array [
+ "LogRetentionPeriod": {
+ "AllowedValues": [
"1",
"3",
"5",
@@ -289,24 +295,24 @@ Object {
"Description": "Log retention period in days.",
"Type": "Number",
},
- "TransitGatewayRTIdForDefaultRoute": Object {
+ "TransitGatewayRTIdForDefaultRoute": {
"Default": "",
"Description": "Existing AWS Transit Gateway route table id. Example: Spoke VPC Route Table. Format: tgw-rtb-4e5f6g7h",
"Type": "String",
},
- "TransitGatewayRouteTableIdForAssociation": Object {
+ "TransitGatewayRouteTableIdForAssociation": {
"Default": "",
"Description": "Existing AWS Transit Gateway route table id. Example: Firewall Route Table. Format: tgw-rtb-0a1b2c3d",
"Type": "String",
},
- "cidrBlock": Object {
+ "cidrBlock": {
"AllowedPattern": "^(?:[0-9]{1,3}.){3}[0-9]{1,3}[/]([0-9]?[0-6]?|[1][7-9])$",
"Default": "192.168.1.0/26",
"Description": "CIDR Block for VPC. Must be /26 or larger CIDR block.",
"Type": "String",
},
- "logDestinationType": Object {
- "AllowedValues": Array [
+ "logDestinationType": {
+ "AllowedValues": [
"S3",
"CloudWatchLogs",
"ConfigureManually",
@@ -315,8 +321,8 @@ Object {
"Description": "The type of storage destination to send these logs to. You can send logs to an Amazon S3 bucket or a CloudWatch log group.",
"Type": "String",
},
- "logType": Object {
- "AllowedValues": Array [
+ "logType": {
+ "AllowedValues": [
"ALERT",
"FLOW",
"EnableBoth",
@@ -326,276 +332,314 @@ Object {
"Type": "String",
},
},
- "Resources": Object {
- "BuildProject097C5DB7": Object {
- "Properties": Object {
- "Artifacts": Object {
+ "Resources": {
+ "BuildProject097C5DB7": {
+ "Properties": {
+ "Artifacts": {
"Type": "CODEPIPELINE",
},
- "EncryptionKey": Object {
- "Fn::GetAtt": Array [
+ "Cache": {
+ "Type": "NO_CACHE",
+ },
+ "EncryptionKey": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
},
- "Environment": Object {
+ "Environment": {
"ComputeType": "BUILD_GENERAL1_SMALL",
- "EnvironmentVariables": Array [
- Object {
+ "EnvironmentVariables": [
+ {
"Name": "LOG_LEVEL",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Log",
"Level",
],
},
},
- Object {
+ {
"Name": "VPC_ID",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "VPC",
},
},
- Object {
+ {
"Name": "SUBNET_IDS",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "NetworkFirewallSubnet1",
},
",",
- Object {
+ {
"Ref": "NetworkFirewallSubnet2",
},
],
],
},
},
- Object {
+ {
"Name": "LOG_TYPE",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "logType",
},
},
- Object {
+ {
"Name": "LOG_DESTINATION_TYPE",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "logDestinationType",
},
},
- Object {
+ {
"Name": "S3_LOG_BUCKET_NAME",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"LoggingInS3",
- Object {
+ {
"Ref": "Logs6819BB44",
},
"NotConfigured",
],
},
},
- Object {
+ {
"Name": "CLOUDWATCH_LOG_GROUP_NAME",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"LoggingInCloudWatch",
- Object {
+ {
"Ref": "CloudWatchLogGroup",
},
"NotConfigured",
],
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_AZ_1",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::GetAtt": Array [
+ "Value": {
+ "Fn::GetAtt": [
"NetworkFirewallSubnet1",
"AvailabilityZone",
],
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_AZ_2",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::GetAtt": Array [
+ "Value": {
+ "Fn::GetAtt": [
"NetworkFirewallSubnet2",
"AvailabilityZone",
],
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_1",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "VPCTGWRouteTable1",
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_2",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "VPCTGWRouteTable2",
},
},
- Object {
+ {
"Name": "CODE_BUILD_SOURCE_CODE_S3_KEY",
"Type": "PLAINTEXT",
- "Value": "network-firewall-automation/v1.0.0",
+ "Value": "network-firewall-automation/v1.0.2",
},
- Object {
+ {
"Name": "STACK_ID",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "AWS::StackId",
},
},
- Object {
+ {
"Name": "SSM_PARAM_FOR_UUID",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
- "Send",
- "ParameterKey",
- "UniqueId",
+ "Value": {
+ "Fn::Join": [
+ "",
+ [
+ "/",
+ {
+ "Fn::FindInMap": [
+ "Send",
+ "ParameterKey",
+ "UniqueId",
+ ],
+ },
+ ],
],
},
},
- Object {
+ {
"Name": "SEND_ANONYMOUS_METRICS",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"Send",
"AnonymousUsage",
"Data",
],
},
},
- Object {
+ {
"Name": "SOLUTION_ID",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Solution",
"Identifier",
],
},
},
- Object {
+ {
"Name": "METRICS_URL",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Metrics",
"URL",
],
},
},
- Object {
+ {
"Name": "TRANSIT_GATEWAY_ATTACHMENT_ID",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"CreateTransitGatewayAttachment",
- Object {
+ {
"Ref": "VPCTGWATTACHMENT",
},
"",
],
},
},
- Object {
+ {
"Name": "TRANSIT_GATEWAY_ATTACHMENT_APPLIANCE_MODE",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"TransitGatewayAttachment",
"ApplianceMode",
],
},
},
+ {
+ "Name": "CUSTOM_SDK_USER_AGENT",
+ "Type": "PLAINTEXT",
+ "Value": {
+ "Fn::Join": [
+ "",
+ [
+ "AwsSolution/",
+ {
+ "Fn::FindInMap": [
+ "SolutionMapping",
+ "Solution",
+ "Identifier",
+ ],
+ },
+ "/",
+ {
+ "Fn::FindInMap": [
+ "SolutionMapping",
+ "Solution",
+ "Version",
+ ],
+ },
+ ],
+ ],
+ },
+ },
],
- "Image": "aws/codebuild/standard:4.0",
+ "Image": "aws/codebuild/standard:6.0",
"ImagePullCredentialsType": "CODEBUILD",
"PrivilegedMode": false,
"Type": "LINUX_CONTAINER",
},
- "ServiceRole": Object {
- "Fn::GetAtt": Array [
+ "ServiceRole": {
+ "Fn::GetAtt": [
"BuildProjectRoleAA92C755",
"Arn",
],
},
- "Source": Object {
- "BuildSpec": Object {
- "Fn::Join": Array [
+ "Source": {
+ "BuildSpec": {
+ "Fn::Join": [
"",
- Array [
+ [
"{
- \\"version\\": \\"0.2\\",
- \\"phases\\": {
- \\"install\\": {
- \\"runtime-versions\\": {
- \\"nodejs\\": \\"12\\"
- },
- \\"commands\\": [
- \\"export current=$(pwd)\\",
- \\"export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY\\"
+ "version": "0.2",
+ "phases": {
+ "install": {
+ "runtime-versions": {
+ "nodejs": "16"
+ },
+ "commands": [
+ "export current=$(pwd)",
+ "export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY"
]
},
- \\"pre_build\\": {
- \\"commands\\": [
- \\"cd $current\\",
- \\"pwd; ls -ltr\\",
- \\"echo 'Download Network Firewall Solution Package'\\",
- \\"aws s3 cp s3://",
- Object {
+ "pre_build": {
+ "commands": [
+ "cd $current",
+ "pwd; ls -ltr",
+ "echo 'Download Network Firewall Solution Package'",
+ "aws s3 cp s3://",
+ {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
- "/$sourceCodeKey/network-firewall-automation.zip $current || true\\",
- \\"if [ -f $current/network-firewall-automation.zip ];then exit 0;else echo \\\\\\"Copy file to s3 bucket\\\\\\"; aws s3 cp s3://solutions-",
- Object {
+ "/$sourceCodeKey/network-firewall-automation.zip $current || true",
+ "if [ -f $current/network-firewall-automation.zip ];then exit 0;else echo \\"Copy file to s3 bucket\\"; aws s3 cp s3://solutions-",
+ {
"Ref": "AWS::Region",
},
"/$sourceCodeKey/network-firewall-automation.zip s3://",
- Object {
+ {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
- "/$sourceCodeKey/network-firewall-automation.zip; aws s3 cp s3://",
- Object {
+ "/$sourceCodeKey/network-firewall-automation.zip --copy-props none; aws s3 cp s3://",
+ {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
- "/$sourceCodeKey/network-firewall-automation.zip $current; fi;\\",
- \\"unzip -o $current/network-firewall-automation.zip -d $current\\",
- \\"pwd; ls -ltr\\"
+ "/$sourceCodeKey/network-firewall-automation.zip $current; fi;",
+ "unzip -o $current/network-firewall-automation.zip -d $current",
+ "pwd; ls -ltr"
]
},
- \\"build\\": {
- \\"commands\\": [
- \\"echo \\\\\\"Validating the firewall config\\\\\\"\\",
- \\"node build.js\\"
+ "build": {
+ "commands": [
+ "echo \\"Validating the firewall config\\"",
+ "node build.js"
]
}
},
- \\"artifacts\\": {
- \\"files\\": \\"**/*\\"
+ "artifacts": {
+ "files": "**/*"
}
}",
],
@@ -606,14 +650,14 @@ Object {
},
"Type": "AWS::CodeBuild::Project",
},
- "BuildProjectRoleAA92C755": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "BuildProjectRoleAA92C755": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
+ "Principal": {
"Service": "codebuild.amazonaws.com",
},
},
@@ -623,43 +667,43 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "BuildProjectRoleDefaultPolicy3E9F248C": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "BuildProjectRoleDefaultPolicy3E9F248C": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::Join": Array [
+ "Resource": [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":logs:eu-west-1:1234:log-group:/aws/codebuild/",
- Object {
+ {
"Ref": "BuildProject097C5DB7",
},
],
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":logs:eu-west-1:1234:log-group:/aws/codebuild/",
- Object {
+ {
"Ref": "BuildProject097C5DB7",
},
":*",
@@ -668,8 +712,8 @@ Object {
},
],
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"codebuild:CreateReportGroup",
"codebuild:CreateReport",
"codebuild:UpdateReport",
@@ -677,16 +721,16 @@ Object {
"codebuild:BatchPutCodeCoverages",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::Join": Array [
+ "Resource": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":codebuild:eu-west-1:1234:report-group/",
- Object {
+ {
"Ref": "BuildProject097C5DB7",
},
"-*",
@@ -694,29 +738,33 @@ Object {
],
},
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:DeleteObject*",
- "s3:PutObject*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging",
"s3:Abort*",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::GetAtt": Array [
+ "Resource": [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
- Object {
- "Fn::GetAtt": Array [
+ [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
@@ -727,8 +775,8 @@ Object {
},
],
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
@@ -736,23 +784,23 @@ Object {
"kms:GenerateDataKey*",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
},
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"kms:Decrypt",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
@@ -762,54 +810,56 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "BuildProjectRoleDefaultPolicy3E9F248C",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "BuildProjectRoleAA92C755",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "CloudWatchLogGroup": Object {
+ "CloudWatchLogGroup": {
"Condition": "LoggingInCloudWatch",
- "Properties": Object {
- "KmsKeyId": Object {
- "Fn::GetAtt": Array [
- "KMSKeyForNetworkFirewallLogDestinations70A79322",
+ "Properties": {
+ "KmsKeyId": {
+ "Fn::GetAtt": [
+ "KMSKeyForNetworkFirewallBuckets73A57817",
"Arn",
],
},
- "RetentionInDays": Object {
+ "RetentionInDays": {
"Ref": "LogRetentionPeriod",
},
},
"Type": "AWS::Logs::LogGroup",
},
- "CloudWatchLogsForNetworkFirewallBucketPolicy611AC31C": Object {
+ "CloudWatchLogsForNetworkFirewallBucketPolicy611AC31C": {
"Condition": "LoggingInS3",
"DeletionPolicy": "Retain",
- "Properties": Object {
- "Bucket": Object {
+ "Properties": {
+ "Bucket": {
"Ref": "Logs6819BB44",
},
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
+ "PolicyDocument": {
+ "Statement": [
+ {
"Action": "s3:GetObject",
- "Condition": Object {
- "Bool": Object {
+ "Condition": {
+ "Bool": {
"aws:SecureTransport": false,
},
},
"Effect": "Deny",
- "Principal": "*",
- "Resource": Array [
- Object {
- "Fn::Join": Array [
+ "Principal": {
+ "AWS": "*",
+ },
+ "Resource": [
+ {
+ "Fn::Join": [
"",
- Array [
- Object {
- "Fn::GetAtt": Array [
+ [
+ {
+ "Fn::GetAtt": [
"Logs6819BB44",
"Arn",
],
@@ -818,8 +868,8 @@ Object {
],
],
},
- Object {
- "Fn::GetAtt": Array [
+ {
+ "Fn::GetAtt": [
"Logs6819BB44",
"Arn",
],
@@ -833,36 +883,38 @@ Object {
"Type": "AWS::S3::BucketPolicy",
"UpdateReplacePolicy": "Retain",
},
- "CodeBuildStageSourceCodeBucketPolicyF19BA2A0": Object {
+ "CodeBuildStageSourceCodeBucketPolicyF19BA2A0": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "Bucket": Object {
+ "Properties": {
+ "Bucket": {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
+ "PolicyDocument": {
+ "Statement": [
+ {
"Action": "s3:GetObject",
- "Condition": Object {
- "Bool": Object {
+ "Condition": {
+ "Bool": {
"aws:SecureTransport": false,
},
},
"Effect": "Deny",
- "Principal": "*",
- "Resource": Array [
- Object {
- "Fn::GetAtt": Array [
+ "Principal": {
+ "AWS": "*",
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
"CodeBuildStagesSourceCodeBucketFA98E7C7",
"Arn",
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
- Object {
- "Fn::GetAtt": Array [
+ [
+ {
+ "Fn::GetAtt": [
"CodeBuildStagesSourceCodeBucketFA98E7C7",
"Arn",
],
@@ -880,29 +932,29 @@ Object {
"Type": "AWS::S3::BucketPolicy",
"UpdateReplacePolicy": "Retain",
},
- "CodeBuildStagesSourceCodeBucketFA98E7C7": Object {
+ "CodeBuildStagesSourceCodeBucketFA98E7C7": {
"DeletionPolicy": "Retain",
- "Metadata": Object {
- "cfn_nag": Object {
- "rules_to_suppress": Array [
- Object {
+ "Metadata": {
+ "cfn_nag": {
+ "rules_to_suppress": [
+ {
"id": "W35",
"reason": "Source Code bucket bucket does not require logging configuration",
},
- Object {
+ {
"id": "W51",
"reason": "Source Code bucket is private and does not require a bucket policy",
},
],
},
},
- "Properties": Object {
- "BucketEncryption": Object {
- "ServerSideEncryptionConfiguration": Array [
- Object {
- "ServerSideEncryptionByDefault": Object {
- "KMSMasterKeyID": Object {
- "Fn::GetAtt": Array [
+ "Properties": {
+ "BucketEncryption": {
+ "ServerSideEncryptionConfiguration": [
+ {
+ "ServerSideEncryptionByDefault": {
+ "KMSMasterKeyID": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
@@ -912,7 +964,7 @@ Object {
},
],
},
- "PublicAccessBlockConfiguration": Object {
+ "PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
@@ -922,345 +974,323 @@ Object {
"Type": "AWS::S3::Bucket",
"UpdateReplacePolicy": "Retain",
},
- "CodePipelineArtifactS3BucketPolicy6FFF9EE9": Object {
- "DeletionPolicy": "Retain",
- "Properties": Object {
- "Bucket": Object {
- "Ref": "NetworkFirewallCodePipelineArtifactsBucketF2569455",
- },
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": "s3:DeleteBucket",
- "Effect": "Allow",
- "Principal": Object {
- "Service": "cloudformation.amazonaws.com",
- },
- "Resource": Object {
- "Fn::GetAtt": Array [
- "NetworkFirewallCodePipelineArtifactsBucketF2569455",
- "Arn",
- ],
- },
- },
- Object {
- "Action": "s3:GetObject",
- "Condition": Object {
- "Bool": Object {
- "aws:SecureTransport": false,
- },
- },
- "Effect": "Deny",
- "Principal": "*",
- "Resource": Array [
- Object {
- "Fn::Join": Array [
- "",
- Array [
- Object {
- "Fn::GetAtt": Array [
- "NetworkFirewallCodePipelineArtifactsBucketF2569455",
- "Arn",
- ],
- },
- "/*",
- ],
- ],
- },
- Object {
- "Fn::GetAtt": Array [
- "NetworkFirewallCodePipelineArtifactsBucketF2569455",
- "Arn",
- ],
- },
- ],
- },
- ],
- "Version": "2012-10-17",
- },
- },
- "Type": "AWS::S3::BucketPolicy",
- "UpdateReplacePolicy": "Retain",
- },
- "DefaultRouteSpokeVPCTGWRouteTable": Object {
+ "DefaultRouteSpokeVPCTGWRouteTable": {
"Condition": "CreateDefaultRouteFirewallRT",
"DeletionPolicy": "Retain",
- "Properties": Object {
- "DestinationCidrBlock": Object {
- "Fn::FindInMap": Array [
+ "Properties": {
+ "DestinationCidrBlock": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Route",
"QuadZero",
],
},
- "TransitGatewayAttachmentId": Object {
+ "TransitGatewayAttachmentId": {
"Ref": "VPCTGWATTACHMENT",
},
- "TransitGatewayRouteTableId": Object {
+ "TransitGatewayRouteTableId": {
"Ref": "TransitGatewayRTIdForDefaultRoute",
},
},
"Type": "AWS::EC2::TransitGatewayRoute",
},
- "DeployProject1CF7CB79": Object {
- "Properties": Object {
- "Artifacts": Object {
+ "DeployProject1CF7CB79": {
+ "Properties": {
+ "Artifacts": {
"Type": "CODEPIPELINE",
},
- "EncryptionKey": Object {
- "Fn::GetAtt": Array [
+ "Cache": {
+ "Type": "NO_CACHE",
+ },
+ "EncryptionKey": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
},
- "Environment": Object {
+ "Environment": {
"ComputeType": "BUILD_GENERAL1_SMALL",
- "EnvironmentVariables": Array [
- Object {
+ "EnvironmentVariables": [
+ {
"Name": "LOG_LEVEL",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Log",
"Level",
],
},
},
- Object {
+ {
"Name": "VPC_ID",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "VPC",
},
},
- Object {
+ {
"Name": "SUBNET_IDS",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "NetworkFirewallSubnet1",
},
",",
- Object {
+ {
"Ref": "NetworkFirewallSubnet2",
},
],
],
},
},
- Object {
+ {
"Name": "LOG_TYPE",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "logType",
},
},
- Object {
+ {
"Name": "LOG_DESTINATION_TYPE",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "logDestinationType",
},
},
- Object {
+ {
"Name": "S3_LOG_BUCKET_NAME",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"LoggingInS3",
- Object {
+ {
"Ref": "Logs6819BB44",
},
"NotConfigured",
],
},
},
- Object {
+ {
"Name": "CLOUDWATCH_LOG_GROUP_NAME",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"LoggingInCloudWatch",
- Object {
+ {
"Ref": "CloudWatchLogGroup",
},
"NotConfigured",
],
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_AZ_1",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::GetAtt": Array [
+ "Value": {
+ "Fn::GetAtt": [
"NetworkFirewallSubnet1",
"AvailabilityZone",
],
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_AZ_2",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::GetAtt": Array [
+ "Value": {
+ "Fn::GetAtt": [
"NetworkFirewallSubnet2",
"AvailabilityZone",
],
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_1",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "VPCTGWRouteTable1",
},
},
- Object {
+ {
"Name": "VPC_TGW_ATTACHMENT_ROUTE_TABLE_ID_2",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "VPCTGWRouteTable2",
},
},
- Object {
+ {
"Name": "CODE_BUILD_SOURCE_CODE_S3_KEY",
"Type": "PLAINTEXT",
- "Value": "network-firewall-automation/v1.0.0",
+ "Value": "network-firewall-automation/v1.0.2",
},
- Object {
+ {
"Name": "STACK_ID",
"Type": "PLAINTEXT",
- "Value": Object {
+ "Value": {
"Ref": "AWS::StackId",
},
},
- Object {
+ {
"Name": "SSM_PARAM_FOR_UUID",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
- "Send",
- "ParameterKey",
- "UniqueId",
+ "Value": {
+ "Fn::Join": [
+ "",
+ [
+ "/",
+ {
+ "Fn::FindInMap": [
+ "Send",
+ "ParameterKey",
+ "UniqueId",
+ ],
+ },
+ ],
],
},
},
- Object {
+ {
"Name": "SEND_ANONYMOUS_METRICS",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"Send",
"AnonymousUsage",
"Data",
],
},
},
- Object {
+ {
"Name": "SOLUTION_ID",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Solution",
"Identifier",
],
},
},
- Object {
+ {
"Name": "METRICS_URL",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Metrics",
"URL",
],
},
},
- Object {
+ {
"Name": "TRANSIT_GATEWAY_ATTACHMENT_ID",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::If": Array [
+ "Value": {
+ "Fn::If": [
"CreateTransitGatewayAttachment",
- Object {
+ {
"Ref": "VPCTGWATTACHMENT",
},
"",
],
},
},
- Object {
+ {
"Name": "TRANSIT_GATEWAY_ATTACHMENT_APPLIANCE_MODE",
"Type": "PLAINTEXT",
- "Value": Object {
- "Fn::FindInMap": Array [
+ "Value": {
+ "Fn::FindInMap": [
"SolutionMapping",
"TransitGatewayAttachment",
"ApplianceMode",
],
},
},
+ {
+ "Name": "CUSTOM_SDK_USER_AGENT",
+ "Type": "PLAINTEXT",
+ "Value": {
+ "Fn::Join": [
+ "",
+ [
+ "AwsSolution/",
+ {
+ "Fn::FindInMap": [
+ "SolutionMapping",
+ "Solution",
+ "Identifier",
+ ],
+ },
+ "/",
+ {
+ "Fn::FindInMap": [
+ "SolutionMapping",
+ "Solution",
+ "Version",
+ ],
+ },
+ ],
+ ],
+ },
+ },
],
- "Image": "aws/codebuild/standard:4.0",
+ "Image": "aws/codebuild/standard:6.0",
"ImagePullCredentialsType": "CODEBUILD",
"PrivilegedMode": false,
"Type": "LINUX_CONTAINER",
},
- "ServiceRole": Object {
- "Fn::GetAtt": Array [
+ "ServiceRole": {
+ "Fn::GetAtt": [
"DeployProjectRole588C8C1D",
"Arn",
],
},
- "Source": Object {
- "BuildSpec": Object {
- "Fn::Join": Array [
+ "Source": {
+ "BuildSpec": {
+ "Fn::Join": [
"",
- Array [
+ [
"{
- \\"version\\": \\"0.2\\",
- \\"phases\\": {
- \\"install\\": {
- \\"runtime-versions\\": {
- \\"nodejs\\": \\"12\\"
- },
- \\"commands\\": [
- \\"export current=$(pwd)\\",
- \\"export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY\\"
+ "version": "0.2",
+ "phases": {
+ "install": {
+ "runtime-versions": {
+ "nodejs": "16"
+ },
+ "commands": [
+ "export current=$(pwd)",
+ "export sourceCodeKey=$CODE_BUILD_SOURCE_CODE_S3_KEY"
]
},
- \\"pre_build\\": {
- \\"commands\\": [
- \\"cd $current\\",
- \\"pwd; ls -ltr\\",
- \\"echo 'Download Network Firewall Solution Package'\\",
- \\"aws s3 cp s3://",
- Object {
+ "pre_build": {
+ "commands": [
+ "cd $current",
+ "pwd; ls -ltr",
+ "echo 'Download Network Firewall Solution Package'",
+ "aws s3 cp s3://",
+ {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
- "/$sourceCodeKey/network-firewall-automation.zip $current\\",
- \\"unzip -o $current/network-firewall-automation.zip -d $current\\",
- \\"pwd; ls -ltr\\"
+ "/$sourceCodeKey/network-firewall-automation.zip $current",
+ "unzip -o $current/network-firewall-automation.zip -d $current",
+ "pwd; ls -ltr"
]
},
- \\"build\\": {
- \\"commands\\": [
- \\"echo \\\\\\"Initiating Network Firewall Automation\\\\\\"\\",
- \\"node index.js\\"
+ "build": {
+ "commands": [
+ "echo \\"Initiating Network Firewall Automation\\"",
+ "node index.js"
]
},
- \\"post_build\\": {
- \\"commands\\": []
+ "post_build": {
+ "commands": []
}
},
- \\"artifacts\\": {
- \\"files\\": \\"**/*\\"
+ "artifacts": {
+ "files": "**/*"
}
}",
],
@@ -1271,14 +1301,14 @@ Object {
},
"Type": "AWS::CodeBuild::Project",
},
- "DeployProjectRole588C8C1D": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "DeployProjectRole588C8C1D": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
+ "Principal": {
"Service": "codebuild.amazonaws.com",
},
},
@@ -1288,43 +1318,43 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "DeployProjectRoleDefaultPolicy52AEA98B": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "DeployProjectRoleDefaultPolicy52AEA98B": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::Join": Array [
+ "Resource": [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":logs:eu-west-1:1234:log-group:/aws/codebuild/",
- Object {
+ {
"Ref": "DeployProject1CF7CB79",
},
],
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":logs:eu-west-1:1234:log-group:/aws/codebuild/",
- Object {
+ {
"Ref": "DeployProject1CF7CB79",
},
":*",
@@ -1333,8 +1363,8 @@ Object {
},
],
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"codebuild:CreateReportGroup",
"codebuild:CreateReport",
"codebuild:UpdateReport",
@@ -1342,16 +1372,16 @@ Object {
"codebuild:BatchPutCodeCoverages",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::Join": Array [
+ "Resource": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":codebuild:eu-west-1:1234:report-group/",
- Object {
+ {
"Ref": "DeployProject1CF7CB79",
},
"-*",
@@ -1359,26 +1389,26 @@ Object {
],
},
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::GetAtt": Array [
+ "Resource": [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
- Object {
- "Fn::GetAtt": Array [
+ [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
@@ -1389,29 +1419,29 @@ Object {
},
],
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"kms:Decrypt",
"kms:DescribeKey",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
},
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"kms:Decrypt",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
@@ -1421,25 +1451,25 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "DeployProjectRoleDefaultPolicy52AEA98B",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "DeployProjectRole588C8C1D",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "FirewallSubnetRouteTable": Object {
+ "FirewallSubnetRouteTable": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "Tags": Array [
- Object {
+ "Properties": {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-FirewallSubnetRouteTable",
@@ -1448,25 +1478,25 @@ Object {
},
},
],
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::RouteTable",
"UpdateReplacePolicy": "Retain",
},
- "FlowLog": Object {
- "Properties": Object {
- "DeliverLogsPermissionArn": Object {
- "Fn::GetAtt": Array [
+ "FlowLog": {
+ "Properties": {
+ "DeliverLogsPermissionArn": {
+ "Fn::GetAtt": [
"RoleFlowLogsCA794118",
"Arn",
],
},
- "LogGroupName": Object {
+ "LogGroupName": {
"Ref": "AWS::StackName",
},
- "ResourceId": Object {
+ "ResourceId": {
"Ref": "VPC",
},
"ResourceType": "VPC",
@@ -1474,39 +1504,23 @@ Object {
},
"Type": "AWS::EC2::FlowLog",
},
- "KMSKeyForNetworkFirewallLogDestinations70A79322": Object {
+ "KMSKeyForNetworkFirewallBuckets73A57817": {
"DeletionPolicy": "Retain",
- "Properties": Object {
+ "Properties": {
"Description": "This key will be used for encrypting the vpc flow logs and firewall logs.",
"EnableKeyRotation": true,
- "KeyPolicy": Object {
- "Statement": Array [
- Object {
- "Action": Array [
- "kms:Create*",
- "kms:Describe*",
- "kms:Enable*",
- "kms:List*",
- "kms:Put*",
- "kms:Update*",
- "kms:Revoke*",
- "kms:Disable*",
- "kms:Get*",
- "kms:Delete*",
- "kms:ScheduleKeyDeletion",
- "kms:CancelKeyDeletion",
- "kms:GenerateDataKey",
- "kms:TagResource",
- "kms:UntagResource",
- ],
+ "KeyPolicy": {
+ "Statement": [
+ {
+ "Action": "kms:*",
"Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::Join": Array [
+ "Principal": {
+ "AWS": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":iam::1234:root",
@@ -1516,16 +1530,16 @@ Object {
},
"Resource": "*",
},
- Object {
+ {
"Action": "kms:GenerateDataKey*",
"Effect": "Allow",
- "Principal": Object {
+ "Principal": {
"Service": "delivery.logs.amazonaws.com",
},
"Resource": "*",
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"kms:Encrypt*",
"kms:Decrypt*",
"kms:ReEncrypt*",
@@ -1533,13 +1547,13 @@ Object {
"kms:Describe*",
],
"Effect": "Allow",
- "Principal": Object {
- "Service": Object {
- "Fn::Join": Array [
+ "Principal": {
+ "Service": {
+ "Fn::Join": [
"",
- Array [
+ [
"logs.",
- Object {
+ {
"Ref": "AWS::Region",
},
".amazonaws.com",
@@ -1556,48 +1570,48 @@ Object {
"Type": "AWS::KMS::Key",
"UpdateReplacePolicy": "Retain",
},
- "LogGroupFlowLogs": Object {
- "Properties": Object {
- "KmsKeyId": Object {
- "Fn::GetAtt": Array [
- "KMSKeyForNetworkFirewallLogDestinations70A79322",
+ "LogGroupFlowLogs": {
+ "Properties": {
+ "KmsKeyId": {
+ "Fn::GetAtt": [
+ "KMSKeyForNetworkFirewallBuckets73A57817",
"Arn",
],
},
- "LogGroupName": Object {
+ "LogGroupName": {
"Ref": "AWS::StackName",
},
- "RetentionInDays": Object {
+ "RetentionInDays": {
"Ref": "LogRetentionPeriod",
},
},
"Type": "AWS::Logs::LogGroup",
},
- "Logs6819BB44": Object {
+ "Logs6819BB44": {
"Condition": "LoggingInS3",
"DeletionPolicy": "Retain",
- "Metadata": Object {
- "cfn_nag": Object {
- "rules_to_suppress": Array [
- Object {
+ "Metadata": {
+ "cfn_nag": {
+ "rules_to_suppress": [
+ {
"id": "W35",
"reason": "Logs bucket does not require logging configuration",
},
- Object {
+ {
"id": "W51",
"reason": "Logs bucket is private and does not require a bucket policy",
},
],
},
},
- "Properties": Object {
- "BucketEncryption": Object {
- "ServerSideEncryptionConfiguration": Array [
- Object {
- "ServerSideEncryptionByDefault": Object {
- "KMSMasterKeyID": Object {
- "Fn::GetAtt": Array [
- "KMSKeyForNetworkFirewallLogDestinations70A79322",
+ "Properties": {
+ "BucketEncryption": {
+ "ServerSideEncryptionConfiguration": [
+ {
+ "ServerSideEncryptionByDefault": {
+ "KMSMasterKeyID": {
+ "Fn::GetAtt": [
+ "KMSKeyForNetworkFirewallBuckets73A57817",
"Arn",
],
},
@@ -1606,17 +1620,17 @@ Object {
},
],
},
- "LifecycleConfiguration": Object {
- "Rules": Array [
- Object {
- "ExpirationInDays": Object {
+ "LifecycleConfiguration": {
+ "Rules": [
+ {
+ "ExpirationInDays": {
"Ref": "LogRetentionPeriod",
},
"Status": "Enabled",
},
],
},
- "PublicAccessBlockConfiguration": Object {
+ "PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
@@ -1626,61 +1640,61 @@ Object {
"Type": "AWS::S3::Bucket",
"UpdateReplacePolicy": "Retain",
},
- "NetworkFirewallCodePipelineA72E3ADD": Object {
- "DependsOn": Array [
+ "NetworkFirewallCodePipelineA72E3ADD": {
+ "DependsOn": [
"NetworkFirewallCodePipelineRoleDefaultPolicyF0142ABD",
"NetworkFirewallCodePipelineRoleDDD28B15",
],
- "Properties": Object {
- "ArtifactStore": Object {
- "EncryptionKey": Object {
- "Id": Object {
- "Fn::GetAtt": Array [
+ "Properties": {
+ "ArtifactStore": {
+ "EncryptionKey": {
+ "Id": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
},
"Type": "KMS",
},
- "Location": Object {
+ "Location": {
"Ref": "NetworkFirewallCodePipelineArtifactsBucketF2569455",
},
"Type": "S3",
},
- "RoleArn": Object {
- "Fn::GetAtt": Array [
+ "RoleArn": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineRoleDDD28B15",
"Arn",
],
},
- "Stages": Array [
- Object {
- "Actions": Array [
- Object {
- "ActionTypeId": Object {
+ "Stages": [
+ {
+ "Actions": [
+ {
+ "ActionTypeId": {
"Category": "Source",
"Owner": "AWS",
"Provider": "CodeCommit",
"Version": "1",
},
- "Configuration": Object {
+ "Configuration": {
"BranchName": "main",
"PollForSourceChanges": false,
- "RepositoryName": Object {
- "Fn::GetAtt": Array [
+ "RepositoryName": {
+ "Fn::GetAtt": [
"NetworkFirewallCodeRepositoryF7BA0495",
"Name",
],
},
},
"Name": "Source",
- "OutputArtifacts": Array [
- Object {
+ "OutputArtifacts": [
+ {
"Name": "SourceArtifact",
},
],
- "RoleArn": Object {
- "Fn::GetAtt": Array [
+ "RoleArn": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineSourceCodePipelineActionRole67C89750",
"Arn",
],
@@ -1690,33 +1704,33 @@ Object {
],
"Name": "Source",
},
- Object {
- "Actions": Array [
- Object {
- "ActionTypeId": Object {
+ {
+ "Actions": [
+ {
+ "ActionTypeId": {
"Category": "Build",
"Owner": "AWS",
"Provider": "CodeBuild",
"Version": "1",
},
- "Configuration": Object {
- "ProjectName": Object {
+ "Configuration": {
+ "ProjectName": {
"Ref": "BuildProject097C5DB7",
},
},
- "InputArtifacts": Array [
- Object {
+ "InputArtifacts": [
+ {
"Name": "SourceArtifact",
},
],
"Name": "CodeBuild",
- "OutputArtifacts": Array [
- Object {
+ "OutputArtifacts": [
+ {
"Name": "BuildArtifact",
},
],
- "RoleArn": Object {
- "Fn::GetAtt": Array [
+ "RoleArn": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRole2A3E8726",
"Arn",
],
@@ -1726,28 +1740,28 @@ Object {
],
"Name": "Validation",
},
- Object {
- "Actions": Array [
- Object {
- "ActionTypeId": Object {
+ {
+ "Actions": [
+ {
+ "ActionTypeId": {
"Category": "Build",
"Owner": "AWS",
"Provider": "CodeBuild",
"Version": "1",
},
- "Configuration": Object {
- "ProjectName": Object {
+ "Configuration": {
+ "ProjectName": {
"Ref": "DeployProject1CF7CB79",
},
},
- "InputArtifacts": Array [
- Object {
+ "InputArtifacts": [
+ {
"Name": "BuildArtifact",
},
],
"Name": "CodeDeploy",
- "RoleArn": Object {
- "Fn::GetAtt": Array [
+ "RoleArn": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRole6EA7639D",
"Arn",
],
@@ -1761,38 +1775,22 @@ Object {
},
"Type": "AWS::CodePipeline::Pipeline",
},
- "NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060": Object {
+ "NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060": {
"DeletionPolicy": "Delete",
- "Properties": Object {
+ "Properties": {
"EnableKeyRotation": true,
- "KeyPolicy": Object {
- "Statement": Array [
- Object {
- "Action": Array [
- "kms:Create*",
- "kms:Describe*",
- "kms:Enable*",
- "kms:List*",
- "kms:Put*",
- "kms:Update*",
- "kms:Revoke*",
- "kms:Disable*",
- "kms:Get*",
- "kms:Delete*",
- "kms:ScheduleKeyDeletion",
- "kms:CancelKeyDeletion",
- "kms:GenerateDataKey",
- "kms:TagResource",
- "kms:UntagResource",
- ],
+ "KeyPolicy": {
+ "Statement": [
+ {
+ "Action": "kms:*",
"Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::Join": Array [
+ "Principal": {
+ "AWS": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":iam::1234:root",
@@ -1802,115 +1800,6 @@ Object {
},
"Resource": "*",
},
- Object {
- "Action": Array [
- "kms:Decrypt",
- "kms:DescribeKey",
- "kms:Encrypt",
- "kms:ReEncrypt*",
- "kms:GenerateDataKey*",
- ],
- "Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::GetAtt": Array [
- "NetworkFirewallCodePipelineRoleDDD28B15",
- "Arn",
- ],
- },
- },
- "Resource": "*",
- },
- Object {
- "Action": Array [
- "kms:Decrypt",
- "kms:DescribeKey",
- "kms:Encrypt",
- "kms:ReEncrypt*",
- "kms:GenerateDataKey*",
- ],
- "Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::GetAtt": Array [
- "NetworkFirewallCodePipelineSourceCodePipelineActionRole67C89750",
- "Arn",
- ],
- },
- },
- "Resource": "*",
- },
- Object {
- "Action": Array [
- "kms:Decrypt",
- "kms:DescribeKey",
- "kms:Encrypt",
- "kms:ReEncrypt*",
- "kms:GenerateDataKey*",
- ],
- "Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::GetAtt": Array [
- "BuildProjectRoleAA92C755",
- "Arn",
- ],
- },
- },
- "Resource": "*",
- },
- Object {
- "Action": Array [
- "kms:Decrypt",
- "kms:Encrypt",
- "kms:ReEncrypt*",
- "kms:GenerateDataKey*",
- ],
- "Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::GetAtt": Array [
- "BuildProjectRoleAA92C755",
- "Arn",
- ],
- },
- },
- "Resource": "*",
- },
- Object {
- "Action": Array [
- "kms:Decrypt",
- "kms:DescribeKey",
- ],
- "Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::GetAtt": Array [
- "DeployProjectRole588C8C1D",
- "Arn",
- ],
- },
- },
- "Resource": "*",
- },
- Object {
- "Action": Array [
- "kms:Decrypt",
- "kms:Encrypt",
- "kms:ReEncrypt*",
- "kms:GenerateDataKey*",
- ],
- "Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::GetAtt": Array [
- "DeployProjectRole588C8C1D",
- "Arn",
- ],
- },
- },
- "Resource": "*",
- },
],
"Version": "2012-10-17",
},
@@ -1918,23 +1807,23 @@ Object {
"Type": "AWS::KMS::Key",
"UpdateReplacePolicy": "Delete",
},
- "NetworkFirewallCodePipelineArtifactsBucketEncryptionKeyAlias1704A536": Object {
+ "NetworkFirewallCodePipelineArtifactsBucketEncryptionKeyAlias1704A536": {
"DeletionPolicy": "Delete",
- "Properties": Object {
- "AliasName": Object {
- "Fn::Join": Array [
+ "Properties": {
+ "AliasName": {
+ "Fn::Join": [
"",
- Array [
+ [
"alias/",
- Object {
+ {
"Ref": "AWS::StackName",
},
"-artifactBucket-EncryptionKeyAlias",
],
],
},
- "TargetKeyId": Object {
- "Fn::GetAtt": Array [
+ "TargetKeyId": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
@@ -1943,25 +1832,25 @@ Object {
"Type": "AWS::KMS::Alias",
"UpdateReplacePolicy": "Delete",
},
- "NetworkFirewallCodePipelineArtifactsBucketF2569455": Object {
+ "NetworkFirewallCodePipelineArtifactsBucketF2569455": {
"DeletionPolicy": "Retain",
- "Metadata": Object {
- "cfn_nag": Object {
- "rules_to_suppress": Array [
- Object {
+ "Metadata": {
+ "cfn_nag": {
+ "rules_to_suppress": [
+ {
"id": "W35",
"reason": "This S3 bucket is used as the destination for 'NetworkFirewallCodePipelineArtifactsBucket'",
},
],
},
},
- "Properties": Object {
- "BucketEncryption": Object {
- "ServerSideEncryptionConfiguration": Array [
- Object {
- "ServerSideEncryptionByDefault": Object {
- "KMSMasterKeyID": Object {
- "Fn::GetAtt": Array [
+ "Properties": {
+ "BucketEncryption": {
+ "ServerSideEncryptionConfiguration": [
+ {
+ "ServerSideEncryptionByDefault": {
+ "KMSMasterKeyID": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
@@ -1971,7 +1860,7 @@ Object {
},
],
},
- "PublicAccessBlockConfiguration": Object {
+ "PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
@@ -1981,20 +1870,67 @@ Object {
"Type": "AWS::S3::Bucket",
"UpdateReplacePolicy": "Retain",
},
- "NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRole6EA7639D": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "NetworkFirewallCodePipelineArtifactsBucketPolicyA1DE12F9": {
+ "Properties": {
+ "Bucket": {
+ "Ref": "NetworkFirewallCodePipelineArtifactsBucketF2569455",
+ },
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": "s3:*",
+ "Condition": {
+ "Bool": {
+ "aws:SecureTransport": "false",
+ },
+ },
+ "Effect": "Deny",
+ "Principal": {
+ "AWS": "*",
+ },
+ "Resource": [
+ {
+ "Fn::GetAtt": [
+ "NetworkFirewallCodePipelineArtifactsBucketF2569455",
+ "Arn",
+ ],
+ },
+ {
+ "Fn::Join": [
+ "",
+ [
+ {
+ "Fn::GetAtt": [
+ "NetworkFirewallCodePipelineArtifactsBucketF2569455",
+ "Arn",
+ ],
+ },
+ "/*",
+ ],
+ ],
+ },
+ ],
+ },
+ ],
+ "Version": "2012-10-17",
+ },
+ },
+ "Type": "AWS::S3::BucketPolicy",
+ },
+ "NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRole6EA7639D": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::Join": Array [
+ "Principal": {
+ "AWS": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":iam::1234:root",
@@ -2009,19 +1945,19 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRoleDefaultPolicyAB6FC4F9": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRoleDefaultPolicyAB6FC4F9": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild",
"codebuild:StopBuild",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"DeployProject1CF7CB79",
"Arn",
],
@@ -2031,22 +1967,22 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRoleDefaultPolicyAB6FC4F9",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRole6EA7639D",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "NetworkFirewallCodePipelineEventsRole94323A48": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "NetworkFirewallCodePipelineEventsRole94323A48": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
+ "Principal": {
"Service": "events.amazonaws.com",
},
},
@@ -2056,23 +1992,23 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "NetworkFirewallCodePipelineEventsRoleDefaultPolicy5835E037": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
+ "NetworkFirewallCodePipelineEventsRoleDefaultPolicy5835E037": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
"Action": "codepipeline:StartPipelineExecution",
"Effect": "Allow",
- "Resource": Object {
- "Fn::Join": Array [
+ "Resource": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":codepipeline:eu-west-1:1234:",
- Object {
+ {
"Ref": "NetworkFirewallCodePipelineA72E3ADD",
},
],
@@ -2083,22 +2019,22 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "NetworkFirewallCodePipelineEventsRoleDefaultPolicy5835E037",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "NetworkFirewallCodePipelineEventsRole94323A48",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "NetworkFirewallCodePipelineRoleDDD28B15": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "NetworkFirewallCodePipelineRoleDDD28B15": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
+ "Principal": {
"Service": "codepipeline.amazonaws.com",
},
},
@@ -2108,33 +2044,37 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "NetworkFirewallCodePipelineRoleDefaultPolicyF0142ABD": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "NetworkFirewallCodePipelineRoleDefaultPolicyF0142ABD": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:DeleteObject*",
- "s3:PutObject*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging",
"s3:Abort*",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::GetAtt": Array [
+ "Resource": [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
- Object {
- "Fn::GetAtt": Array [
+ [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
@@ -2145,8 +2085,8 @@ Object {
},
],
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
@@ -2154,38 +2094,38 @@ Object {
"kms:GenerateDataKey*",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
},
},
- Object {
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineSourceCodePipelineActionRole67C89750",
"Arn",
],
},
},
- Object {
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRole2A3E8726",
"Arn",
],
},
},
- Object {
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineDeploymentCodeDeployCodePipelineActionRole6EA7639D",
"Arn",
],
@@ -2195,28 +2135,28 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "NetworkFirewallCodePipelineRoleDefaultPolicyF0142ABD",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "NetworkFirewallCodePipelineRoleDDD28B15",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "NetworkFirewallCodePipelineSourceCodePipelineActionRole67C89750": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "NetworkFirewallCodePipelineSourceCodePipelineActionRole67C89750": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::Join": Array [
+ "Principal": {
+ "AWS": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":iam::1234:root",
@@ -2231,33 +2171,37 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "NetworkFirewallCodePipelineSourceCodePipelineActionRoleDefaultPolicyB01603D9": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "NetworkFirewallCodePipelineSourceCodePipelineActionRoleDefaultPolicyB01603D9": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:DeleteObject*",
- "s3:PutObject*",
+ "s3:PutObject",
+ "s3:PutObjectLegalHold",
+ "s3:PutObjectRetention",
+ "s3:PutObjectTagging",
+ "s3:PutObjectVersionTagging",
"s3:Abort*",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::GetAtt": Array [
+ "Resource": [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
- Object {
- "Fn::GetAtt": Array [
+ [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketF2569455",
"Arn",
],
@@ -2268,8 +2212,8 @@ Object {
},
],
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
@@ -2277,15 +2221,15 @@ Object {
"kms:GenerateDataKey*",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineArtifactsBucketEncryptionKey086ED060",
"Arn",
],
},
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"codecommit:GetBranch",
"codecommit:GetCommit",
"codecommit:UploadArchive",
@@ -2293,8 +2237,8 @@ Object {
"codecommit:CancelUploadArchive",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"NetworkFirewallCodeRepositoryF7BA0495",
"Arn",
],
@@ -2304,28 +2248,28 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "NetworkFirewallCodePipelineSourceCodePipelineActionRoleDefaultPolicyB01603D9",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "NetworkFirewallCodePipelineSourceCodePipelineActionRole67C89750",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRole2A3E8726": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRole2A3E8726": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
- "AWS": Object {
- "Fn::Join": Array [
+ "Principal": {
+ "AWS": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":iam::1234:root",
@@ -2340,19 +2284,19 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRoleDefaultPolicyA4A71A44": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRoleDefaultPolicyA4A71A44": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"codebuild:BatchGetBuilds",
"codebuild:StartBuild",
"codebuild:StopBuild",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"BuildProject097C5DB7",
"Arn",
],
@@ -2362,27 +2306,27 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRoleDefaultPolicyA4A71A44",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "NetworkFirewallCodePipelineValidationCodeBuildCodePipelineActionRole2A3E8726",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "NetworkFirewallCodeRepositoryF7BA0495": Object {
+ "NetworkFirewallCodeRepositoryF7BA0495": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "Code": Object {
- "S3": Object {
+ "Properties": {
+ "Code": {
+ "S3": {
"Bucket": "solutions-eu-west-1",
- "Key": Object {
- "Fn::Join": Array [
+ "Key": {
+ "Fn::Join": [
"",
- Array [
+ [
"network-firewall-automation/",
- Object {
- "Fn::FindInMap": Array [
+ {
+ "Fn::FindInMap": [
"SolutionMapping",
"Version",
"Latest",
@@ -2395,18 +2339,18 @@ Object {
},
},
"RepositoryDescription": "This repository is created by the AWS Network Firewall solution for AWS Transit Gateway, to store and trigger changes to the network firewall rules and configurations.",
- "RepositoryName": Object {
- "Fn::Join": Array [
+ "RepositoryName": {
+ "Fn::Join": [
"",
- Array [
- Object {
- "Fn::FindInMap": Array [
+ [
+ {
+ "Fn::FindInMap": [
"SolutionMapping",
"CodeCommitRepo",
"Name",
],
},
- Object {
+ {
"Ref": "AWS::StackName",
},
],
@@ -2416,54 +2360,54 @@ Object {
"Type": "AWS::CodeCommit::Repository",
"UpdateReplacePolicy": "Retain",
},
- "NetworkFirewallCodeRepositoryMyTestStackNetworkFirewallCodePipelineD8BFDC90mainEventRule334BD2D0": Object {
- "Properties": Object {
- "EventPattern": Object {
- "detail": Object {
- "event": Array [
+ "NetworkFirewallCodeRepositoryMyTestStackNetworkFirewallCodePipelineD8BFDC90mainEventRule334BD2D0": {
+ "Properties": {
+ "EventPattern": {
+ "detail": {
+ "event": [
"referenceCreated",
"referenceUpdated",
],
- "referenceName": Array [
+ "referenceName": [
"main",
],
},
- "detail-type": Array [
+ "detail-type": [
"CodeCommit Repository State Change",
],
- "resources": Array [
- Object {
- "Fn::GetAtt": Array [
+ "resources": [
+ {
+ "Fn::GetAtt": [
"NetworkFirewallCodeRepositoryF7BA0495",
"Arn",
],
},
],
- "source": Array [
+ "source": [
"aws.codecommit",
],
},
"State": "ENABLED",
- "Targets": Array [
- Object {
- "Arn": Object {
- "Fn::Join": Array [
+ "Targets": [
+ {
+ "Arn": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":codepipeline:eu-west-1:1234:",
- Object {
+ {
"Ref": "NetworkFirewallCodePipelineA72E3ADD",
},
],
],
},
"Id": "Target0",
- "RoleArn": Object {
- "Fn::GetAtt": Array [
+ "RoleArn": {
+ "Fn::GetAtt": [
"NetworkFirewallCodePipelineEventsRole94323A48",
"Arn",
],
@@ -2473,24 +2417,24 @@ Object {
},
"Type": "AWS::Events::Rule",
},
- "NetworkFirewallSubnet1": Object {
+ "NetworkFirewallSubnet1": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "AvailabilityZone": Object {
- "Fn::Select": Array [
+ "Properties": {
+ "AvailabilityZone": {
+ "Fn::Select": [
"0",
- Object {
+ {
"Fn::GetAZs": "",
},
],
},
- "CidrBlock": Object {
- "Fn::Select": Array [
+ "CidrBlock": {
+ "Fn::Select": [
0,
- Object {
- "Fn::Cidr": Array [
- Object {
- "Fn::GetAtt": Array [
+ {
+ "Fn::Cidr": [
+ {
+ "Fn::GetAtt": [
"VPC",
"CidrBlock",
],
@@ -2501,14 +2445,14 @@ Object {
},
],
},
- "Tags": Array [
- Object {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-FirewallSubnet1",
@@ -2517,44 +2461,44 @@ Object {
},
},
],
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::Subnet",
"UpdateReplacePolicy": "Retain",
},
- "NetworkFirewallSubnet1RouteTableAssociation": Object {
+ "NetworkFirewallSubnet1RouteTableAssociation": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "RouteTableId": Object {
+ "Properties": {
+ "RouteTableId": {
"Ref": "FirewallSubnetRouteTable",
},
- "SubnetId": Object {
+ "SubnetId": {
"Ref": "NetworkFirewallSubnet1",
},
},
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"UpdateReplacePolicy": "Retain",
},
- "NetworkFirewallSubnet2": Object {
+ "NetworkFirewallSubnet2": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "AvailabilityZone": Object {
- "Fn::Select": Array [
+ "Properties": {
+ "AvailabilityZone": {
+ "Fn::Select": [
"1",
- Object {
+ {
"Fn::GetAZs": "",
},
],
},
- "CidrBlock": Object {
- "Fn::Select": Array [
+ "CidrBlock": {
+ "Fn::Select": [
1,
- Object {
- "Fn::Cidr": Array [
- Object {
- "Fn::GetAtt": Array [
+ {
+ "Fn::Cidr": [
+ {
+ "Fn::GetAtt": [
"VPC",
"CidrBlock",
],
@@ -2565,14 +2509,14 @@ Object {
},
],
},
- "Tags": Array [
- Object {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-FirewallSubnet2",
@@ -2581,34 +2525,34 @@ Object {
},
},
],
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::Subnet",
"UpdateReplacePolicy": "Retain",
},
- "NetworkFirewallSubnet2RouteTableAssociation": Object {
+ "NetworkFirewallSubnet2RouteTableAssociation": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "RouteTableId": Object {
+ "Properties": {
+ "RouteTableId": {
"Ref": "FirewallSubnetRouteTable",
},
- "SubnetId": Object {
+ "SubnetId": {
"Ref": "NetworkFirewallSubnet2",
},
},
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"UpdateReplacePolicy": "Retain",
},
- "RoleFlowLogsCA794118": Object {
- "Properties": Object {
- "AssumeRolePolicyDocument": Object {
- "Statement": Array [
- Object {
+ "RoleFlowLogsCA794118": {
+ "Properties": {
+ "AssumeRolePolicyDocument": {
+ "Statement": [
+ {
"Action": "sts:AssumeRole",
"Effect": "Allow",
- "Principal": Object {
+ "Principal": {
"Service": "vpc-flow-logs.amazonaws.com",
},
},
@@ -2618,12 +2562,12 @@ Object {
},
"Type": "AWS::IAM::Role",
},
- "RoleFlowLogsDefaultPolicyD1F03EF4": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "RoleFlowLogsDefaultPolicyD1F03EF4": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"logs:CreateLogStream",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
@@ -2631,8 +2575,8 @@ Object {
"logs:DescribeLogGroups",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"LogGroupFlowLogs",
"Arn",
],
@@ -2642,54 +2586,54 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "RoleFlowLogsDefaultPolicyD1F03EF4",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "RoleFlowLogsCA794118",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "TGWRoute": Object {
+ "TGWRoute": {
"Condition": "CreateTransitGatewayAttachment",
- "DependsOn": Array [
+ "DependsOn": [
"VPCTGWATTACHMENT",
],
- "Properties": Object {
- "DestinationCidrBlock": Object {
- "Fn::FindInMap": Array [
+ "Properties": {
+ "DestinationCidrBlock": {
+ "Fn::FindInMap": [
"SolutionMapping",
"Route",
"QuadZero",
],
},
- "RouteTableId": Object {
+ "RouteTableId": {
"Ref": "FirewallSubnetRouteTable",
},
- "TransitGatewayId": Object {
+ "TransitGatewayId": {
"Ref": "ExistingTransitGateway",
},
},
"Type": "AWS::EC2::Route",
},
- "VPC": Object {
+ "VPC": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "CidrBlock": Object {
+ "Properties": {
+ "CidrBlock": {
"Ref": "cidrBlock",
},
- "Tags": Array [
- Object {
+ "Tags": [
+ {
"Key": "created-by",
"Value": "network-firewall-automation",
},
- Object {
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-Inspection-VPC",
@@ -2702,26 +2646,26 @@ Object {
"Type": "AWS::EC2::VPC",
"UpdateReplacePolicy": "Retain",
},
- "VPCTGWATTACHMENT": Object {
+ "VPCTGWATTACHMENT": {
"Condition": "CreateTransitGatewayAttachment",
"DeletionPolicy": "Retain",
- "Properties": Object {
- "SubnetIds": Array [
- Object {
+ "Properties": {
+ "SubnetIds": [
+ {
"Ref": "VPCTGWSubnet1",
},
- Object {
+ {
"Ref": "VPCTGWSubnet2",
},
],
- "Tags": Array [
- Object {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-Inspection-VPC-Attachment",
@@ -2730,26 +2674,26 @@ Object {
},
},
],
- "TransitGatewayId": Object {
+ "TransitGatewayId": {
"Ref": "ExistingTransitGateway",
},
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::TransitGatewayAttachment",
},
- "VPCTGWRouteTable1": Object {
+ "VPCTGWRouteTable1": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "Tags": Array [
- Object {
+ "Properties": {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-TGWSubnetRouteTable1",
@@ -2758,24 +2702,24 @@ Object {
},
},
],
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::RouteTable",
"UpdateReplacePolicy": "Retain",
},
- "VPCTGWRouteTable2": Object {
+ "VPCTGWRouteTable2": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "Tags": Array [
- Object {
+ "Properties": {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-TGWSubnetRouteTable2",
@@ -2784,44 +2728,44 @@ Object {
},
},
],
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::RouteTable",
"UpdateReplacePolicy": "Retain",
},
- "VPCTGWRouteTableAssociation": Object {
+ "VPCTGWRouteTableAssociation": {
"Condition": "CreateTransitGatewayRTAssociation",
"DeletionPolicy": "Retain",
- "Properties": Object {
- "TransitGatewayAttachmentId": Object {
+ "Properties": {
+ "TransitGatewayAttachmentId": {
"Ref": "VPCTGWATTACHMENT",
},
- "TransitGatewayRouteTableId": Object {
+ "TransitGatewayRouteTableId": {
"Ref": "TransitGatewayRouteTableIdForAssociation",
},
},
"Type": "AWS::EC2::TransitGatewayRouteTableAssociation",
},
- "VPCTGWSubnet1": Object {
+ "VPCTGWSubnet1": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "AvailabilityZone": Object {
- "Fn::Select": Array [
+ "Properties": {
+ "AvailabilityZone": {
+ "Fn::Select": [
"0",
- Object {
+ {
"Fn::GetAZs": "",
},
],
},
- "CidrBlock": Object {
- "Fn::Select": Array [
+ "CidrBlock": {
+ "Fn::Select": [
2,
- Object {
- "Fn::Cidr": Array [
- Object {
- "Fn::GetAtt": Array [
+ {
+ "Fn::Cidr": [
+ {
+ "Fn::GetAtt": [
"VPC",
"CidrBlock",
],
@@ -2832,14 +2776,14 @@ Object {
},
],
},
- "Tags": Array [
- Object {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-VPCTGWSubnet1",
@@ -2848,44 +2792,44 @@ Object {
},
},
],
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::Subnet",
"UpdateReplacePolicy": "Retain",
},
- "VPCTGWSubnet1RouteTableAssociation": Object {
+ "VPCTGWSubnet1RouteTableAssociation": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "RouteTableId": Object {
+ "Properties": {
+ "RouteTableId": {
"Ref": "VPCTGWRouteTable1",
},
- "SubnetId": Object {
+ "SubnetId": {
"Ref": "VPCTGWSubnet1",
},
},
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"UpdateReplacePolicy": "Retain",
},
- "VPCTGWSubnet2": Object {
+ "VPCTGWSubnet2": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "AvailabilityZone": Object {
- "Fn::Select": Array [
+ "Properties": {
+ "AvailabilityZone": {
+ "Fn::Select": [
"1",
- Object {
+ {
"Fn::GetAZs": "",
},
],
},
- "CidrBlock": Object {
- "Fn::Select": Array [
+ "CidrBlock": {
+ "Fn::Select": [
3,
- Object {
- "Fn::Cidr": Array [
- Object {
- "Fn::GetAtt": Array [
+ {
+ "Fn::Cidr": [
+ {
+ "Fn::GetAtt": [
"VPC",
"CidrBlock",
],
@@ -2896,14 +2840,14 @@ Object {
},
],
},
- "Tags": Array [
- Object {
+ "Tags": [
+ {
"Key": "Name",
- "Value": Object {
- "Fn::Join": Array [
+ "Value": {
+ "Fn::Join": [
"",
- Array [
- Object {
+ [
+ {
"Ref": "AWS::StackName",
},
"-VPCTGWSubnet2",
@@ -2912,71 +2856,71 @@ Object {
},
},
],
- "VpcId": Object {
+ "VpcId": {
"Ref": "VPC",
},
},
"Type": "AWS::EC2::Subnet",
"UpdateReplacePolicy": "Retain",
},
- "VPCTGWSubnet2RouteTableAssociation": Object {
+ "VPCTGWSubnet2RouteTableAssociation": {
"DeletionPolicy": "Retain",
- "Properties": Object {
- "RouteTableId": Object {
+ "Properties": {
+ "RouteTableId": {
"Ref": "VPCTGWRouteTable2",
},
- "SubnetId": Object {
+ "SubnetId": {
"Ref": "VPCTGWSubnet2",
},
},
"Type": "AWS::EC2::SubnetRouteTableAssociation",
"UpdateReplacePolicy": "Retain",
},
- "buildStageIAMPolicyB31D4B98": Object {
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "buildStageIAMPolicyB31D4B98": {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"network-firewall:CreateFirewallPolicy",
"network-firewall:CreateRuleGroup",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
+ "Resource": [
+ {
"Fn::Sub": "arn:\${AWS::Partition}:network-firewall:\${AWS::Region}:\${AWS::AccountId}:stateful-rulegroup/*",
},
- Object {
+ {
"Fn::Sub": "arn:\${AWS::Partition}:network-firewall:\${AWS::Region}:\${AWS::AccountId}:firewall-policy/*",
},
- Object {
+ {
"Fn::Sub": "arn:\${AWS::Partition}:network-firewall:\${AWS::Region}:\${AWS::AccountId}:stateless-rulegroup/*",
},
],
},
- Object {
+ {
"Action": "s3:GetObject",
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::Sub": Array [
+ "Resource": [
+ {
+ "Fn::Sub": [
"arn:\${AWS::Partition}:s3:::\${CodeBucketName}/\${KeyName}/*",
- Object {
+ {
"CodeBucketName": "solutions-eu-west-1",
"KeyName": "network-firewall-automation",
},
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":s3:::",
- Object {
+ {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
"/*",
@@ -2985,19 +2929,19 @@ Object {
},
],
},
- Object {
+ {
"Action": "s3:PutObject",
"Effect": "Allow",
- "Resource": Object {
- "Fn::Join": Array [
+ "Resource": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":s3:::",
- Object {
+ {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
"/*",
@@ -3005,18 +2949,18 @@ Object {
],
},
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"ssm:PutParameter",
"ssm:GetParameter",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::Sub": Array [
- "arn:\${AWS::Partition}:ssm:\${AWS::Region}:\${AWS::AccountId}:parameter/\${ParameterKey}",
- Object {
- "ParameterKey": Object {
- "Fn::FindInMap": Array [
+ "Resource": {
+ "Fn::Sub": [
+ "arn:\${AWS::Partition}:ssm:\${AWS::Region}:\${AWS::AccountId}:parameter/\${ParameterKey}-*",
+ {
+ "ParameterKey": {
+ "Fn::FindInMap": [
"Send",
"ParameterKey",
"UniqueId",
@@ -3030,41 +2974,41 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "buildStageIAMPolicyB31D4B98",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "BuildProjectRoleAA92C755",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "deployStageFirewallLoggingCWPolicyD4098456": Object {
+ "deployStageFirewallLoggingCWPolicyD4098456": {
"Condition": "LoggingInCloudWatch",
- "Metadata": Object {
- "cfn_nag": Object {
- "rules_to_suppress": Array [
- Object {
+ "Metadata": {
+ "cfn_nag": {
+ "rules_to_suppress": [
+ {
"id": "W12",
"reason": "Resource * is required for describe APIs",
},
],
},
},
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"logs:PutResourcePolicy",
"logs:DescribeResourcePolicies",
],
"Effect": "Allow",
"Resource": "*",
},
- Object {
+ {
"Action": "logs:DescribeLogGroups",
"Effect": "Allow",
- "Resource": Object {
+ "Resource": {
"Fn::Sub": "arn:\${AWS::Partition}:logs:*:\${AWS::AccountId}:log-group:*",
},
},
@@ -3072,31 +3016,31 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "deployStageFirewallLoggingCWPolicyD4098456",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "DeployProjectRole588C8C1D",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "deployStageFirewallLoggingPolicy15AD5CD5": Object {
+ "deployStageFirewallLoggingPolicy15AD5CD5": {
"Condition": "NotLoggingConfigureManually",
- "Metadata": Object {
- "cfn_nag": Object {
- "rules_to_suppress": Array [
- Object {
+ "Metadata": {
+ "cfn_nag": {
+ "rules_to_suppress": [
+ {
"id": "W12",
"reason": "Resource * is required for these actions.",
},
],
},
},
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"logs:CreateLogDelivery",
"logs:GetLogDelivery",
"logs:UpdateLogDelivery",
@@ -3110,27 +3054,27 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "deployStageFirewallLoggingPolicy15AD5CD5",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "DeployProjectRole588C8C1D",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "deployStageFirewallLoggingS3Policy8F79BDD2": Object {
+ "deployStageFirewallLoggingS3Policy8F79BDD2": {
"Condition": "LoggingInS3",
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"s3:PutBucketPolicy",
"s3:GetBucketPolicy",
],
"Effect": "Allow",
- "Resource": Object {
- "Fn::GetAtt": Array [
+ "Resource": {
+ "Fn::GetAtt": [
"Logs6819BB44",
"Arn",
],
@@ -3140,30 +3084,30 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "deployStageFirewallLoggingS3Policy8F79BDD2",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "DeployProjectRole588C8C1D",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "deployStageFirewallPolicy72BE60BE": Object {
- "Metadata": Object {
- "cfn_nag": Object {
- "rules_to_suppress": Array [
- Object {
+ "deployStageFirewallPolicy72BE60BE": {
+ "Metadata": {
+ "cfn_nag": {
+ "rules_to_suppress": [
+ {
"id": "W12",
"reason": "Resource * is required for describe APIs",
},
],
},
},
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
- "Action": Array [
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
+ "Action": [
"network-firewall:CreateFirewall",
"network-firewall:UpdateFirewallDeleteProtection",
"network-firewall:DeleteRuleGroup",
@@ -3186,44 +3130,44 @@ Object {
"network-firewall:TagResource",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
+ "Resource": [
+ {
"Fn::Sub": "arn:\${AWS::Partition}:network-firewall:\${AWS::Region}:\${AWS::AccountId}:stateful-rulegroup/*",
},
- Object {
+ {
"Fn::Sub": "arn:\${AWS::Partition}:network-firewall:\${AWS::Region}:\${AWS::AccountId}:firewall-policy/*",
},
- Object {
+ {
"Fn::Sub": "arn:\${AWS::Partition}:network-firewall:\${AWS::Region}:\${AWS::AccountId}:firewall/*",
},
- Object {
+ {
"Fn::Sub": "arn:\${AWS::Partition}:network-firewall:\${AWS::Region}:\${AWS::AccountId}:stateless-rulegroup/*",
},
],
},
- Object {
+ {
"Action": "s3:GetObject",
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::Sub": Array [
+ "Resource": [
+ {
+ "Fn::Sub": [
"arn:\${AWS::Partition}:s3:::\${CodeBucketName}/\${KeyName}/*",
- Object {
+ {
"CodeBucketName": "solutions-eu-west-1",
"KeyName": "network-firewall-automation",
},
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":s3:::",
- Object {
+ {
"Ref": "CodeBuildStagesSourceCodeBucketFA98E7C7",
},
"/*",
@@ -3232,8 +3176,8 @@ Object {
},
],
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"ec2:DescribeRouteTables",
@@ -3241,54 +3185,54 @@ Object {
"Effect": "Allow",
"Resource": "*",
},
- Object {
- "Action": Array [
+ {
+ "Action": [
"ec2:CreateRoute",
"ec2:DeleteRoute",
],
"Effect": "Allow",
- "Resource": Array [
- Object {
- "Fn::Join": Array [
+ "Resource": [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":ec2:",
- Object {
+ {
"Ref": "AWS::Region",
},
":",
- Object {
+ {
"Ref": "AWS::AccountId",
},
":route-table/",
- Object {
+ {
"Ref": "VPCTGWRouteTable1",
},
],
],
},
- Object {
- "Fn::Join": Array [
+ {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":ec2:",
- Object {
+ {
"Ref": "AWS::Region",
},
":",
- Object {
+ {
"Ref": "AWS::AccountId",
},
":route-table/",
- Object {
+ {
"Ref": "VPCTGWRouteTable2",
},
],
@@ -3296,10 +3240,10 @@ Object {
},
],
},
- Object {
+ {
"Action": "iam:CreateServiceLinkedRole",
"Effect": "Allow",
- "Resource": Object {
+ "Resource": {
"Fn::Sub": "arn:aws:iam::\${AWS::AccountId}:role/aws-service-role/network-firewall.amazonaws.com/AWSServiceRoleForNetworkFirewall",
},
},
@@ -3307,40 +3251,40 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "deployStageFirewallPolicy72BE60BE",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "DeployProjectRole588C8C1D",
},
],
},
"Type": "AWS::IAM::Policy",
},
- "deployStageModifyTransitGatewayAttachmentPolicy993566C2": Object {
+ "deployStageModifyTransitGatewayAttachmentPolicy993566C2": {
"Condition": "CreateTransitGatewayAttachment",
- "Properties": Object {
- "PolicyDocument": Object {
- "Statement": Array [
- Object {
+ "Properties": {
+ "PolicyDocument": {
+ "Statement": [
+ {
"Action": "ec2:ModifyTransitGatewayVpcAttachment",
"Effect": "Allow",
- "Resource": Object {
- "Fn::Join": Array [
+ "Resource": {
+ "Fn::Join": [
"",
- Array [
+ [
"arn:",
- Object {
+ {
"Ref": "AWS::Partition",
},
":ec2:",
- Object {
+ {
"Ref": "AWS::Region",
},
":",
- Object {
+ {
"Ref": "AWS::AccountId",
},
":transit-gateway-attachment/",
- Object {
+ {
"Ref": "VPCTGWATTACHMENT",
},
],
@@ -3351,8 +3295,8 @@ Object {
"Version": "2012-10-17",
},
"PolicyName": "deployStageModifyTransitGatewayAttachmentPolicy993566C2",
- "Roles": Array [
- Object {
+ "Roles": [
+ {
"Ref": "DeployProjectRole588C8C1D",
},
],
@@ -3360,5 +3304,32 @@ Object {
"Type": "AWS::IAM::Policy",
},
},
+ "Rules": {
+ "CheckBootstrapVersion": {
+ "Assertions": [
+ {
+ "Assert": {
+ "Fn::Not": [
+ {
+ "Fn::Contains": [
+ [
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ ],
+ {
+ "Ref": "BootstrapVersion",
+ },
+ ],
+ },
+ ],
+ },
+ "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.",
+ },
+ ],
+ },
+ },
}
`;
diff --git a/source/test/network-firewall-automation-solution.test.ts b/source/test/network-firewall-automation-solution.test.ts
index 38c6580..a9bbd86 100644
--- a/source/test/network-firewall-automation-solution.test.ts
+++ b/source/test/network-firewall-automation-solution.test.ts
@@ -1,38 +1,36 @@
-/**
- * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
- * with the License. A copy of the License is located at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
- * OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
+/*
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0
*/
-import * as cdk from '@aws-cdk/core';
-import { SynthUtils } from '@aws-cdk/assert';
-import * as NetworkFirewallAutomationStack from "../lib/network-firewall-automation-solution-stack"
-import '@aws-cdk/assert/jest';
-
+import { App, Stack } from 'aws-cdk-lib';
+import { Template } from 'aws-cdk-lib/assertions';
+import {
+ NetworkFirewallAutomationStack,
+ NetworkFirewallAutomationStackProps,
+} from '../lib/network-firewall-automation-solution-stack';
-function getTestStack(): cdk.Stack {
- const app = new cdk.App();
- const props: NetworkFirewallAutomationStack.NetworkFirewallAutomationStackProps = {
- env: { account: '1234', region: 'eu-west-1' },
- solutionBucket: 'solutions',
- solutionId: 'SO0108',
- solutionName: 'network-firewall-automation',
- solutionProvider: 'AWS Solutions Builders',
- solutionTradeMarkName: 'network-firewall-automation',
- solutionVersion: 'v1.0.0'
- };
- return new NetworkFirewallAutomationStack.NetworkFirewallAutomationStack(app, 'MyTestStack', props)
+function getTestStack(): Stack {
+ const app = new App();
+ const props: NetworkFirewallAutomationStackProps = {
+ env: { account: '1234', region: 'eu-west-1' },
+ solutionBucket: 'solutions',
+ solutionId: 'SO0108',
+ solutionName: 'network-firewall-automation',
+ solutionProvider: 'AWS Solutions Builders',
+ solutionTradeMarkName: 'network-firewall-automation',
+ solutionVersion: 'v1.0.2',
+ };
+ return new NetworkFirewallAutomationStack(app, 'MyTestStack', props);
}
-/*
- * Snapshot test
- */
-test('NetworkFirewallAutomationStack Snapshot test', () => {
- expect(SynthUtils.toCloudFormation(getTestStack())).toMatchSnapshot();
-});
\ No newline at end of file
+
+describe('Firewall Automation for Network Traffic on AWS', () => {
+ const stack = getTestStack();
+ const template = Template.fromStack(stack);
+ /*
+ * Snapshot test
+ */
+ test('NetworkFirewallAutomationStack Snapshot test', () => {
+ expect(template.toJSON()).toMatchSnapshot();
+ });
+});