From 423cffd898f90baf8209f8a39617750572c90517 Mon Sep 17 00:00:00 2001 From: Stephen Watts Date: Wed, 26 Feb 2025 13:29:34 +1100 Subject: [PATCH 01/11] First pass on refactor as an oncoanalyser-specific CDK application (#9) --- README.md | 128 +- application/application-stack.ts | 133 - application/base-pipeline-stack.ts | 306 --- application/constants.ts | 17 - application/pipeline-stacks/common.ts | 213 -- .../assets/nextflow_aws.template.config | 304 --- .../oncoanalyser/assets/run-v2.sh | 976 ------- .../oncoanalyser/assets/run.sh | 627 ----- .../batch_job_submission/lambda_code.py | 293 --- .../pipeline-stacks/oncoanalyser/stack.ts | 10 - application/pipeline-stacks/sash/Dockerfile | 102 - .../sash/assets/nextflow_aws.template.config | 137 - .../pipeline-stacks/sash/assets/run-v2.sh | 539 ---- .../pipeline-stacks/sash/assets/run.sh | 436 ---- .../batch_job_submission/lambda_code.py | 191 -- application/pipeline-stacks/sash/stack.ts | 10 - .../pipeline-stacks/star-align-nf/Dockerfile | 101 - .../assets/nextflow_aws.template.config | 63 - .../star-align-nf/assets/run.sh | 369 --- .../batch_job_submission/lambda_code.py | 178 -- .../pipeline-stacks/star-align-nf/stack.ts | 10 - .../resources/launch_templates/ebs.txt | 32 - .../resources/launch_templates/nvme.txt | 13 - application/settings.ts | 126 - application/shared/base-roles.ts | 210 -- application/shared/batch-queues.ts | 120 - bin/oncoanalyser-stack.ts | 15 + cdk.json | 43 +- deployment/codepipeline-stack.ts | 124 - deployment/nextflow-stack.ts | 21 - deployment/settings-umccr.ts | 30 - lib/application-stack.ts | 376 +++ .../oncoanalyser => lib/resources}/Dockerfile | 27 +- lib/resources/nextflow_aws.template.config | 254 ++ lib/resources/run.sh | 81 + lib/settings.ts | 19 + package-lock.json | 2315 ++++++++--------- package.json | 25 +- ...ack.test.ts => oncoanalyser-stack.test.ts} | 6 +- tsconfig.json | 3 +- 40 files changed, 1877 insertions(+), 7106 deletions(-) delete mode 100644 application/application-stack.ts delete mode 100644 application/base-pipeline-stack.ts delete mode 100644 application/constants.ts delete mode 100644 application/pipeline-stacks/common.ts delete mode 100644 application/pipeline-stacks/oncoanalyser/assets/nextflow_aws.template.config delete mode 100755 application/pipeline-stacks/oncoanalyser/assets/run-v2.sh delete mode 100755 application/pipeline-stacks/oncoanalyser/assets/run.sh delete mode 100644 application/pipeline-stacks/oncoanalyser/lambda_functions/batch_job_submission/lambda_code.py delete mode 100644 application/pipeline-stacks/oncoanalyser/stack.ts delete mode 100644 application/pipeline-stacks/sash/Dockerfile delete mode 100644 application/pipeline-stacks/sash/assets/nextflow_aws.template.config delete mode 100755 application/pipeline-stacks/sash/assets/run-v2.sh delete mode 100755 application/pipeline-stacks/sash/assets/run.sh delete mode 100644 application/pipeline-stacks/sash/lambda_functions/batch_job_submission/lambda_code.py delete mode 100644 application/pipeline-stacks/sash/stack.ts delete mode 100644 application/pipeline-stacks/star-align-nf/Dockerfile delete mode 100644 application/pipeline-stacks/star-align-nf/assets/nextflow_aws.template.config delete mode 100755 application/pipeline-stacks/star-align-nf/assets/run.sh delete mode 100644 application/pipeline-stacks/star-align-nf/lambda_functions/batch_job_submission/lambda_code.py delete mode 100644 application/pipeline-stacks/star-align-nf/stack.ts delete mode 100644 application/resources/launch_templates/ebs.txt delete mode 100644 application/resources/launch_templates/nvme.txt delete mode 100644 application/settings.ts delete mode 100644 application/shared/base-roles.ts delete mode 100644 application/shared/batch-queues.ts create mode 100644 bin/oncoanalyser-stack.ts delete mode 100644 deployment/codepipeline-stack.ts delete mode 100644 deployment/nextflow-stack.ts delete mode 100644 deployment/settings-umccr.ts create mode 100644 lib/application-stack.ts rename {application/pipeline-stacks/oncoanalyser => lib/resources}/Dockerfile (77%) create mode 100644 lib/resources/nextflow_aws.template.config create mode 100755 lib/resources/run.sh create mode 100644 lib/settings.ts rename test/{nextflow-stack.test.ts => oncoanalyser-stack.test.ts} (65%) diff --git a/README.md b/README.md index be9e80c..9315fe5 100644 --- a/README.md +++ b/README.md @@ -1,122 +1,14 @@ -# nextflow-stack +# Welcome to your CDK TypeScript project -An AWS stack for running Nextflow pipelines on Batch using shared resources. +This is a blank project for CDK development with TypeScript. -🚧 +The `cdk.json` file tells the CDK Toolkit how to execute your app. -Highlight key aspects +## Useful commands -* Precise resource allocation requests under SPOT pricing model -* No EBS costs and local SSD discounted via SPOT pricing -* No duplication of Batch queues -* Fusion, Wave -* Improved resume experience compared to use of ephermal workdir disk -* Ability to highly optimise instances for individual processes - -Future work - -* Dynamic queue selection -* Retry on SPOT pre-emption X times -* BYO bucket -* CodePipeline for deployment -* Improve configuration and data handling - -## Table of contents - -🚧 - -## Deployment - -🚧 - -* Detail application stacks that must be deployed aplus additional set up (i.e. ECR, Docker images) - -### Development - -> `deployment/development-stack.ts` - -### CodePipeline CI/CD - -> `deployment/codepipeline-stack.ts` - -## Pipelines - -🚧 - -### oncoanalyser - -🚧 - -### star-align-nf - -🚧 - -> `umccr/star-align-nf` - -### UMCCR post-processing - -🚧 - -#### Design - -🚧 - -Diagram (avoid overlap with Overview diagram) including reference data etc - -Section detailing current compromises - -* GDS token access -* Migrating data from GDS to S3 for execution -* Not fully optimised for speed; show timeline or similar -* Many Docker images on DockerHub, ideally would be on ECR - * Must resolve 502 errors in Wave when pulling from grch.io or ECR -* Only broad control over processes run currently -* Passing run configuration by CLI args is somewhat clumsy - * Alternative: JSON on remote (S3, API call); could be extended to general config - -Items that need to be addressed - -* **Important**: Isofox takes an expected count file that is dependent of read length - * So we **must** be sure that we're using expected counts for the correct read length -* Application still tied to UMCCR VPC and other resources -* Repetition between pipeline stacks and associated code (run.sh, Dockerfile, etc) -* Cannot parallelise workflow stack deployment in CodePipeline with waves in current set up -* Extra arguments for `run.sh` are ignored, error should be raised -* Job cancellation is difficult when the pipeline crashes -* I have observed a rare issue with unexpected Fusion shutdown that interrupts processing -* Staging data from GDS to S3 suffers significant slow down after ~one hour (bursting related?) - * Could spin out multiple instances or high capacity instance improve transfer speed - -Other notes - -* Nextflow config `nextflow_aws.config` could be split into processes and input -* Include other parameters in config: HMF refdata path, VBE path, genome version, workdir -* To discuss staged data location, sorting, structure, retention -* Lifecycle of data in Nextflow S3 workdir; single workdir or per run/sample/etc - -#### Usage - -🚧 - -Diagram describing common run modes with correponding commands - -Run modes (relative to CUPPA) - -* WGTS -* WGS only -* WTS only -* WGTS with existing WGS -* WGTS with existing WTS -* WGTS with existing WGS and WTS - -> include run resuming and use of this as an alternative to providing existing data - -> note how to run any individual process/stage with the appropriate inputs - -#### Notes - -🚧 - -Other important items to note - -* Fusion usually gives much better performance but not always +* `npm run build` compile typescript to js +* `npm run watch` watch for changes and compile +* `npm run test` perform the jest unit tests +* `npx cdk deploy` deploy this stack to your default AWS account/region +* `npx cdk diff` compare deployed stack with current state +* `npx cdk synth` emits the synthesized CloudFormation template diff --git a/application/application-stack.ts b/application/application-stack.ts deleted file mode 100644 index 2cbd7ef..0000000 --- a/application/application-stack.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { Construct } from 'constructs' - -import * as cdk from 'aws-cdk-lib'; - -import * as baseStack from './base-pipeline-stack'; -import * as settings from './settings'; - -import { OncoanalyserStack } from './pipeline-stacks/oncoanalyser/stack'; -import { SashStack } from './pipeline-stacks/sash/stack'; -import { StarAlignNfStack } from './pipeline-stacks/star-align-nf/stack'; - - -interface IApplicationBuildStackProps extends cdk.StackProps { - env: cdk.Environment; - envName: string; - envBuild: cdk.Environment; - dockerTag?: string; -} - -interface IBuildStack extends IApplicationBuildStackProps { - workflowName: string; - jobQueuePipelineArns: string[]; - jobQueueTaskArns: string[]; -} - - -export class ApplicationStack extends cdk.Stack { - constructor(scope: Construct, id: string, props: IApplicationBuildStackProps) { - super(scope, id, props); - - // Create shared resources and add tags - const stackPipelineBase = new baseStack.BasePipelineStack(this, 'BasePipelineStack', { - env: props.env, - }); - cdk.Tags.of(stackPipelineBase).add('Stack', 'NextflowStack'); - - // Create individual pipeline stacks - this.buildOncoanalyserStack({ - workflowName: 'oncoanalyser', - jobQueuePipelineArns: stackPipelineBase.jobQueuePipelineArns, - jobQueueTaskArns: stackPipelineBase.jobQueueTaskArns, - ...props, - }); - - this.buildSashStack({ - workflowName: 'sash', - jobQueuePipelineArns: stackPipelineBase.jobQueuePipelineArns, - jobQueueTaskArns: stackPipelineBase.jobQueueTaskArns, - ...props, - }); - - this.buildStarAlignNfStack({ - workflowName: 'star-align-nf', - jobQueuePipelineArns: stackPipelineBase.jobQueuePipelineArns, - jobQueueTaskArns: stackPipelineBase.jobQueueTaskArns, - ...props, - }); - } - - buildOncoanalyserStack(args: IBuildStack) { - const stackSettings = new settings.Oncoanalyser(args.envName, args.workflowName); - const s3Data = stackSettings.getS3Data(); - - const pipelineStack = new OncoanalyserStack(this, 'OncoanalyserStack', { - ...args, - pipelineVersionTag: stackSettings.versionTag, - nfBucketName: s3Data.get('nfBucketName')!, - nfPrefixTemp: s3Data.get('nfPrefixTemp')!, - nfPrefixOutput: s3Data.get('nfPrefixOutput')!, - orcabusDataS3BucketName: s3Data.get('orcabusS3BucketName')!, - orcabusDataS3ByobPrefix: s3Data.get('orcabusS3ByobPrefix')!, - orcabusDataS3PrefixOutput: s3Data.get('orcabusS3PrefixOutput')!, - orcabusDataS3PrefixTemp: s3Data.get('orcabusS3PrefixTemp')!, - refdataBucketName: s3Data.get('refdataBucketName')!, - refdataPrefix: s3Data.get('refdataPrefix')!, - ssmParameters: stackSettings.getSsmParameters() - }); - cdk.Tags.of(pipelineStack).add('Stack', 'OncoanalyserStack'); - } - - buildSashStack(args: IBuildStack) { - const stackSettings = new settings.Sash(args.envName, args.workflowName); - const s3Data = stackSettings.getS3Data(); - - const pipelineStack = new SashStack(this, 'SashStack', { - ...args, - pipelineVersionTag: stackSettings.versionTag, - nfBucketName: s3Data.get('nfBucketName')!, - nfPrefixTemp: s3Data.get('nfPrefixTemp')!, - nfPrefixOutput: s3Data.get('nfPrefixOutput')!, - orcabusDataS3BucketName: s3Data.get('orcabusS3BucketName')!, - orcabusDataS3ByobPrefix: s3Data.get('orcabusS3ByobPrefix')!, - orcabusDataS3PrefixOutput: s3Data.get('orcabusS3PrefixOutput')!, - orcabusDataS3PrefixTemp: s3Data.get('orcabusS3PrefixTemp')!, - refdataBucketName: s3Data.get('refdataBucketName')!, - refdataPrefix: s3Data.get('refdataPrefix')!, - ssmParameters: stackSettings.getSsmParameters(), - }); - cdk.Tags.of(pipelineStack).add('Stack', 'SashStack'); - } - - buildStarAlignNfStack(args: IBuildStack) { - const stackSettings = new settings.StarAlignNf(args.envName, args.workflowName); - const s3Data = stackSettings.getS3Data(); - - const pipelineStack = new StarAlignNfStack(this, 'StarAlignNfStack', { - ...args, - pipelineVersionTag: stackSettings.versionTag, - nfBucketName: s3Data.get('nfBucketName')!, - nfPrefixTemp: s3Data.get('nfPrefixTemp')!, - nfPrefixOutput: s3Data.get('nfPrefixOutput')!, - refdataBucketName: s3Data.get('refdataBucketName')!, - orcabusDataS3BucketName: s3Data.get('orcabusS3BucketName')!, - orcabusDataS3ByobPrefix: s3Data.get('orcabusS3ByobPrefix')!, - orcabusDataS3PrefixOutput: s3Data.get('orcabusS3PrefixOutput')!, - orcabusDataS3PrefixTemp: s3Data.get('orcabusS3PrefixTemp')!, - refdataPrefix: s3Data.get('refdataPrefix')!, - ssmParameters: stackSettings.getSsmParameters(), - }); - cdk.Tags.of(pipelineStack).add('Stack', 'StarAlignNfStack'); - } -} - - -export class ApplicationBuildStage extends cdk.Stage { - constructor(scope: Construct, id: string, props: IApplicationBuildStackProps) { - super(scope, id, props); - - const applicationStack = new ApplicationStack(this, 'NextflowApplicationStack', props); - - cdk.Tags.of(applicationStack).add('Stack', 'NextflowStack'); - } -} diff --git a/application/base-pipeline-stack.ts b/application/base-pipeline-stack.ts deleted file mode 100644 index 2ef330b..0000000 --- a/application/base-pipeline-stack.ts +++ /dev/null @@ -1,306 +0,0 @@ -import { Construct } from 'constructs'; - -import * as fs from 'fs'; -import * as path from 'path'; - -import * as batch from 'aws-cdk-lib/aws-batch'; -import * as cdk from 'aws-cdk-lib'; -import * as ec2 from 'aws-cdk-lib/aws-ec2'; -import * as iam from 'aws-cdk-lib/aws-iam'; - -import * as baseRoles from './shared/base-roles'; -import * as batchQueues from './shared/batch-queues'; -import * as constants from './constants'; -import * as settings from './settings'; - - -export class BasePipelineStack extends cdk.Stack { - public readonly jobQueuePipelineArns: string[] = []; - public readonly jobQueueTaskArns: string[] = []; - - constructor(scope: Construct, id: string, props?: cdk.StackProps) { - super(scope, id, props); - - // Collect existing misc general resource - const vpc = ec2.Vpc.fromLookup(this, 'MainVPC', { - vpcName: 'main-vpc', - }); - - const securityGroup = ec2.SecurityGroup.fromLookupByName( - this, - 'SecurityGroupOutBoundOnly', - 'main-vpc-sg-outbound', - vpc, - ); - - // Create resources, store job queue ARNs for reference in other constructs - this.createTaskResources({ - queueTypes: settings.taskQueueTypes, - storageTypes: settings.taskInstanceStorageTypes, - vpc: vpc, - securityGroup: securityGroup, - }); - - this.createPipelineResources({ - storageTypes: settings.taskInstanceStorageTypes, - vpc: vpc, - securityGroup: securityGroup, - }); - - } - - createTaskResources(args: { - queueTypes: constants.QueueType[], - storageTypes: constants.InstanceStorageType[], - vpc: ec2.IVpc, - securityGroup: ec2.ISecurityGroup, - }) { - // NOTE(SW): default job role and should be overridden by a custom job role defined in an individual stack - const roleBatchInstanceTask = baseRoles.getRoleBatchInstanceTask({ - context: this, - workflowName: 'base', - }); - - let roleBatchSpotfleetTask; - if (args.queueTypes.includes(constants.QueueType.Spot)) { - - roleBatchSpotfleetTask = new iam.Role(this, 'BaseTaskBatchSpotFleetRole', { - assumedBy: new iam.ServicePrincipal('spotfleet.amazonaws.com'), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2SpotFleetTaggingRole'), - ], - }); - - } - - for (let storageType of args.storageTypes) { - const launchTemplateTask = this.getLaunchTemplate({ - namespace: 'BaseTask', - storageType: storageType, - securityGroup: args.securityGroup, - }); - - for (let queueType of args.queueTypes) { - - let jobQueueTaskArns: Map = new Map(); - - for (let taskQueueData of batchQueues.taskQueues) { - - let [computeEnvironment, jobQueue] = this.getComputeEnvironment({ - queueData: taskQueueData, - queueType: queueType, - storageType: storageType, - vpc: args.vpc, - launchTemplate: launchTemplateTask, - roleBatchInstance: roleBatchInstanceTask, - roleBatchSpotfleet: roleBatchSpotfleetTask, - serviceType: constants.ServiceType.Task, - }); - - this.jobQueueTaskArns.push(jobQueue.jobQueueArn); - } - } - } - } - - createPipelineResources(args: { - storageTypes: constants.InstanceStorageType[], - vpc: ec2.IVpc, - securityGroup: ec2.ISecurityGroup, - }) { - // NOTE(SW): default job role and should be overridden by a custom job role defined in an individual stack - const roleBatchInstance = baseRoles.getBaseBatchInstancePipelineRole({ - context: this, - workflowName: 'base', - jobQueueArns: Array.from(this.jobQueueTaskArns.values()), - }); - - - // NOTE(SW): here we make a special case for the pipeline queue in the UMCCR environment. This exception is designed - // to met existing compatibility requirements for the external orchestrator service (single queue, constant queue - // name) while allowing runs with and without FusionFS. This is done by: - // (1) creating a single pipeline queue with a predefined constant name - // (2) forcing the pipeline queue storage type to 'NvmeSsdOnly' for FusionFS compatibility - // - // One side-effect of this is that pipelines not using FusionFS will still be run on instance with NVMe SSD but - // won't utilise that resource. - const queueName = constants.PIPELINE_BATCH_QUEUE_BASENAME; - const storageType = constants.InstanceStorageType.NvmeSsdOnly; - - - const launchTemplate = this.getLaunchTemplate({ - namespace: 'BasePipeline', - storageType: storageType, - securityGroup: args.securityGroup, - }); - - const [computeEnvironment, jobQueue] = this.getComputeEnvironment({ - queueData: batchQueues.pipelineQueue, - queueType: constants.QueueType.Ondemand, - storageType: storageType, - vpc: args.vpc, - launchTemplate: launchTemplate, - roleBatchInstance: roleBatchInstance, - serviceType: constants.ServiceType.Pipeline, - queueName: queueName, - }); - - this.jobQueuePipelineArns.push(jobQueue.jobQueueArn); - } - - getLaunchTemplate(args: { - namespace: string, - storageType: constants.InstanceStorageType, - securityGroup: ec2.ISecurityGroup, - }) { - - // NOTE(SW): EBS user data installs required packages for Amazon Elastic Block Store Autoscale - // set in the Cloud Config block - - // NOTE(SW): The AWS CLIv2 install must not clobber Docker paths otherwise the corresponding - // paths in the Docker container will be mounted over. The Amazon Elastic Block Store Autoscale - // install and daemon also require AWS CLIv2 to be in path, so I symlink it into /usr/local/bin - - // NOTE(SW): using UserData.addCommands does not render with a MIME block when passed to the - // batch-alpha.ComputeEnvironment, which then results in an invalid compute environment - - // Get and apply user data for all task lts and only for the pipeline + FusionFS/NVMeSSD lts. No - // user data is currently needed for the pipeline + EBS lts. - let userDataTask - if (args.namespace == 'BaseTask' || (args.namespace == 'BasePipeline' && args.storageType === constants.InstanceStorageType.NvmeSsdOnly)) { - let userDataFn: string; - switch(args.storageType) { - case(constants.InstanceStorageType.EbsOnly): - userDataFn = 'ebs.txt'; - break; - case(constants.InstanceStorageType.NvmeSsdOnly): - userDataFn = 'nvme.txt'; - break; - default: - throw new Error('Got bad storage type'); - } - - const userDataFp: string = path.join(__dirname, 'resources/launch_templates/', userDataFn); - const userDataString = fs.readFileSync(userDataFp, {encoding: 'utf-8'}); - userDataTask = ec2.UserData.custom(userDataString); - } - - const launchTemplate = new ec2.LaunchTemplate(this, `${args.namespace}LaunchTemplate-${args.storageType.toLowerCase()}`, { - launchTemplateName: `nextflow-${args.namespace.toLowerCase()}-${args.storageType.toLowerCase()}-launch-template`, - associatePublicIpAddress: true, - userData: userDataTask, - securityGroup: args.securityGroup, - requireImdsv2: true, - httpTokens: ec2.LaunchTemplateHttpTokens.REQUIRED, - }); - - let instanceName: string; - if (args.namespace == 'BaseTask') { - instanceName = 'nextflow-task'; - } else if (args.namespace == 'BasePipeline') { - instanceName = 'nextflow-pipeline'; - } else { - throw new Error('Got bad namespace'); - } - cdk.Tags.of(launchTemplate).add('Name', instanceName); - - return launchTemplate; - } - - getComputeEnvironment(args: { - queueData: batchQueues.IQueueData, - queueType: constants.QueueType, - storageType: constants.InstanceStorageType, - vpc: ec2.IVpc, - launchTemplate: ec2.ILaunchTemplate, - roleBatchInstance: iam.Role, - roleBatchSpotfleet?: iam.Role, - serviceType: constants.ServiceType, - queueName?: string, - }): [batch.ManagedEc2EcsComputeEnvironment, batch.JobQueue] { - - let queueDataInstanceTypeKey: string; - switch (args.storageType) { - case constants.InstanceStorageType.EbsOnly: - queueDataInstanceTypeKey = 'standard'; - break; - case constants.InstanceStorageType.NvmeSsdOnly: - queueDataInstanceTypeKey = 'nvme_ssd'; - break; - default: - throw new Error('Got bad storage type'); - } - - if (!args.queueData.instances.has(queueDataInstanceTypeKey)) { - throw new Error(`Got bad instance type key, "${queueDataInstanceTypeKey}"`); - } - - const instanceTypes = args.queueData.instances.get(queueDataInstanceTypeKey)! - .map((typeStr) => { - return new ec2.InstanceType(typeStr); - }); - - let spotMode; - let roleBatchSpotfleet; - let allocationStrategy; - switch (args.queueType) { - case constants.QueueType.Ondemand: - spotMode = false; - roleBatchSpotfleet = undefined; - allocationStrategy = batch.AllocationStrategy.BEST_FIT; - break; - case constants.QueueType.Spot: - spotMode = true; - roleBatchSpotfleet = args.roleBatchSpotfleet; - allocationStrategy = batch.AllocationStrategy.SPOT_CAPACITY_OPTIMIZED; - break; - default: - throw new Error('Got bad queue type'); - } - - let queueName: string; - if (args.queueName) { - queueName = args.queueName; - } else { - queueName = batchQueues.getQueueName({ - queueBaseName: args.queueData.name, - queueType: args.queueType, - storageType: args.storageType, - serviceType: args.serviceType, - }); - } - - // NOTE(SW): the new default behaviour of UMCCR subnets to not assign/associate public IP addresses for EC2 - // instances is overridden in the launch template. However, setting this override causes the launch template to - // create a network interface, which includes a security group. The consequence of this is that the security group - // configuration must be moved to the launch template since it cannot be defined in both the compute environment or - // launch template network interface. This is done in part below by setting the `securityGroups` arg as an empty list. - - const computeEnvId = `BaseComputeEnvironment-${queueName}`; - const computeEnvironment = new batch.ManagedEc2EcsComputeEnvironment(this, computeEnvId, { - allocationStrategy: allocationStrategy, - instanceRole: args.roleBatchInstance, - instanceTypes: instanceTypes, - launchTemplate: args.launchTemplate, - maxvCpus: args.queueData.maxvCpus ?? settings.maxvCpusDefault, - securityGroups: [], - spot: spotMode, - spotFleetRole: roleBatchSpotfleet, - useOptimalInstanceClasses: false, - vpc: args.vpc, - vpcSubnets: { - subnetType: ec2.SubnetType.PUBLIC, - }, - }); - - const jobQueueId = `BaseJobQueue-${queueName}`; - const jobQueue = new batch.JobQueue(this, jobQueueId, { - jobQueueName: `nextflow-${queueName}`, - computeEnvironments: [ - { computeEnvironment: computeEnvironment, order: 1 }, - ], - }); - - return [computeEnvironment, jobQueue]; - } -} diff --git a/application/constants.ts b/application/constants.ts deleted file mode 100644 index fc8f9c0..0000000 --- a/application/constants.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const PIPELINE_BATCH_QUEUE_BASENAME: string = 'pipeline' - - -export enum ServiceType { - Task = 'TASK', - Pipeline = 'PIPELINE', -} - -export enum QueueType { - Ondemand = 'ONDEMAND', - Spot = 'SPOT', -} - -export enum InstanceStorageType { - EbsOnly = 'EBS', - NvmeSsdOnly = 'NVME_SSD', -} diff --git a/application/pipeline-stacks/common.ts b/application/pipeline-stacks/common.ts deleted file mode 100644 index 830b891..0000000 --- a/application/pipeline-stacks/common.ts +++ /dev/null @@ -1,213 +0,0 @@ -import * as path from 'path'; - -import { Construct } from 'constructs'; - -import * as batch from 'aws-cdk-lib/aws-batch'; -import * as cdk from 'aws-cdk-lib'; -import * as ecr from 'aws-cdk-lib/aws-ecr'; -import * as ecrAssets from 'aws-cdk-lib/aws-ecr-assets'; -import * as ecs from 'aws-cdk-lib/aws-ecs'; -import * as iam from 'aws-cdk-lib/aws-iam' -import * as lambda from 'aws-cdk-lib/aws-lambda' -import * as s3 from 'aws-cdk-lib/aws-s3'; -import * as ssm from 'aws-cdk-lib/aws-ssm'; - -import * as ecrDeployment from 'cdk-ecr-deployment'; - -import * as baseRoles from '../shared/base-roles'; - - -interface IDockerImageBuild extends cdk.StackProps { - env: cdk.Environment; - workflowName: string; - gitReference: string; - dockerTag?: string; -} - -export interface IPipelineStack extends cdk.StackProps { - env: cdk.Environment; - envBuild: cdk.Environment; - workflowName: string; - pipelineVersionTag: string; - dockerTag?: string; - jobQueuePipelineArns: string[]; - jobQueueTaskArns: string[]; - nfBucketName: string; - nfPrefixTemp: string; - nfPrefixOutput: string; - orcabusDataS3BucketName: string; - orcabusDataS3ByobPrefix: string; - orcabusDataS3PrefixTemp: string; - orcabusDataS3PrefixOutput: string; - refdataBucketName: string; - refdataPrefix: string; - ssmParameters: Map; -} - - -export class PipelineStack extends cdk.Stack { - constructor(scope: Construct, id: string, props: IPipelineStack) { - super(scope, id, props); - - // Create Docker image and deploy - const dockerStack = new DockerImageBuildStack(this, `DockerImageBuildStack-${props.workflowName}`, { - env: props.envBuild, - workflowName: props.workflowName, - gitReference: props.pipelineVersionTag, - dockerTag: props.dockerTag, - }); - - // Create roles - const stackRoles = baseRoles.createPipelineRoles({ - context: this, - workflowName: props.workflowName, - jobQueueArns: props.jobQueueTaskArns, - }); - - // Bucket permissions - const nfBucket = s3.Bucket.fromBucketName(this, `S3Bucket-nfBucket-${props.workflowName}`, - props.nfBucketName, - ); - - nfBucket.grantReadWrite(stackRoles.taskRole, `${props.nfPrefixTemp}/*/${props.workflowName}/*`); - nfBucket.grantReadWrite(stackRoles.pipelineRole, `${props.nfPrefixTemp}/*/${props.workflowName}/*`); - - nfBucket.grantReadWrite(stackRoles.taskRole, `${props.nfPrefixOutput}/*/${props.workflowName}/*`); - nfBucket.grantReadWrite(stackRoles.pipelineRole, `${props.nfPrefixOutput}/*/${props.workflowName}/*`); - - // New bucket permissions - // We don't have control over this bucket from this stack - // Instead we are just granting permissions to the roles we create - const orcabusDataBucket = s3.Bucket.fromBucketName(this, `S3Bucket-orcabusDataBucket-${props.workflowName}`, - props.orcabusDataS3BucketName, - ); - - // Roles can read and write to the temp and output directories - // We don't finish with a slash on the prefix to allow for the wildcard - // because we have workflow names oncoanalyser-wgts-dna and oncoanalyser-wgts-rna - [ - stackRoles.taskRole, - stackRoles.pipelineRole - ].forEach(role => { - orcabusDataBucket.grantReadWrite(role, `${props.orcabusDataS3PrefixTemp}*`); - orcabusDataBucket.grantDelete(role, `${props.orcabusDataS3PrefixTemp}*`); - orcabusDataBucket.grantReadWrite(role, `${props.orcabusDataS3PrefixOutput}*`); - orcabusDataBucket.grantRead(role, `${props.orcabusDataS3ByobPrefix}*`) - }) - - const refdataBucket = s3.Bucket.fromBucketName(this, `S3Bucket-refdataBucket-${props.workflowName}`, - props.refdataBucketName, - ); - - refdataBucket.grantRead(stackRoles.taskRole, `${props.refdataPrefix}/*`); - refdataBucket.grantRead(stackRoles.pipelineRole, `${props.refdataPrefix}/*`); - - // Create job definition for pipeline execution - const pipelineJobDefinition = new batch.EcsJobDefinition(this, `Nextflow-${props.workflowName}`, { - jobDefinitionName: `Nextflow-${props.workflowName}`, - container: new batch.EcsEc2ContainerDefinition(this, `Nextflow-Container-${props.workflowName}`, { - cpu: 1, - image: dockerStack.image, - command: ['true'], - memory: cdk.Size.mebibytes(1000), - jobRole: stackRoles.pipelineRole, - // NOTE(SW): host Docker socket is mounted in the container to launch Docker containers for local processes - volumes: [ - batch.EcsVolume.host({ - name: 'docker_socket', - containerPath: '/var/run/docker.sock', - hostPath: '/var/run/docker.sock', - readonly: false, - }), - ], - }), - }); - - // Create Lambda function role - const lambdaSubmissionRole = new iam.Role(this, `LambdaSubmitRole-${props.workflowName}`, { - assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMReadOnlyAccess'), - iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole'), - ] - }); - - new iam.Policy(this, `LambdaBatchPolicy-${props.workflowName}`, { - roles: [lambdaSubmissionRole], - statements: [new iam.PolicyStatement({ - actions: [ - 'batch:SubmitJob', - 'batch:TagResource', - ], - resources: [ - ...props.jobQueuePipelineArns, - pipelineJobDefinition.jobDefinitionArn, - ], - })], - }); - - // Create Lambda function - const aws_lambda_function = new lambda.Function(this, `LambdaSubmissionFunction-${props.workflowName}`, { - functionName: `${props.workflowName}-batch-job-submission`, - handler: 'lambda_code.main', - runtime: lambda.Runtime.PYTHON_3_9, - code: lambda.Code.fromAsset(path.join(__dirname, props.workflowName, 'lambda_functions', 'batch_job_submission')), - role: lambdaSubmissionRole - }); - - // Create SSM parameters - new ssm.StringParameter(this, `SsmParameter-batch_job_definition-${props.workflowName}`, { - parameterName: `/nextflow_stack/${props.workflowName}/batch_job_definition_arn`, - stringValue: pipelineJobDefinition.jobDefinitionArn, - }); - - new ssm.StringParameter(this, `SsmParameter-batch_instance_task_role-${props.workflowName}`, { - parameterName: `/nextflow_stack/${props.workflowName}/batch_instance_task_role_arn`, - stringValue: stackRoles.taskRole.roleArn, - }); - - new ssm.StringParameter(this, `SsmParameter-batch_instance_task_profile-${props.workflowName}`, { - parameterName: `/nextflow_stack/${props.workflowName}/batch_instance_task_profile_arn`, - stringValue: stackRoles.taskProfile.attrArn, - }); - - new ssm.StringParameter(this, `SsmParameter-submission_lambda-${props.workflowName}`, { - parameterName: `/nextflow_stack/${props.workflowName}/submission_lambda_arn`, - stringValue: aws_lambda_function.functionArn, - }); - - // Store SSM parameters from settings - for (let [key, value] of props.ssmParameters) { - new ssm.StringParameter(this, `SsmParameter-${key.replace(/^.*\//, '')}-${props.workflowName}`, { - parameterName: key, - stringValue: value, - }); - } - } -} - - -export class DockerImageBuildStack extends cdk.Stack { - public readonly image: ecs.EcrImage; - - constructor(scope: Construct, id: string, props: IDockerImageBuild) { - super(scope, id, props); - - const dockerTag = props.dockerTag || 'latest'; - - const image = new ecrAssets.DockerImageAsset(this, `CDKDockerImage-${props.workflowName}`, { - buildArgs: { 'PIPELINE_GITHUB_REF': props.gitReference }, - directory: path.join(__dirname, props.workflowName), - }); - - const dockerDestBase = `${props.env.account}.dkr.ecr.${props.env.region}.amazonaws.com`; - - new ecrDeployment.ECRDeployment(this, `DeployDockerImage-${props.workflowName}`, { - src: new ecrDeployment.DockerImageName(image.imageUri), - dest: new ecrDeployment.DockerImageName(`${dockerDestBase}/${props.workflowName}:${dockerTag}`), - }); - - const ecrRepository = ecr.Repository.fromRepositoryName(this, `EcrRespository-${props.workflowName}`, props.workflowName); - this.image = ecs.EcrImage.fromEcrRepository(ecrRepository, dockerTag); - } -} diff --git a/application/pipeline-stacks/oncoanalyser/assets/nextflow_aws.template.config b/application/pipeline-stacks/oncoanalyser/assets/nextflow_aws.template.config deleted file mode 100644 index a15ed42..0000000 --- a/application/pipeline-stacks/oncoanalyser/assets/nextflow_aws.template.config +++ /dev/null @@ -1,304 +0,0 @@ -plugins { - id 'nf-amazon' -} - -fusion { - enabled = true -} - -wave { - enabled = true -} - -aws { - batch { - jobRole = '__BATCH_INSTANCE_ROLE__' - volumes = '/mnt/local_ephemeral/:/tmp/' - } -} - -params { - - max_fastq_records = 250000000 - - genomes { - GRCh38_umccr { - fasta = "__S3_GENOMES_DATA_PATH__/GRCh38_umccr/GRCh38_full_analysis_set_plus_decoy_hla.fa" - fai = "__S3_GENOMES_DATA_PATH__/GRCh38_umccr/samtools_index/1.16/GRCh38_full_analysis_set_plus_decoy_hla.fa.fai" - dict = "__S3_GENOMES_DATA_PATH__/GRCh38_umccr/samtools_index/1.16/GRCh38_full_analysis_set_plus_decoy_hla.fa.dict" - bwamem2_index = "__S3_GENOMES_DATA_PATH__/GRCh38_umccr/bwa-mem2_index/2.2.1/" - gridss_index = "__S3_GENOMES_DATA_PATH__/GRCh38_umccr/gridss_index/2.13.2/" - star_index = "__S3_GENOMES_DATA_PATH__/GRCh38_umccr/star_index/gencode_38/2.7.3a/" - } - } - -} - -process { - executor = 'awsbatch' - scratch = false - - // NOTE(SW): using docker.runOptions in 23.10.01 causes `--network host` to be included twice, triggering an error in Docker - containerOptions = '--network host' - - resourceLabels = { - return [ - 'Stack': 'NextflowStack', - 'SubStack': 'OncoanalyserStack', - 'RunId': '__PORTAL_RUN_ID__', - 'JobName': task.process, - ] - } - - withName: 'FASTP' { - queue = 'nextflow-task-ondemand-16cpu_32gb-nvme_ssd' - cpus = 16 - memory = 30.GB - } - - withName: 'BWAMEM2_ALIGN' { - queue = 'nextflow-task-ondemand-32cpu_64gb-nvme_ssd' - cpus = 32 - memory = 60.GB - } - - withName: 'MARKDUPS' { - queue = 'nextflow-task-ondemand-16cpu_128gb-nvme_ssd' - cpus = 16 - memory = 120.GB - } - - withName: 'STAR_ALIGN' { - queue = 'nextflow-task-ondemand-8cpu_64gb-nvme_ssd' - cpus = 8 - memory = 60.GB - } - - withName: 'SAMTOOLS_SORT' { - queue = 'nextflow-task-ondemand-8cpu_32gb-nvme_ssd' - cpus = 8 - memory = 30.GB - } - - withName: 'SAMBAMBA_MERGE' { - queue = 'nextflow-task-ondemand-8cpu_32gb-nvme_ssd' - cpus = 8 - memory = 30.GB - } - - withName: 'GATK4_MARKDUPLICATES' { - queue = 'nextflow-task-ondemand-8cpu_32gb-nvme_ssd' - cpus = 8 - memory = 30.GB - } - - withName: 'AMBER' { - queue = 'nextflow-task-ondemand-8cpu_32gb-nvme_ssd' - cpus = 8 - memory = 30.GB - } - - withName: 'COBALT' { - queue = 'nextflow-task-ondemand-8cpu_32gb-nvme_ssd' - cpus = 8 - memory = 30.GB - } - - withName: 'SVPREP_TUMOR' { - errorStrategy = 'retry' - maxRetries = 1 - - queue = { task.attempt == 1 ? 'nextflow-task-ondemand-16cpu_64gb-nvme_ssd' : 'nextflow-task-ondemand-16cpu_128gb-nvme_ssd' } - cpus = { task.attempt == 1 ? 16 : 8 } - memory = { task.attempt == 1 ? 60.GB : 122.GB } - } - - withName: 'SVPREP_NORMAL' { - queue = 'nextflow-task-ondemand-16cpu_32gb-nvme_ssd' - cpus = 16 - memory = 30.GB - } - - withName: '.*:GRIDSS_SVPREP_CALLING:ASSEMBLE' { - errorStrategy = 'retry' - maxRetries = 1 - - time = 12.h - - queue = { task.attempt == 1 ? 'nextflow-task-ondemand-16cpu_32gb-nvme_ssd' : 'nextflow-task-ondemand-16cpu_128gb-nvme_ssd' } - cpus = 16 - memory = { task.attempt == 1 ? 30.GB : 122.GB } - } - - withName: '.*:GRIDSS_SVPREP_CALLING:(PREPROCESS|CALL)' { - queue = 'nextflow-task-ondemand-16cpu_32gb-nvme_ssd' - cpus = 16 - memory = 30.GB - } - - withName: '.*:GRIDSS_SVPREP_CALLING:DEPTH_ANNOTATOR' { - errorStrategy = 'retry' - maxRetries = 1 - - queue = { task.attempt == 1 ? 'nextflow-task-ondemand-16cpu_64gb-nvme_ssd' : 'nextflow-task-ondemand-16cpu_128gb-nvme_ssd' } - cpus = { task.attempt == 1 ? 16 : 8 } - memory = { task.attempt == 1 ? 60.GB : 122.GB } - } - - withName: '.*:GRIPSS_FILTERING:(?:GERMLINE|SOMATIC)' { - queue = 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' - cpus = 4 - memory = 30.GB - } - - withName: '.*:SAGE_CALLING:GERMLINE' { - queue = 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' - cpus = 4 - memory = 30.GB - } - - withName: '.*:SAGE_CALLING:SOMATIC' { - queue = 'nextflow-task-ondemand-16cpu_32gb-nvme_ssd' - cpus = 16 - memory = 30.GB - } - - withName: '.*:SAGE_APPEND:(?:GERMLINE|SOMATIC)' { - queue = 'nextflow-task-ondemand-2cpu_16gb-nvme_ssd' - cpus = 2 - memory = 14.GB - } - - withName: '.*:PAVE_ANNOTATION:GERMLINE' { - queue = 'nextflow-task-ondemand-2cpu_16gb-nvme_ssd' - cpus = 2 - memory = 14.GB - } - - // NOTE(SW): PAVE somatic uses a significant amount of memory, runtime is usually less than 5-10 minutes - - withName: '.*:PAVE_ANNOTATION:SOMATIC' { - queue = 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' - cpus = 4 - memory = 30.GB - } - - withName: 'PURPLE' { - errorStrategy = 'retry' - maxRetries = 1 - - queue = { task.attempt == 1 ? 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' : 'nextflow-task-ondemand-8cpu_64gb-nvme_ssd' } - cpus = { task.attempt == 1 ? 4 : 8 } - memory = { task.attempt == 1 ? 30.GB : 60.GB } - } - - withName: '.*:LINX_ANNOTATION:(?:GERMLINE|SOMATIC)' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - - withName: '.*:LINX_PLOTTING:VISUALISER' { - errorStrategy = 'retry' - maxRetries = 1 - - queue = 'nextflow-task-ondemand-8cpu_64gb-nvme_ssd' - cpus = 8 - memory = 60.GB - } - - withName: '.*:LINX_PLOTTING:REPORT' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - - withName: 'BAMTOOLS' { - - // TODO(SW): can use much less memory for this process; create new CPU queue or determine whether performance over fusion is good enough for nextflow-task-16cpu_32gb - - queue = 'nextflow-task-ondemand-8cpu_32gb-nvme_ssd' - cpus = 8 - memory = 30.GB - time = 24.h - } - - withName: 'CHORD' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - - withName: 'LILAC' { - queue = 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' - cpus = 4 - memory = 30.GB - } - - withName: '.*:LILAC_CALLING:EXTRACTCONTIG' { - queue = 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' - cpus = 4 - memory = 30.GB - } - - withName: '.*:LILAC_CALLING:REALIGNREADS' { - queue = 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' - cpus = 4 - memory = 30.GB - } - - withName: '.*:LILAC_CALLING:SLICEBAM' { - queue = 'nextflow-task-ondemand-4cpu_32gb-nvme_ssd' - cpus = 4 - memory = 30.GB - } - - withName: 'SIGS' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - - withName: 'VIRUSBREAKEND' { - queue = 'nextflow-task-ondemand-8cpu_64gb-nvme_ssd' - cpus = 8 - memory = 60.GB - } - - withName: 'VIRUSINTERPRETER' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - - withName: 'ISOFOX' { - queue = 'nextflow-task-ondemand-8cpu_32gb-nvme_ssd' - cpus = 8 - memory = 30.GB - } - - withName: 'CUPPA' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - - withName: 'SAMTOOLS_FLAGSTAT' { - queue = 'nextflow-task-ondemand-2cpu_16gb-nvme_ssd' - cpus = 2 - memory = 14.GB - } - - withName: 'ORANGE' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - - withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - -} diff --git a/application/pipeline-stacks/oncoanalyser/assets/run-v2.sh b/application/pipeline-stacks/oncoanalyser/assets/run-v2.sh deleted file mode 100755 index 9c92bbb..0000000 --- a/application/pipeline-stacks/oncoanalyser/assets/run-v2.sh +++ /dev/null @@ -1,976 +0,0 @@ -#!/usr/bin/env bash - -# Set up to fail -set -euo pipefail - -## GLOBALS ## -MAIN_NF_PATH="software/oncoanalyser/main.nf" -TEMPLATE_CONFIG_PATH="/root/pipeline/assets/nextflow_aws.template.config" -NEXTFLOW_CONFIG_PATH="aws.config" - -VALID_MODES=( \ - "wgts" \ - "targeted" \ -) -VALID_ANALYSIS_TYPES=( \ - "DNA" \ - "RNA" \ - "DNA/RNA" \ -) - -# BASE REQUIREMENTS -REQUIRED_INPUTS_ARGS=( \ - "mode" \ - "subject_id" \ -) - -REQUIRED_ENGINE_PARAMETER_ARGS=( \ - "portal_run_id" \ - "output_results_dir" \ - "output_scratch_dir" \ -) - -# MODE / SAMPLE TYPE SPECIFIC REQUIREMENTS -REQUIRED_INPUTS_ARGS_WGTS_DNA=( \ - "tumor_dna_sample_id" \ - "normal_dna_sample_id" \ - "tumor_dna_bam_uri" \ - "normal_dna_bam_uri" \ -) - -REQUIRED_INPUTS_ARGS_WGTS_RNA=( \ - "tumor_rna_sample_id" \ - "tumor_rna_fastq_list_rows" \ -) - -REQUIRED_INPUTS_ARGS_WGTS_DNA_RNA=( \ - "dna_oncoanalyser_analysis_uri" \ - "rna_oncoanalyser_analysis_uri" \ -) - -# INTERMEDIATE FILES -SAMPLESHEET_CSV_PATH="samplesheet.csv" -NEXTFLOW_PARAMS_PATH="nextflow.params.json" -CUSTOM_CONFIG_PATH="custom.config" - -## END GLOBALS ## - -## FUNCTIONS ## -print_help_text() { - cat <", // Required - "tumor_dna_sample_id": "", // Required if analysis_type is set to DNA or DNA/RNA - "normal_dna_sample_id": "", // Required if analysis_type is set to DNA or DNA/RNA - "tumor_dna_bam_uri": "", // Required if analysis_type is set to DNA - "normal_dna_bam_uri": "", // Required if analysis_type is set to DNA - "tumor_rna_sample_id": "", // Required if analysis_type is set to RNA or DNA/RNA - "tumor_rna_fastq_list_rows": [ ] // Required if analysis_type is set to RNA - "dna_oncoanalyser_analysis_uri": "" // Required if analysis_type is set to DNA/RNA - "rna_oncoanalyser_analysis_uri": "" // Required if analysis_type is set to DNA/RNA - }, - "engine_parameters": { - "portal_run_id": "", // Always required - "output_results_dir": "", // Always required - "output_scratch_dir": "", // Always required - "custom_config_str": "" // Optional - "resume_nextflow_uri": "" // Optional - } -} - -EOF -} - -cleanup(){ - : ' - Upload data to the output results dir and then exit with failure - ' - local output_results_dir="${1}" - upload_data "${output_results_dir}" - exit 1 -} - -echo_stderr(){ - : ' - Write input to stderr - ' - echo -e "${@}" 1>&2 -} - -### JQ FUNCTIONS ### -bash_array_to_jq_list(){ - : ' - Given a bash array, convert the bash array to a list of strings - ' - printf '%s\n' "${@}" | \ - jq \ - --raw-input --compact-output \ - --slurp \ - --raw-output \ - ' - split("\n")[:-1] - ' -} - -jq_to_csv(){ - : ' - Credit to - https://stackoverflow.com/a/32965227/6946787 - AND - https://unix.stackexchange.com/a/507625 - ' - jq --raw-output \ - ' - (map(keys) | add | unique) as $cols | - map( - . as $row | $cols | map($row[.]) - ) as $rows | - $cols, $rows[] | - @tsv | - gsub("\t"; ",") - ' < /dev/stdin -} - -get_mode(){ - : ' - Get the mode from the manifest json - Note that the "any(" logic requires jq 1.7 or higher - ' - jq --raw-output \ - --exit-status \ - --argjson valid_modes_array "$(bash_array_to_jq_list "${VALID_MODES[@]}")" \ - ' - .inputs.mode as $mode | - if any($valid_modes_array[] == $mode) then - $mode - else - null - end - ' <<< "${1}" -} - -get_analysis_type(){ - : ' - Get the analysis type from the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson valid_analysis_types_array "$(bash_array_to_jq_list "${VALID_ANALYSIS_TYPES[@]}")" \ - ' - .inputs.analysis_type as $analysis_type | - if any($valid_analysis_types_array[] == $analysis_type) then - $analysis_type - else - null - end - ' <<< "${1}" -} - -check_required_input_args(){ - : ' - Check that each of the required inputs args are present in the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson required_input_args "$(bash_array_to_jq_list "${REQUIRED_INPUTS_ARGS[@]}")" \ - ' - .inputs as $inputs | - all($required_input_args[]; in($inputs)) - ' <<< "${1}" 1>/dev/null -} - -check_required_engine_parameters_args(){ - : ' - Check that each of the required engine_parameters args are present in the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson required_engine_parameters "$(bash_array_to_jq_list "${REQUIRED_ENGINE_PARAMETER_ARGS[@]}")" \ - ' - .engine_parameters as $engine_parameters | - all($required_engine_parameters[]; in($engine_parameters)) - ' <<< "${1}" 1>/dev/null -} - -check_required_inputs_args_wgts_dna(){ - : ' - Check that each of the required inputs args are present in the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson required_input_args "$(bash_array_to_jq_list "${REQUIRED_INPUTS_ARGS_WGTS_DNA[@]}")" \ - ' - .inputs as $inputs | - all($required_input_args[]; in($inputs)) - ' <<< "${1}" 1>/dev/null -} - -check_required_inputs_args_wgts_rna(){ - : ' - Check that each of the required inputs args are present in the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson required_input_args "$(bash_array_to_jq_list "${REQUIRED_INPUTS_ARGS_WGTS_RNA[@]}")" \ - ' - .inputs as $inputs | - all($required_input_args[]; in($inputs)) - ' <<< "${1}" 1>/dev/null -} - -check_required_inputs_args_wgts_dna_rna(){ - : ' - Check that each of the required inputs args are present in the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson required_input_args "$(bash_array_to_jq_list "${REQUIRED_INPUTS_ARGS_WGTS_DNA_RNA[@]}")" \ - ' - .inputs as $inputs | - all($required_input_args[]; in($inputs)) - ' <<< "${1}" 1>/dev/null -} - -get_subject_id(){ - : ' - Get the subject id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.subject_id' <<< "${1}" -} - -get_tumor_dna_sample_id(){ - : ' - Get the tumor dna sample id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.tumor_dna_sample_id' <<< "${1}" -} - -get_normal_dna_sample_id(){ - : ' - Get the normal dna sample id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.normal_dna_sample_id' <<< "${1}" -} - -get_tumor_dna_bam_uri(){ - : ' - Get the tumor dna bam uri from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.tumor_dna_bam_uri' <<< "${1}" -} - -get_normal_dna_bam_uri(){ - : ' - Get the normal dna bam uri from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.normal_dna_bam_uri' <<< "${1}" -} - -get_tumor_rna_sample_id(){ - : ' - Get the tumor rna sample id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.tumor_rna_sample_id' <<< "${1}" -} - -get_tumor_rna_fastq_list_rows(){ - : ' - Get the tumor rna fastq uri list from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.tumor_rna_fastq_list_rows' <<< "${1}" -} - -get_dna_oncoanalyser_analysis_uri(){ - : ' - Get the dna oncoanalyser analysis uri from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.dna_oncoanalyser_analysis_uri' <<< "${1}" -} - -get_rna_oncoanalyser_analysis_uri(){ - : ' - Get the rna oncoanalyser analysis uri from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.rna_oncoanalyser_analysis_uri' <<< "${1}" -} - -get_portal_run_id(){ - : ' - Get the portal run id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.engine_parameters.portal_run_id' <<< "${1}" -} - -get_output_results_dir(){ - : ' - Get the output results dir from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.engine_parameters.output_results_dir' <<< "${1}" -} - -get_output_scratch_dir(){ - : ' - Get the output scratch dir from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.engine_parameters.output_scratch_dir' <<< "${1}" -} - -get_custom_config(){ - : ' - Get the custom config from the manifest json - ' - jq --raw-output \ - '.engine_parameters.custom_config_str' <<< "${1}" -} - -get_resume_nextflow_uri(){ - : ' - Get the custom config from the manifest json - ' - jq --raw-output \ - '.engine_parameters.resume_nextflow_uri' <<< "${1}" -} - -generate_wgts_dna_samplesheet(){ - : ' - Given the manifest json, generate the samplesheet for wgts mode / dna analysis type - - We return the following columns - - group_id,subject_id,sample_id,sample_type,sequence_type,filetype,filepath - ' - local manifest_json="${1}" - - jq --raw-output \ - ' - [ - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "bam", - "filepath": .inputs.tumor_dna_bam_uri - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.normal_dna_sample_id, - "sample_type": "normal", - "sequence_type": "dna", - "filetype": "bam", - "filepath": .inputs.normal_dna_bam_uri - } - ] - ' <<< "${manifest_json}" | \ - jq_to_csv > "${SAMPLESHEET_CSV_PATH}" -} - -generate_wgts_rna_to_samplesheet(){ - : ' - Given the manifest json, generate the samplesheet for wgts mode / rna analysis type - - We return the following columns - - group_id,subject_id,sample_id,sample_type,sequence_type,filetype,info,filepath - ' - local manifest_json="${1}" - - jq --raw-output \ - ' - .inputs as $inputs | - $inputs.tumor_rna_fastq_list_rows | - map( - { - "group_id": $inputs.tumor_rna_sample_id, - "subject_id": $inputs.subject_id, - "sample_id": $inputs.tumor_rna_sample_id, - "sample_type": "tumor", - "sequence_type": "rna", - "filetype": "fastq", - "info": "library_id:\(.rglb);lane:\(.lane)", - "filepath": "\(.read1FileUri);\(.read2FileUri)" - } - ) - ' <<< "${manifest_json}" | \ - jq_to_csv > "${SAMPLESHEET_CSV_PATH}" -} - -generate_wgts_dna_rna_to_samplesheet(){ - : ' - Given the manifest json, generate the samplesheet for wgts mode / dna/rna analysis type - We return the following columns - group_id,subject_id,sample_id,sample_type,sequence_type,filetype,filepath - Get dna bam from alignments/dna/ - Get rna_bam from outputs/alignments/rna/.md.bam - ' - local manifest_json="${1}" - - jq --raw-output \ - ' - [ - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "bam_markdups", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)alignments/dna/\(.inputs.tumor_dna_sample_id).markdups.bam" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.normal_dna_sample_id, - "sample_type": "normal", - "sequence_type": "dna", - "filetype": "bam_markdups", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)alignments/dna/\(.inputs.normal_dna_sample_id).markdups.bam" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_rna_sample_id, - "sample_type": "tumor", - "sequence_type": "rna", - "filetype": "bam", - "filepath": "\(.inputs.rna_oncoanalyser_analysis_uri)alignments/rna/\(.inputs.tumor_rna_sample_id).md.bam" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "bamtools", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)bamtools/\(.inputs.tumor_dna_sample_id).wgsmetrics" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.normal_dna_sample_id, - "sample_type": "normal", - "sequence_type": "dna", - "filetype": "bamtools", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)bamtools/\(.inputs.normal_dna_sample_id).wgsmetrics" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "flagstat", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)flagstats/\(.inputs.tumor_dna_sample_id).flagstat" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.normal_dna_sample_id, - "sample_type": "normal", - "sequence_type": "dna", - "filetype": "flagstat", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)flagstats/\(.inputs.normal_dna_sample_id).flagstat" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "sage_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)sage/somatic/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.normal_dna_sample_id, - "sample_type": "normal", - "sequence_type": "dna", - "filetype": "sage_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)sage/germline/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "linx_anno_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)linx/somatic_annotations/" - }, { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "linx_plot_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)linx/somatic_plots/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.normal_dna_sample_id, - "sample_type": "normal", - "sequence_type": "dna", - "filetype": "linx_anno_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)linx/germline_annotations/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "purple_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)purple/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "virusinterpreter_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)virusinterpreter/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "chord_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)chord/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_dna_sample_id, - "sample_type": "tumor", - "sequence_type": "dna", - "filetype": "sigs_dir", - "filepath": "\(.inputs.dna_oncoanalyser_analysis_uri)sigs/" - }, - { - "group_id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)_\(.inputs.tumor_rna_sample_id)", - "subject_id": .inputs.subject_id, - "sample_id": .inputs.tumor_rna_sample_id, - "sample_type": "tumor", - "sequence_type": "rna", - "filetype": "isofox_dir", - "filepath": "\(.inputs.rna_oncoanalyser_analysis_uri)isofox/" - } - ] - ' <<< "${manifest_json}" | \ - jq_to_csv > "${SAMPLESHEET_CSV_PATH}" -} - -generate_standard_args(){ - : ' - Generate the standard nextflow args - ' - local output_results_dir="${1}" - local ref_data_hmf_data_path - local ref_data_virusbreakenddb_path - - # Set the ref data paths - ref_data_hmf_data_path="s3://$(get_hmf_refdata_from_ssm)/" - ref_data_virusbreakenddb_path="s3://$(get_virusbreakend_db_from_ssm)/" - - # Generate the nextflow args - jq --null-input --raw-output \ - --arg ref_data_hmf_data_path "${ref_data_hmf_data_path%/}/" \ - --arg ref_data_virusbreakenddb_path "${ref_data_virusbreakenddb_path%/}/" \ - --arg output_results_dir "${output_results_dir%/}/" \ - --arg samplesheet_csv "${SAMPLESHEET_CSV_PATH}" \ - ' - { - "monochrome_logs": true, - "mode": "wgts", - "input": $samplesheet_csv, - "genome": "GRCh38_umccr", - "genome_version": "38", - "genome_type": "alt", - "force_genome": true, - "ref_data_hmf_data_path": $ref_data_hmf_data_path, - "ref_data_virusbreakenddb_path": $ref_data_virusbreakenddb_path, - "outdir": $output_results_dir - } - ' -} - -generate_wgts_dna_nextflow_params(){ - : ' - Generate the nextflow args specific to the mode / analysis combination - For wgts dna analysis, simply extend the nextflow args with the mode set to wgts - ' - local output_results_dir="${1}" - - jq --null-input --raw-output \ - --argjson stdargs "$(generate_standard_args "${output_results_dir%/}/")" \ - ' - $stdargs - ' \ - > "${NEXTFLOW_PARAMS_PATH}" -} - -generate_wgts_rna_nextflow_params(){ - : ' - For wgts dna analysis, generate the nextflow args specific to the mode / analysis combination - ' - local output_results_dir="${1}" - - jq --null-input --raw-output \ - --argjson stdargs "$(generate_standard_args "${output_results_dir%/}/")" \ - ' - $stdargs - ' \ - > "${NEXTFLOW_PARAMS_PATH}" -} - -generate_wgts_dna_rna_nextflow_params(){ - : ' - For wgts dna + rna analysis, generate the nextflow args specific to the mode / analysis combination - ' - local output_results_dir="${1}" - - jq --null-input --raw-output \ - --argjson stdargs "$(generate_standard_args "${output_results_dir%/}/")" \ - ' - $stdargs + - { - "mode": "wgts", - "processes_manual": true, - "processes_include": "lilac,cuppa,orange", - } - ' \ - > "${NEXTFLOW_PARAMS_PATH}" -} - -create_nextflow_config() { - : ' - Given a portal run id, generate the nextflow config file - ' - local portal_run_id="${1}" - local s3_genomes_data_path - local batch_instance_role_arn - - s3_genomes_data_path="s3://$(get_genomes_path_from_ssm)" - batch_instance_role_arn="$(get_batch_instance_role_arn_from_ssm)" - - sed \ - --regexp-extended \ - --expression \ - " - s#__S3_GENOMES_DATA_PATH__#${s3_genomes_data_path%/}/#g; - s#__BATCH_INSTANCE_ROLE__#${batch_instance_role_arn}#g; - s#__PORTAL_RUN_ID__#${portal_run_id}#g; - " \ - "${TEMPLATE_CONFIG_PATH}" > "${NEXTFLOW_CONFIG_PATH}" -} - -### END JQ FUNCTIONS ### - -### AWS FUNCTIONS ### - -get_ssm_parameter_value() { - aws ssm get-parameter \ - --name "$1" \ - --output json | - jq --raw-output '.Parameter | .Value' -} - -get_hmf_refdata_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/refdata_hmf" -} - -get_virusbreakend_db_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/refdata_virusbreakend" -} - -get_genomes_path_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/refdata_genomes" -} - -get_batch_instance_role_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/batch_instance_task_role_arn" -} - -get_batch_instance_profile_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/batch_instance_task_profile_arn" -} - -# Final upload data function -upload_data() { - : ' - Upload the results to the output_results_dir - ' - local output_results_dir="${1}" - - aws s3 sync \ - --no-progress \ - --no-follow-symlinks \ - --exclude='software/*' \ - --exclude='assets/*' \ - --exclude='work/*' \ - ./ "${output_results_dir%/}/" -} - -### END AWS FUNCTIONS ### - -## END FUNCTIONS ## - -## GET / CHECK ARGS ## - -MANIFEST_JSON="" - -while [ $# -gt 0 ]; do - case "$1" in - --manifest-json) - MANIFEST_JSON="$2" - shift 1 - ;; - -h|--help) - print_help_text - exit 0 - esac - shift -done - -# Load manifest json -if ! MANIFEST_JSON="$( \ - jq --raw-output <<< "${MANIFEST_JSON}" \ -)"; then - print_help_text - echo_stderr "\nERROR: Could not load the manifest json" - exit 1 -fi - -# Check 'mode' is one of the valid options (VALID_MODES) -if ! mode="$(get_mode "${MANIFEST_JSON}")"; then - print_help_text - echo_stderr "\nERROR: inputs.mode must be one of 'wgts' or 'targeted'" - exit 1 -fi - -# Check 'analysis_type' is one of the valid options (VALID_ANALYSIS_TYPES) -if ! analysis_type="$(get_analysis_type "${MANIFEST_JSON}")"; then - print_help_text - echo_stderr "\nERROR: inputs.analysis_type must be one of 'DNA', 'RNA' or 'DNA/RNA'" - exit 1 -fi - -# Check required inputs args -if ! check_required_input_args "${MANIFEST_JSON}"; then - print_help_text - echo_stderr "\nERROR: Required inputs are missing" - exit 1 -fi - -# Check required engine_parameters args -if ! check_required_engine_parameters_args "${MANIFEST_JSON}"; then - print_help_text - echo_stderr "\nERROR: Required engine_parameters are missing" - exit 1 -fi - -# Check required inputs args for wgts dna -if [[ "${mode}" == "wgts" && "${analysis_type}" == "DNA" ]]; then - if ! check_required_inputs_args_wgts_dna "${MANIFEST_JSON}"; then - print_help_text - echo_stderr "\nERROR: Required inputs are missing for mode 'wgts' / DNA analysis type" - exit 1 - fi -fi - -# Check required inputs args for wgts rna -if [[ "${mode}" == "wgts" && "${analysis_type}" == "RNA" ]]; then - if ! check_required_inputs_args_wgts_rna "${MANIFEST_JSON}"; then - print_help_text - echo_stderr "\nERROR: Required inputs are missing for mode 'wgts' / RNA analysis type" - exit 1 - fi -fi - -# Check required inputs args for wgts rna -if [[ "${mode}" == "wgts" && "${analysis_type}" == "DNA/RNA" ]]; then - if ! check_required_inputs_args_wgts_dna_rna "${MANIFEST_JSON}"; then - print_help_text - echo_stderr "\nERROR: Required inputs are missing for mode 'wgts' / RNA analysis type" - exit 1 - fi -fi - -## END GET / CHECK ARGS ## - -## MISC SETUP ## - -# Get IMDSv2 session token to make metadata requests -IMDS_TOKEN="$( \ - curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token \ -)" - -## END MISC SETUP ## - - -## SET AWS REGION ## - -# Get the current aws region -# https://stackoverflow.com/questions/4249488/find-region-from-within-an-ec2-instance -AWS_REGION=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/placement/region) -export AWS_REGION - -## END SET AWS REGION ## - - -## LOCAL EXECUTOR WORKAROUND ## - -# This stack runs the main Nextflow pipeline process as a Batch job and therefore the pipeline process is executed -# within a Docker container. Individual pipeline tasks are generally submitted as Batch jobs but can also be run -# locally. Running a process locally is useful for very short jobs. In order to run a process locally, the pipeline must -# execute the task within a Docker container. I have configured the Docker container that executes the Nextflow pipeline -# process to use the host Docker service for local jobs. -# -# A consequence of this set up is that that all task run locally using Docker containers inherit the EC2 instance IAM -# profile, which can only be set at creation of the Batch compute environment during stack deployment. In this case the -# Batch compute environment uses the non-permissive Nextflow pipeline role. This means to run Nextflow processes locally -# that can r/w to S3 (e.g. when using Fusion, S3 output directory, etc) we must manually set the EC2 instance IAM role -# at runtime to a profile with the required permissions. Here I associate the instance with the OncoanalyserStack task -# role. There may be better approaches to achieve this. - -instance_id=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/instance-id) -association_id=$( - aws ec2 describe-iam-instance-profile-associations | \ - jq --raw-output \ - --arg instance_id "${instance_id}" \ - ' - .IamInstanceProfileAssociations | - map( - select(.InstanceId == $instance_id) - ) | - map( - .AssociationId - ) | - .[] - ' -) -aws ec2 replace-iam-instance-profile-association 1>/dev/null \ - --association-id "${association_id}" \ - --iam-instance-profile "Arn=$(get_batch_instance_profile_arn_from_ssm)" - -## END LOCAL EXECUTOR WORKAROUND ## - -## START SAMPLESHEET AND NEXTFLOW ARGS ## - -# Check required inputs args for wgts dna -if [[ "${mode}" == "wgts" && "${analysis_type}" == "DNA" ]]; then - generate_wgts_dna_samplesheet "${MANIFEST_JSON}" - generate_wgts_dna_nextflow_params "$(get_output_results_dir "${MANIFEST_JSON}")" -fi - -# Check required inputs args for wgts rna -if [[ "${mode}" == "wgts" && "${analysis_type}" == "RNA" ]]; then - generate_wgts_rna_to_samplesheet "${MANIFEST_JSON}" - generate_wgts_rna_nextflow_params "$(get_output_results_dir "${MANIFEST_JSON}")" -fi - -# Check required inputs args for wgts rna -if [[ "${mode}" == "wgts" && "${analysis_type}" == "DNA/RNA" ]]; then - generate_wgts_dna_rna_to_samplesheet "${MANIFEST_JSON}" - generate_wgts_dna_rna_nextflow_params "$(get_output_results_dir "${MANIFEST_JSON}")" -fi - -## END SAMPLESHEET AND NEXTFLOW ARGS ## - -## CREATE NEXTFLOW CONFIGS ## -create_nextflow_config "$(get_portal_run_id "${MANIFEST_JSON}")" - -config_args_array=( \ - "-config" "${NEXTFLOW_CONFIG_PATH}" \ -) - -nf_run_args_array=( - "-ansi-log" "false" \ - "-profile" "docker" \ - "-work-dir" "$(get_output_scratch_dir "${MANIFEST_JSON}")" \ -) - -custom_config="$(get_custom_config "${MANIFEST_JSON}")" -if [[ -n "${custom_config}" && ! "${custom_config}" == "null" ]]; then - base64 -d <<< "${custom_config}" | gunzip > "${CUSTOM_CONFIG_PATH}" - config_args_array+=( "-config" "${CUSTOM_CONFIG_PATH}" ) -fi - -## END CREATE NEXTFLOW CONFIG ## - - -## RESUME BLOCK ## - -resume_nextflow_uri="$(get_resume_nextflow_uri "${MANIFEST_JSON}")" -if [[ -n "${resume_nextflow_uri:-}" && ! "${resume_nextflow_uri}" == "null" ]]; then - aws s3 sync \ - --no-progress \ - "${resume_nextflow_uri}/" ./.nextflow/ - nf_run_args_array+=( "-resume" ) -fi - -## END RESUME BLOCK ## - -# DEBUG -aws sts get-caller-identity --output=json | jq -# DEBUG - -## RUN NEXTFLOW ## -output_results_dir="$(get_output_results_dir "${MANIFEST_JSON}")" -trap 'cleanup "${output_results_dir}"' EXIT - -nextflow \ - "${config_args_array[@]}" \ - run "${MAIN_NF_PATH}" \ - "${nf_run_args_array[@]}" \ - -params-file "${NEXTFLOW_PARAMS_PATH}" - -# Upload data cleanly -upload_data "${output_results_dir%/}/" - -# Then exit cleanly -trap - EXIT - -## END RUN NEXTFLOW ## diff --git a/application/pipeline-stacks/oncoanalyser/assets/run.sh b/application/pipeline-stacks/oncoanalyser/assets/run.sh deleted file mode 100755 index 39e0205..0000000 --- a/application/pipeline-stacks/oncoanalyser/assets/run.sh +++ /dev/null @@ -1,627 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -## GLOBALS ## - -ICA_BASE_URL="https://aps2.platform.illumina.com" -MAIN_NF_PATH="software/oncoanalyser/main.nf" -TEMPLATE_CONFIG_PATH="/root/pipeline/assets/nextflow_aws.template.config" -NEXTFLOW_CONFIG_PATH="aws.config" - -## END GLOBALS ## - -## USAGE / ARGS ## - -print_help_text() { - cat <&2 - exit 1 -fi - -required_args=' -portal_run_id -subject_id -output_results_dir -output_staging_dir -output_scratch_dir -' - -required_args_wgts=' -tumor_wgs_sample_id -tumor_wgs_library_id -tumor_wgs_bam -normal_wgs_sample_id -normal_wgs_library_id -normal_wgs_bam -tumor_wts_sample_id -tumor_wts_library_id -tumor_wts_bam -' - -if [[ ${mode} == 'wgs' ]]; then - required_args+=' - tumor_wgs_sample_id - tumor_wgs_library_id - tumor_wgs_bam - normal_wgs_sample_id - normal_wgs_library_id - normal_wgs_bam - ' -elif [[ ${mode} == 'wts' ]]; then - required_args+=' - tumor_wts_sample_id - tumor_wts_library_id - tumor_wts_bam - ' -elif [[ ${mode} == 'wgts' ]]; then - required_args+="${required_args_wgts}" -elif [[ ${mode} == 'wgts_existing_wgs' ]]; then - required_args+=" - ${required_args_wgts} - existing_wgs_dir - " -elif [[ ${mode} == 'wgts_existing_wts' ]]; then - required_args+=" - ${required_args_wgts} - existing_wts_dir - " -elif [[ ${mode} == 'wgts_existing_both' ]]; then - required_args+=" - ${required_args_wgts} - existing_wgs_dir - existing_wts_dir - " -else - print_help_text - echo "--mode got unexpected value: ${mode}" 1>&2 - exit 1 -fi - -missing_args=() -for argname in ${required_args}; do - if [[ -z "${!argname:-}" ]]; then - missing_args+=( "${argname}" ) - fi -done - -if [[ ${#missing_args[@]} -gt 0 ]]; then - print_help_text - - # Get missing arguments - missing_arg_str="$( \ - echo -n "--${missing_args[0]}"; - for arg in "${missing_args[@]:1}"; do - echo -n ", --${arg}"; - done \ - )" - - # More than one missing arg? - # Lets make sure our grammar is right - plurality="$( \ - if [[ "${#missing_args[@]}" -gt 1 ]]; then - echo are; - else echo is; - fi \ - )" - echo -e "\nERROR: ${missing_arg_str} ${plurality} required" 1>&2 - exit 1 -fi - -## END USAGE / ARGS ## - -## FUNCTIONS ## - -get_ssm_parameter_value() { - aws ssm get-parameter \ - --name "$1" \ - --output json | - jq --raw-output '.Parameter | .Value' -} - -get_hmf_refdata_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/refdata_hmf" -} - -get_virusbreakend_db_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/refdata_virusbreakend" -} - -get_genomes_path_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/refdata_genomes" -} - -get_batch_instance_role_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/batch_instance_task_role_arn" -} - -get_batch_instance_profile_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/oncoanalyser/batch_instance_task_profile_arn" -} - -get_ica_access_token_from_secrets_manager() { - aws secretsmanager get-secret-value \ - --secret-id IcaSecretsPortal \ - --output json | \ - jq --raw-output \ - ' - .SecretString - ' -} - -stage_gds_fp() { - local gds_fp="${1}" - local gds_dp="${gds_fp%/*}/" - - # Local vars - local dst_bucket - local dst_key_base - local dst_dp - local dst_fp - local gds_volume_name - local gds_path - local gds_folder_id - local creds - local src_fp - - - dst_dp="${output_staging_dir#s3://}" - dst_fp="${dst_dp}/${gds_fp##*/}" - - echo s3://${dst_fp} - - if [[ -z "${ICA_ACCESS_TOKEN:-}" ]]; then - ICA_ACCESS_TOKEN="$(get_ica_access_token_from_secrets_manager)" - export ICA_ACCESS_TOKEN - fi - - # Get gds folder id from data path - gds_volume_name="$( \ - python3 -c "from urllib.parse import urlparse; print(urlparse('${gds_dp}').netloc)" \ - )" - gds_path="$( \ - python3 -c "from urllib.parse import urlparse; print(urlparse('${gds_dp}').path)" \ - )" - gds_folder_id="$( \ - curl --fail --silent --location --show-error \ - --request "GET" \ - --header "Accept: application/json" \ - --header "Authorization: Bearer ${ICA_ACCESS_TOKEN}" \ - --url "${ICA_BASE_URL}/v1/folders?volume.name=${gds_volume_name}&path=${gds_path}" | \ - jq --raw-output \ - ' - .items | - map(.id) | - .[] - ' \ - )" - - # Get ICA credentials for folder - creds="$( \ - curl --fail --silent --location --show-error \ - --request "PATCH" \ - --header 'Accept: application/json' \ - --header "Authorization: Bearer ${ICA_ACCESS_TOKEN}" \ - --header "Content-Type: application/json-patch+json" \ - --url "${ICA_BASE_URL}/v1/folders/${gds_folder_id}?include=ObjectStoreAccess" \ - --data '{}' | \ - jq --raw-output \ - '.objectStoreAccess.awsS3TemporaryUploadCredentials' \ - )" - - - mkdir -p ~/.config/rclone/ - - cat < ~/.config/rclone/rclone.conf -[ica] -type = s3 -provider = AWS -access_key_id = $(jq --raw-output '.access_Key_Id' <<< "${creds}") -secret_access_key = $(jq --raw-output '.secret_Access_Key' <<< "${creds}") -session_token = $(jq --raw-output '.session_Token' <<< "${creds}") -region = ap-southeast-2 - -[aws] -type = s3 -provider = AWS -env_auth = true -region = ap-southeast-2 -no_check_bucket = true -EOF - - src_fp="$( \ - jq --raw-output \ - --arg gds_fp "${gds_fp##*/}" \ - '"\(.bucketName)/\(.keyPrefix)\($gds_fp)"' \ - <<< "${creds}" \ - )" - - echo "staging ${gds_fp}.bai to s3://${dst_fp}.bai" 1>&2 - rclone copy --s3-upload-concurrency 8 \ - "ica:${src_fp}.bai" "aws:${dst_dp}/" - - echo "staging ${gds_fp} to s3://${dst_fp}" 1>&2 - rclone copy --s3-upload-concurrency 8 \ - "ica:${src_fp}" "aws:${dst_dp}/" -} - -samplesheet_wgs_entries() { - bam_type="${1}" - if ! [[ "${bam_type}" =~ ^(bam|bam_markdups)$ ]]; then - echo "got bad bam type WGS samplesheet entries" 1>&2 - exit 1 - fi - - echo "${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,${bam_type},${input_fps['tumor_wgs_bam']}" - echo "${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,${bam_type},${input_fps['normal_wgs_bam']}" -} - -samplesheet_wts_entries() { - echo "${subject_id}_${1},${subject_id},${tumor_wts_sample_id},tumor,rna,bam,${input_fps['tumor_wts_bam']}" -} - -# Final upload data function -upload_data() { - aws s3 sync \ - --no-progress \ - --no-follow-symlinks \ - --exclude='software/*' \ - --exclude='assets/*' \ - --exclude='work/*' \ - ./ "${output_results_dir}/" -} - -## END FUNCTIONS ## - -## MISC SETUP ## - -# Get IMDSv2 session token to make metadata requests -IMDS_TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token) - -## END MISC SETUP ## - -## SET AWS REGION ## - -# Get the current aws region -# https://stackoverflow.com/questions/4249488/find-region-from-within-an-ec2-instance -export AWS_REGION=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/placement/region) - -## END SET AWS REGION ## - -## LOCAL EXECUTOR WORKAROUND ## - -# This stack runs the main Nextflow pipeline process as a Batch job and therefore the pipeline process is executed -# within a Docker container. Individual pipeline tasks are generally submitted as Batch jobs but can also be run -# locally. Running a process locally is useful for very short jobs. In order to run a process locally, the pipeline must -# execute the task within a Docker container. I have configured the Docker container that executes the Nextflow pipeline -# process to use the host Docker service for local jobs. -# -# A consequence of this set up is that that all task run locally using Docker containers inherit the EC2 instance IAM -# profile, which can only be set at creation of the Batch compute environment during stack deployment. In this case the -# Batch compute environment uses the non-permissive Nextflow pipeline role. This means to run Nextflow processes locally -# that can r/w to S3 (e.g. when using Fusion, S3 output directory, etc) we must manually set the EC2 instance IAM role -# at runtime to a profile with the required permissions. Here I associate the instance with the OncoanalyserStack task -# role. There may be better approaches to achieve this. - -instance_id=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/instance-id) -association_id=$( - aws ec2 describe-iam-instance-profile-associations | \ - jq --raw-output \ - --arg instance_id "${instance_id}" \ - ' - .IamInstanceProfileAssociations | - map( - select(.InstanceId == $instance_id) - ) | - map( - .AssociationId - ) | - .[] - ' -) -aws ec2 replace-iam-instance-profile-association 1>/dev/null \ - --association-id "${association_id}" \ - --iam-instance-profile "Arn=$(get_batch_instance_profile_arn_from_ssm)" - -## END LOCAL EXECUTOR WORKAROUND ## - -## RESUME BLOCK ## - -if [[ -n "${resume_nextflow_dir:-}" ]]; then - aws s3 sync \ - --no-progress \ - "${resume_nextflow_dir}/" ./.nextflow/ -fi - -## END RESUME BLOCK ## - -## SAMPLESHEET PREP ## - -input_file_args=' -tumor_wgs_bam -normal_wgs_bam -tumor_wts_bam -' - -declare -A input_fps -for fp_name in ${input_file_args}; do - fp=${!fp_name:-} - if [[ -z ${fp} ]]; then - continue - fi - - if [[ ${fp} =~ ^gds://.* ]]; then - input_fps[${fp_name}]=$(stage_gds_fp "${fp}") - else - input_fps[${fp_name}]=${fp} - fi -done - - -cat < samplesheet.csv -group_id,subject_id,sample_id,sample_type,sequence_type,filetype,filepath -EOF - -if [[ ${mode} == 'wgs' ]]; then - - cat <> samplesheet.csv -$(samplesheet_wgs_entries bam) -EOF - -elif [[ ${mode} == 'wts' ]]; then - - cat <> samplesheet.csv -$(samplesheet_wts_entries "${tumor_wts_sample_id}") -EOF - -elif [[ ${mode} == 'wgts' ]]; then - - cat <> samplesheet.csv -$(samplesheet_wgs_entries bam) -$(samplesheet_wts_entries "${tumor_wgs_sample_id}") -EOF - -elif [[ ${mode} == 'wgts_existing_wts' ]]; then - - cat <> samplesheet.csv -$(samplesheet_wgs_entries bam) -$(samplesheet_wts_entries "${tumor_wgs_sample_id}") -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wts_sample_id},tumor,rna,isofox_dir,${existing_wts_dir}/isofox/ -EOF - -elif [[ ${mode} == 'wgts_existing_wgs' ]]; then - - cat <> samplesheet.csv -$(samplesheet_wgs_entries bam_markdups) -$(samplesheet_wts_entries "${tumor_wgs_sample_id}") -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,bamtools,${existing_wgs_dir}/bamtools/${tumor_wgs_sample_id}.wgsmetrics -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,bamtools,${existing_wgs_dir}/bamtools/${normal_wgs_sample_id}.wgsmetrics -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,flagstat,${existing_wgs_dir}/flagstats/${tumor_wgs_sample_id}.flagstat -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,flagstat,${existing_wgs_dir}/flagstats/${normal_wgs_sample_id}.flagstat -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,sage_dir,${existing_wgs_dir}/sage/somatic/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,sage_dir,${existing_wgs_dir}/sage/germline/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,linx_anno_dir,${existing_wgs_dir}/linx/somatic_annotations/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,linx_plot_dir,${existing_wgs_dir}/linx/somatic_plots/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,linx_anno_dir,${existing_wgs_dir}/linx/germline_annotations/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor_normal,dna,purple_dir,${existing_wgs_dir}/purple/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,virusinterpreter_dir,${existing_wgs_dir}/virusinterpreter/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,chord_dir,${existing_wgs_dir}/chord/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,sigs_dir,${existing_wgs_dir}/sigs/ -EOF - -elif [[ ${mode} == 'wgts_existing_both' ]]; then - - cat <> samplesheet.csv -$(samplesheet_wgs_entries bam_markdups) -$(samplesheet_wts_entries "${tumor_wgs_sample_id}") -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,bamtools,${existing_wgs_dir}/bamtools/${tumor_wgs_sample_id}.wgsmetrics -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,bamtools,${existing_wgs_dir}/bamtools/${normal_wgs_sample_id}.wgsmetrics -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,flagstat,${existing_wgs_dir}/flagstats/${tumor_wgs_sample_id}.flagstat -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,flagstat,${existing_wgs_dir}/flagstats/${normal_wgs_sample_id}.flagstat -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,sage_dir,${existing_wgs_dir}/sage/somatic/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,sage_dir,${existing_wgs_dir}/sage/germline/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,linx_anno_dir,${existing_wgs_dir}/linx/somatic_annotations/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,linx_plot_dir,${existing_wgs_dir}/linx/somatic_plots/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${normal_wgs_sample_id},normal,dna,linx_anno_dir,${existing_wgs_dir}/linx/germline_annotations/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor_normal,dna,purple_dir,${existing_wgs_dir}/purple/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,virusinterpreter_dir,${existing_wgs_dir}/virusinterpreter/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,chord_dir,${existing_wgs_dir}/chord/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wgs_sample_id},tumor,dna,sigs_dir,${existing_wgs_dir}/sigs/ -${subject_id}_${tumor_wgs_sample_id},${subject_id},${tumor_wts_sample_id},tumor,rna,isofox_dir,${existing_wts_dir}/isofox/ -EOF - -fi - -## END SAMPLESHEET PREP ## - -## NEXTFLOW ARGS ## - -# NOTE(SW): using new conditional block to separate functionality -nextflow_args='' -if [[ "${mode}" =~ ^w(g|t|gt)s$ ]]; then - nextflow_args='--mode wgts' -elif [[ ${mode} == 'wgts_existing_wts' ]]; then - nextflow_args='--mode wgts --processes_exclude isofox' -elif [[ ${mode} == 'wgts_existing_wgs' ]]; then - nextflow_args='--mode wgts --processes_manual --processes_include isofox,lilac,cuppa,orange' -elif [[ ${mode} == 'wgts_existing_both' ]]; then - nextflow_args='--mode wgts --processes_manual --processes_include lilac,cuppa,orange' -fi - -if [[ -n "${resume_nextflow_dir:-}" ]]; then - nextflow_args+=' -resume' -fi - -## END NEXFLOW ARGS ## - -## CREATE NEXTFLOW CONFIGS ## -sed \ - --regexp-extended \ - --expression \ - " - s#__S3_GENOMES_DATA_PATH__#s3://$(get_genomes_path_from_ssm)#g; - s#__BATCH_INSTANCE_ROLE__#$(get_batch_instance_role_arn_from_ssm)#g; - s#__PORTAL_RUN_ID__#${portal_run_id}#g; - " \ - "${TEMPLATE_CONFIG_PATH}" > "${NEXTFLOW_CONFIG_PATH}" - -if [[ -n "${custom_config:-}" ]]; then - base64 -d <<< "${custom_config}" | gzip -cd > custom.config - nextflow_args+=' -config custom.config' -fi - - -## END CREATE NEXTFLOW CONFIG ## -trap upload_data EXIT - -nextflow \ - -config "${NEXTFLOW_CONFIG_PATH}" \ - run "${MAIN_NF_PATH}" \ - -ansi-log "false" \ - --monochrome_logs \ - -profile "docker" \ - -work-dir "${output_scratch_dir}/" \ - ${nextflow_args} \ - --input "samplesheet.csv" \ - --genome "GRCh38_umccr" \ - --genome_version "38" \ - --genome_type "alt" \ - --force_genome \ - --ref_data_hmf_data_path "s3://$(get_hmf_refdata_from_ssm)/" \ - --ref_data_virusbreakenddb_path "s3://$(get_virusbreakend_db_from_ssm)/" \ - --outdir "${output_results_dir}/" - -# Upload data cleanly -upload_data - -# Then exit cleanly -trap - EXIT diff --git a/application/pipeline-stacks/oncoanalyser/lambda_functions/batch_job_submission/lambda_code.py b/application/pipeline-stacks/oncoanalyser/lambda_functions/batch_job_submission/lambda_code.py deleted file mode 100644 index ab2c19b..0000000 --- a/application/pipeline-stacks/oncoanalyser/lambda_functions/batch_job_submission/lambda_code.py +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env python3 -import json -import logging - - -import boto3 - - -LOGGER = logging.getLogger() -LOGGER.setLevel(logging.INFO) - - -CLIENT_BATCH = boto3.client('batch') -CLIENT_SSM = boto3.client('ssm') - - -def main(event, context): - """Lambda entry point. - - Event dict payload example: - { - "mode": "wgts_existing_both", - "portal_run_id": "20230530abcdefgh", - "subject_id": "SBJ00001", - "tumor_wgs_sample_id": "PRJ230001", - "tumor_wgs_library_id": "L2300001", - "tumor_wgs_bam": "gds://production/analysis_data/SBJ00001/wgs_tumor_normal/20230515zyxwvuts/L2300001_L2300003/PRJ230001_tumor.bam", - "tumor_wts_sample_id": "PRJ230002", - "tumor_wts_library_id": "L2300002", - "tumor_wts_bam": "s3://org.umccr.data.oncoanalyser/analysis_data/SBJ00001/star-align-nf/20230515qwertyui/L2300002/PRJ230002/PRJ230002.md.bam", - "normal_wgs_sample_id": "PRJ230003", - "normal_wgs_library_id": "L2300003", - "normal_wgs_bam": "gds://production/analysis_data/SBJ00001/wgs_tumor_normal/20230515zyxwvuts/L2300001_L2300002_dragen_somatic/PRJ230003_normal.bam", - "existing_wgs_dir": "s3://org.umccr.data.oncoanalyser/analysis_data/SBJ00001/oncoanalyser/20230515asdfghjk/wgs/L2300001__L2300003/", - "existing_wts_dir": "s3://org.umccr.data.oncoanalyser/analysis_data/SBJ00001/oncoanalyser/20230515zzxcvbnm/wts/L2300002/", - } - - :params dict event: Event payload - :params LambdaContext context: Lambda context - :returns: Status code and message - :rtype: dict - """ - - LOGGER.info(f'Received event: {json.dumps(event)}') - - validate_response = validate_event_data(event) - if validate_response['returncode'] != 0: - return validate_response['message'] - - job_data = get_job_data(event) - - output_directory = get_output_results_dir( - event['subject_id'], - get_library_id_string(event), - event['portal_run_id'], - event['mode'], - ) - - LOGGER.info(f'Compiled job data: {job_data}') - - response_job = CLIENT_BATCH.submit_job( - jobName=job_data['name'], - jobQueue=job_data['queue_name'], - jobDefinition=job_data['definition_arn'], - containerOverrides={ - 'command': job_data['command'], - 'resourceRequirements': [ - {'type': 'MEMORY', 'value': '15000'}, - {'type': 'VCPU', 'value': '2'}, - ], - }, - parameters={ - 'portal_run_id': event['portal_run_id'], - 'workflow': f'oncoanalyser_{event["mode"]}', - 'version': get_ssm_parameter_value('/nextflow_stack/oncoanalyser/pipeline_version_tag'), - 'output': json.dumps({'output_directory': output_directory}), - }, - tags={ - 'Stack': 'NextflowStack', - 'SubStack': 'OncoanalyserStack', - 'RunId': event['portal_run_id'], - }, - propagateTags=True - ) - - LOGGER.info(f'Received job submission response: {response_job}') - - return {'statusCode': 200, 'body': json.dumps(f'Submitted job with ID {response_job["jobId"]}')} - - -def get_job_data(event): - - library_id_str = get_library_id_string(event) - - job_name = f'oncoanalyser__{event["mode"]}__{event["subject_id"]}__{library_id_str}__{event["portal_run_id"]}' - job_definition_arn = get_ssm_parameter_value('/nextflow_stack/oncoanalyser/batch_job_definition_arn') - job_queue_name = 'nextflow-pipeline' - - command = get_job_command(event) - - return { - 'name': job_name, - 'definition_arn': job_definition_arn, - 'queue_name': job_queue_name, - 'command': command, - } - - -def get_ssm_parameter_value(name): - - response = CLIENT_SSM.get_parameter(Name=name) - return response['Parameter']['Value'] - - -def get_library_id_string(event): - - library_id_names = ['tumor_wgs_library_id', 'normal_wgs_library_id', 'tumor_wts_library_id'] - library_ids = [event.get(lname) for lname in library_id_names] - return '__'.join(lid for lid in library_ids if lid) - - -def get_output_results_dir(subject_id, library_id_str, portal_run_id, mode): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/oncoanalyser/nf_bucket_name') - return f's3://{bucket_name}/analysis_data/{subject_id}/oncoanalyser/{portal_run_id}/{mode}/{library_id_str}' - - -def get_output_scratch_dir(subject_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/oncoanalyser/nf_bucket_name') - return f's3://{bucket_name}/temp_data/{subject_id}/oncoanalyser/{portal_run_id}/scratch' - - -def get_output_staging_dir(subject_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/oncoanalyser/nf_bucket_name') - return f's3://{bucket_name}/temp_data/{subject_id}/oncoanalyser/{portal_run_id}/staging' - - -def get_job_command(event): - - output_results_dir = get_output_results_dir( - event['subject_id'], - get_library_id_string(event), - event['portal_run_id'], - event['mode'], - ) - output_scratch_dir = get_output_scratch_dir(event['subject_id'], event['portal_run_id']) - output_staging_dir = get_output_staging_dir(event['subject_id'], event['portal_run_id']) - - command_components = [ - './assets/run.sh', - f'--portal_run_id {event["portal_run_id"]}', - f'--mode {event["mode"]}', - f'--subject_id {event["subject_id"]}', - f'--output_results_dir {output_results_dir}', - f'--output_staging_dir {output_staging_dir}', - f'--output_scratch_dir {output_scratch_dir}', - ] - - command_components_wgs = [ - f'--tumor_wgs_sample_id {event.get("tumor_wgs_sample_id")}', - f'--tumor_wgs_library_id {event.get("tumor_wgs_library_id")}', - f'--tumor_wgs_bam {event.get("tumor_wgs_bam")}', - f'--normal_wgs_sample_id {event.get("normal_wgs_sample_id")}', - f'--normal_wgs_library_id {event.get("normal_wgs_library_id")}', - f'--normal_wgs_bam {event.get("normal_wgs_bam")}', - ] - - command_components_wts = [ - f'--tumor_wts_sample_id {event.get("tumor_wts_sample_id")}', - f'--tumor_wts_library_id {event.get("tumor_wts_library_id")}', - f'--tumor_wts_bam {event.get("tumor_wts_bam")}', - ] - - command_components_wgts = [ - *command_components_wgs, - *command_components_wts, - ] - - if event["mode"] == 'wgs': - command_components.extend(command_components_wgs) - elif event["mode"] == 'wts': - command_components.extend(command_components_wts) - elif event["mode"] == 'wgts': - command_components.extend(command_components_wgts) - elif event["mode"] == 'wgts_existing_wgs': - command_components.extend(command_components_wgts) - command_components.append(f'--existing_wgs_dir {get_wgs_existing_dir(event)}') - elif event["mode"] == 'wgts_existing_wts': - command_components.extend(command_components_wgts) - command_components.append(f'--existing_wts_dir {get_wts_existing_dir(event)}') - elif event["mode"] == 'wgts_existing_both': - command_components.extend(command_components_wgts) - command_components.append(f'--existing_wgs_dir {get_wgs_existing_dir(event)}') - command_components.append(f'--existing_wts_dir {get_wts_existing_dir(event)}') - else: - assert False - - return ['bash', '-o', 'pipefail', '-c', ' '.join(command_components)] - - -def get_wgs_existing_dir(event): - return event['existing_wgs_dir'].rstrip('/') + f'/{event["subject_id"]}_{event["tumor_wgs_sample_id"]}/' - - -def get_wts_existing_dir(event): - return event['existing_wts_dir'].rstrip('/') + f'/{event["subject_id"]}_{event["tumor_wts_sample_id"]}/' - - -def validate_event_data(event): - - modes_allowed = ( - 'wgs', - 'wts', - 'wgts', - 'wgts_existing_wgs', - 'wgts_existing_wts', - 'wgts_existing_both', - ) - - if not (mode := event.get('mode')): - return get_error_response('Missing required parameter: mode') - elif mode not in modes_allowed: - modes_allowed_str = ', '.join(modes_allowed) - message = f'Received an unexpected mode: {mode}. Available modes are: {modes_allowed_str}' - return get_error_response(message) - - required_params = [ - 'mode', - 'portal_run_id', - 'subject_id', - ] - - required_params_wgs = ( - 'tumor_wgs_sample_id', - 'tumor_wgs_library_id', - 'tumor_wgs_bam', - 'normal_wgs_sample_id', - 'normal_wgs_library_id', - 'normal_wgs_bam', - ) - - required_params_wts = ( - 'tumor_wts_sample_id', - 'tumor_wts_library_id', - 'tumor_wts_bam', - ) - - required_params_wgts = ( - *required_params_wgs, - *required_params_wts, - ) - - if mode == 'wgs': - required_params.extend(required_params_wgs) - elif mode == 'wts': - required_params.extend(required_params_wts) - elif mode == 'wgts': - required_params.extend(required_params_wgts) - elif mode == 'wgts_existing_wgs': - required_params.extend(required_params_wgts) - required_params.append('existing_wgs_dir') - elif mode == 'wgts_existing_wts': - required_params.extend(required_params_wgts) - required_params.append('existing_wts_dir') - elif mode == 'wgts_existing_both': - required_params.extend(required_params_wgts) - required_params.append('existing_wgs_dir') - required_params.append('existing_wts_dir') - else: - assert False - - missing_params = set(required_params) - set(event) - if missing_params: - plurality = 'parameters' if len(missing_params) > 1 else 'parameter' - message = f'Missing required {plurality}: {", ".join(missing_params)}' - return get_error_response(message) - - extra_params = set(event) - set(required_params) - if extra_params: - plurality = 'parameters' if len(extra_params) > 1 else 'parameter' - message = f'Found unexpected {plurality}: {", ".join(extra_params)}' - return get_error_response(message) - - return {'returncode': 0, 'message': dict()} - - -def get_error_response(message): - - LOGGER.error(message) - message_response = {'statusCode': 400, 'body': json.dumps(message)} - return {'returncode': 1, 'message': message_response} diff --git a/application/pipeline-stacks/oncoanalyser/stack.ts b/application/pipeline-stacks/oncoanalyser/stack.ts deleted file mode 100644 index 45a6d2b..0000000 --- a/application/pipeline-stacks/oncoanalyser/stack.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Construct } from 'constructs'; - -import * as common from '../common'; - - -export class OncoanalyserStack extends common.PipelineStack { - constructor(scope: Construct, id: string, props: common.IPipelineStack) { - super(scope, id, props); - } -} diff --git a/application/pipeline-stacks/sash/Dockerfile b/application/pipeline-stacks/sash/Dockerfile deleted file mode 100644 index 4b80475..0000000 --- a/application/pipeline-stacks/sash/Dockerfile +++ /dev/null @@ -1,102 +0,0 @@ -FROM docker.io/continuumio/miniconda3:23.10.0-1 - -# Set package versions and other info -# Generic -ARG JQ_VERSION="1.6" -ARG NEXTFLOW_VERSION="23.10.1" -ARG OPENJDK_VERSION="17.0.10" -ARG PARALLEL_VERSION="20230322" -ARG RCLONE_VERSION="1.62.2" - -# Docker packages -ARG DEBIAN_PLATFORM_VERSION="debian.11~bullseye_amd64" -ARG CONTAINERD_IO_VERSION="1.6.18-1" -ARG DOCKER_BUILDX_VERSION="0.10.2-1" -ARG DOCKER_CE_CLI_VERSION="23.0.1-1" -ARG DOCKER_CE_VERSION="23.0.1-1" -ARG DOCKER_COMPOSE_VERSION="2.16.0-1" - -# Pipeline GH URL and branch/tag -ARG PIPELINE_GITHUB_REF // NOTE(SW): must be provided as build argument -ARG PIPELINE_GITHUB_REPO_URL="https://github.com/scwatts/sash.git" - -RUN \ - test -n "${PIPELINE_GITHUB_REF}" || (echo "PIPELINE_GITHUB_REF must be set" && false) - -# Configure Conda -RUN \ - conda install --yes \ - conda-libmamba-solver && \ - echo '\ -solver: libmamba\n\ -channels:\n\ - - conda-forge\n\ - - bioconda\n\ - - defaults\n\ -' > ~/.condarc - -# Install software with apt -RUN \ - apt update -y -q && \ - apt install -y -q \ - curl \ - jq="${JQ_VERSION}*" \ - unzip \ - wget && \ - apt clean -y -q - -# Install packages with Conda -RUN \ - conda install --yes \ - "nextflow ==${NEXTFLOW_VERSION}" \ - "openjdk ==${OPENJDK_VERSION}" \ - "parallel ==${PARALLEL_VERSION}" \ - "rclone ==${RCLONE_VERSION}" && \ - conda clean --all --force-pkgs-dirs --yes - -# Install AWS CLIv2 -RUN \ - wget --quiet 'https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip' \ - --output-document "awscli.zip" && \ - unzip -qq "awscli.zip" && \ - ./aws/install && \ - rm -rf aws/ "awscli.zip" - -# Install Docker; used to run additional containers via the host service -RUN \ - mkdir -p "docker_install_temp/" && \ - ( \ - cd "docker_install_temp/" && \ - parallel --jobs 0 " \ - wget \ - --quiet \ - 'https://download.docker.com/linux/debian/dists/bullseye/pool/stable/amd64/{}' \ - " ::: \ - "containerd.io_${CONTAINERD_IO_VERSION}_amd64.deb" \ - "docker-ce_${DOCKER_CE_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-ce-cli_${DOCKER_CE_CLI_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-buildx-plugin_${DOCKER_BUILDX_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-compose-plugin_${DOCKER_COMPOSE_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" && \ - apt install --yes --quiet $(pwd)/*.deb \ - ) && \ - rm --force --recursive "docker_install_temp/" && \ - apt clean --yes --quiet - -# Install pipeline software and config -RUN \ - mkdir -p "/root/pipeline/software/" && \ - mkdir -p "/root/pipeline/assets/" && \ - ( \ - cd "/root/pipeline/software/" && \ - git clone --branch "${PIPELINE_GITHUB_REF}" "${PIPELINE_GITHUB_REPO_URL}" \ - ) - -COPY assets/nextflow_aws.template.config /root/pipeline/assets/ -COPY assets/run.sh /root/pipeline/assets/ -COPY assets/run-v2.sh /root/pipeline/assets/ - -RUN \ - chmod +x "/root/pipeline/assets/run.sh" && \ - chmod +x "/root/pipeline/assets/run-v2.sh" - -WORKDIR /root/pipeline/ diff --git a/application/pipeline-stacks/sash/assets/nextflow_aws.template.config b/application/pipeline-stacks/sash/assets/nextflow_aws.template.config deleted file mode 100644 index f136c2a..0000000 --- a/application/pipeline-stacks/sash/assets/nextflow_aws.template.config +++ /dev/null @@ -1,137 +0,0 @@ -plugins { - id 'nf-amazon' -} - -aws { - batch { - jobRole = '__BATCH_INSTANCE_ROLE__' - cliPath = '/opt/awscliv2/bin/aws' - volumes = '/scratch' - } -} - -process { - executor = 'awsbatch' - scratch = '/scratch/' - - resourceLabels = { - return [ - 'Stack': 'NextflowStack', - 'SubStack': 'SashStack', - 'RunId': '__PORTAL_RUN_ID__', - 'JobName': task.process, - ] - } - - withName: 'BOLT_SMLV_SOMATIC_RESCUE' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: 'BOLT_SMLV_SOMATIC_ANNOTATE' { - queue = 'nextflow-task-ondemand-4cpu_32gb-ebs' - cpus = 4 - memory = 30.GB - } - - withName: 'BOLT_SMLV_SOMATIC_FILTER' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: '.*PAVE_SOMATIC' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: 'BOLT_SMLV_SOMATIC_REPORT' { - queue = 'nextflow-task-ondemand-4cpu_32gb-ebs' - cpus = 4 - memory = 30.GB - } - - withName: 'BOLT_SMLV_GERMLINE_PREPARE' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: 'BOLT_SMLV_GERMLINE_REPORT' { - queue = 'nextflow-task-ondemand-4cpu_32gb-ebs' - cpus = 4 - memory = 30.GB - } - - withName: '.*:GRIPSS_FILTERING:(?:GERMLINE|SOMATIC)' { - queue = 'nextflow-task-ondemand-4cpu_32gb-ebs' - cpus = 4 - memory = 30.GB - } - - withName: 'BOLT_SV_SOMATIC_ANNOTATE' { - queue = 'nextflow-task-ondemand-4cpu_32gb-ebs' - cpus = 4 - memory = 30.GB - } - - withName: 'BOLT_SV_SOMATIC_PRIORITISE' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: 'PURPLE' { - queue = 'nextflow-task-ondemand-4cpu_32gb-ebs' - cpus = 4 - memory = 30.GB - } - - withName: 'BOLT_OTHER_PURPLE_BAF_PLOT' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: 'BOLT_OTHER_CANCER_REPORT' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: 'BOLT_OTHER_MULTIQC_REPORT' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: '.*:LINX_ANNOTATION:(?:GERMLINE|SOMATIC)' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: '.*:LINX_PLOTTING:VISUALISER' { - errorStrategy = 'retry' - maxRetries = 1 - - queue = 'nextflow-task-ondemand-8cpu_64gb-ebs' - cpus = 8 - memory = 60.GB - } - - withName: '.*:LINX_PLOTTING:REPORT' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - - withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { - queue = 'nextflow-task-ondemand-2cpu_16gb-ebs' - cpus = 2 - memory = 14.GB - } - -} diff --git a/application/pipeline-stacks/sash/assets/run-v2.sh b/application/pipeline-stacks/sash/assets/run-v2.sh deleted file mode 100755 index a5bc679..0000000 --- a/application/pipeline-stacks/sash/assets/run-v2.sh +++ /dev/null @@ -1,539 +0,0 @@ -#!/usr/bin/env bash - -# Set up to fail -set -euo pipefail - -## GLOBALS ## -MAIN_NF_PATH="software/sash/main.nf" -TEMPLATE_CONFIG_PATH="/root/pipeline/assets/nextflow_aws.template.config" -NEXTFLOW_CONFIG_PATH="aws.config" - -# BASE REQUIREMENTS -REQUIRED_INPUTS_ARGS=( \ - "subject_id" \ - "tumor_dna_sample_id" \ - "normal_dna_sample_id" \ - "dragen_somatic_uri" \ - "dragen_germline_uri" \ - "oncoanalyser_dna_uri" \ -) - -REQUIRED_ENGINE_PARAMETER_ARGS=( \ - "portal_run_id" \ - "output_results_dir" \ - "output_scratch_dir" \ -) - -# INTERMEDIATE FILES -SAMPLESHEET_CSV_PATH="samplesheet.csv" -NEXTFLOW_PARAMS_PATH="nextflow.params.json" -CUSTOM_CONFIG_PATH="custom.config" - -## END GLOBALS ## - -## FUNCTIONS ## -print_help_text() { - cat <", // Required - "tumor_dna_sample_id": "", // Required if analysis_type is set to DNA or DNA/RNA - "normal_dna_sample_id": "", // Required if analysis_type is set to DNA or DNA/RNA - "dragen_somatic_uri": "" // Required if analysis_type is set to DNA/RNA - "dragen_germline_uri": "" // Required if analysis_type is set to DNA/RNA - "oncoanalyser_dna_uri": "" // Required if analysis_type is set to DNA/RNA - }, - "engine_parameters": { - "portal_run_id": "", // Always required - "output_results_dir": "", // Always required - "output_scratch_dir": "", // Always required - "custom_config_str": "" // Optional - "resume_nextflow_uri": "" // Optional - } -} - -EOF -} - -cleanup(){ - : ' - Upload data to the output results dir and then exit with failure - ' - local output_results_dir="${1}" - upload_data "${output_results_dir}" - exit 1 -} - -echo_stderr(){ - : ' - Write input to stderr - ' - echo -e "${@}" 1>&2 -} - -### JQ FUNCTIONS ### -bash_array_to_jq_list(){ - : ' - Given a bash array, convert the bash array to a list of strings - ' - printf '%s\n' "${@}" | \ - jq \ - --raw-input --compact-output \ - --slurp \ - --raw-output \ - ' - split("\n")[:-1] - ' -} - -jq_to_csv(){ - : ' - Credit to - https://stackoverflow.com/a/32965227/6946787 - AND - https://unix.stackexchange.com/a/507625 - ' - jq --raw-output \ - ' - (map(keys) | add | unique) as $cols | - map( - . as $row | $cols | map($row[.]) - ) as $rows | - $cols, $rows[] | - @tsv | - gsub("\t"; ",") - ' < /dev/stdin -} - -check_required_input_args(){ - : ' - Check that each of the required inputs args are present in the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson required_input_args "$(bash_array_to_jq_list "${REQUIRED_INPUTS_ARGS[@]}")" \ - ' - .inputs as $inputs | - all($required_input_args[]; in($inputs)) - ' <<< "${1}" 1>/dev/null -} - -check_required_engine_parameters_args(){ - : ' - Check that each of the required engine_parameters args are present in the manifest json - ' - jq --raw-output \ - --exit-status \ - --argjson required_engine_parameters "$(bash_array_to_jq_list "${REQUIRED_ENGINE_PARAMETER_ARGS[@]}")" \ - ' - .engine_parameters as $engine_parameters | - all($required_engine_parameters[]; in($engine_parameters)) - ' <<< "${1}" 1>/dev/null -} - -## Input functions -get_subject_id(){ - : ' - Get the subject id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.subject_id' <<< "${1}" -} - -get_tumor_dna_sample_id(){ - : ' - Get the tumor dna sample id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.tumor_dna_sample_id' <<< "${1}" -} - -get_normal_dna_sample_id(){ - : ' - Get the normal dna sample id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.normal_dna_sample_id' <<< "${1}" -} - -get_dragen_somatic_uri(){ - : ' - Get the dragen somatic uri from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.dragen_somatic_uri' <<< "${1}" -} - -get_dragen_germline_uri(){ - : ' - Get the dragen germline uri from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.dragen_germline_uri' <<< "${1}" -} - -get_oncoanalyser_dna_uri(){ - : ' - Get the oncoanalyser dna uri from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.inputs.oncoanalyser_dna_uri' <<< "${1}" -} - -## Engine parameter functions -get_portal_run_id(){ - : ' - Get the portal run id from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.engine_parameters.portal_run_id' <<< "${1}" -} - -get_output_results_dir(){ - : ' - Get the output results dir from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.engine_parameters.output_results_dir' <<< "${1}" -} - -get_output_scratch_dir(){ - : ' - Get the output scratch dir from the manifest json - ' - jq --raw-output \ - --exit-status \ - '.engine_parameters.output_scratch_dir' <<< "${1}" -} - -get_custom_config(){ - : ' - Get the custom config from the manifest json - ' - jq --raw-output \ - '.engine_parameters.custom_config_str' <<< "${1}" -} - -get_resume_nextflow_uri(){ - : ' - Get the custom config from the manifest json - ' - jq --raw-output \ - '.engine_parameters.resume_nextflow_uri' <<< "${1}" -} - -generate_samplesheet(){ - : ' - Given the manifest json, generate the samplesheet for wgts mode / dna analysis type - - We return the following columns - - id,subject_name,sample_name,filetype,filepath - ' - local manifest_json="${1}" - - jq --raw-output \ - ' - [ - { - "id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)", - "subject_name": .inputs.subject_id, - "sample_name": .inputs.tumor_dna_sample_id, - "filetype": "dragen_somatic_dir", - "filepath": .inputs.dragen_somatic_uri - }, - { - "id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)", - "subject_name": .inputs.subject_id, - "sample_name": .inputs.normal_dna_sample_id, - "filetype": "dragen_germline_dir", - "filepath": .inputs.dragen_germline_uri - }, - { - "id": "\(.inputs.tumor_dna_sample_id)_\(.inputs.normal_dna_sample_id)", - "subject_name": .inputs.subject_id, - "sample_name": .inputs.tumor_dna_sample_id, - "filetype": "oncoanalyser_dir", - "filepath": .inputs.oncoanalyser_dna_uri - } - ] - ' <<< "${manifest_json}" | \ - jq_to_csv > "${SAMPLESHEET_CSV_PATH}" -} - -generate_standard_args(){ - : ' - Generate the standard nextflow args - ' - local output_results_dir="${1}" - local ref_data_hmf_data_path - - # Set ref data path - ref_data_hmf_data_path="s3://$(get_refdata_basepath)/" - - jq --null-input --raw-output \ - --arg ref_data_hmf_data_path "${ref_data_hmf_data_path%/}/" \ - --arg output_results_dir "${output_results_dir%/}/" \ - --arg samplesheet_csv "${SAMPLESHEET_CSV_PATH}" \ - ' - { - "monochrome_logs": true, - "input": $samplesheet_csv, - "ref_data_path": $ref_data_hmf_data_path, - "outdir": $output_results_dir - } - ' -} - -generate_nextflow_params(){ - : ' - Generate the nextflow args specific to the mode / analysis combination - For sash analysis, simply extend the nextflow args - ' - local output_results_dir="${1}" - - jq --null-input --raw-output \ - --argjson stdargs "$(generate_standard_args "${output_results_dir%/}/")" \ - ' - $stdargs - ' \ - > "${NEXTFLOW_PARAMS_PATH}" -} - -create_nextflow_config() { - : ' - Given a portal run id, generate the nextflow config file - ' - local portal_run_id="${1}" - local batch_instance_role_arn - - batch_instance_role_arn="$(get_batch_instance_role_arn_from_ssm)" - - sed \ - --regexp-extended \ - --expression \ - " - s#__BATCH_INSTANCE_ROLE__#${batch_instance_role_arn}#g; - s#__PORTAL_RUN_ID__#${portal_run_id}#g; - " \ - "${TEMPLATE_CONFIG_PATH}" > "${NEXTFLOW_CONFIG_PATH}" -} - -### END JQ FUNCTIONS ### - -### AWS FUNCTIONS ### - -get_ssm_parameter_value() { - aws ssm get-parameter \ - --name "$1" \ - --output json | - jq --raw-output '.Parameter | .Value' -} - -get_refdata_basepath() { - get_ssm_parameter_value "/nextflow_stack/sash/refdata_basepath" -} - -get_batch_instance_role_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/sash/batch_instance_task_role_arn" -} - -get_batch_instance_profile_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/sash/batch_instance_task_profile_arn" -} - -# Final upload data function -upload_data() { - : ' - Upload the results to the output_results_dir - ' - local output_results_dir="${1}" - - aws s3 sync \ - --no-progress \ - --no-follow-symlinks \ - --exclude='software/*' \ - --exclude='assets/*' \ - --exclude='work/*' \ - ./ "${output_results_dir%/}/" -} - -### END AWS FUNCTIONS ### - -## END FUNCTIONS ## - -## GET / CHECK ARGS ## - -MANIFEST_JSON="" - -while [ $# -gt 0 ]; do - case "$1" in - --manifest-json) - MANIFEST_JSON="$2" - shift 1 - ;; - -h|--help) - print_help_text - exit 0 - esac - shift -done - -# Load manifest json -if ! MANIFEST_JSON="$( \ - jq --raw-output <<< "${MANIFEST_JSON}" \ -)"; then - print_help_text - echo_stderr "\nERROR: Could not load the manifest json" - exit 1 -fi - -# Check required inputs args -if ! check_required_input_args "${MANIFEST_JSON}"; then - print_help_text - echo_stderr "\nERROR: Required inputs are missing" - exit 1 -fi - -# Check required engine_parameters args -if ! check_required_engine_parameters_args "${MANIFEST_JSON}"; then - print_help_text - echo_stderr "\nERROR: Required engine_parameters are missing" - exit 1 -fi - -## END GET / CHECK ARGS ## - -## MISC SETUP ## - -# Get IMDSv2 session token to make metadata requests -IMDS_TOKEN="$( \ - curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token \ -)" - -## END MISC SETUP ## - - -## SET AWS REGION ## - -# Get the current aws region -# https://stackoverflow.com/questions/4249488/find-region-from-within-an-ec2-instance -AWS_REGION=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/placement/region) -export AWS_REGION - -## END SET AWS REGION ## - - -## LOCAL EXECUTOR WORKAROUND ## - -# This stack runs the main Nextflow pipeline process as a Batch job and therefore the pipeline process is executed -# within a Docker container. Individual pipeline tasks are generally submitted as Batch jobs but can also be run -# locally. Running a process locally is useful for very short jobs. In order to run a process locally, the pipeline must -# execute the task within a Docker container. I have configured the Docker container that executes the Nextflow pipeline -# process to use the host Docker service for local jobs. -# -# A consequence of this set up is that that all task run locally using Docker containers inherit the EC2 instance IAM -# profile, which can only be set at creation of the Batch compute environment during stack deployment. In this case the -# Batch compute environment uses the non-permissive Nextflow pipeline role. This means to run Nextflow processes locally -# that can r/w to S3 (e.g. when using Fusion, S3 output directory, etc) we must manually set the EC2 instance IAM role -# at runtime to a profile with the required permissions. Here I associate the instance with the OncoanalyserStack task -# role. There may be better approaches to achieve this. - -instance_id=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/instance-id) -association_id=$( - aws ec2 describe-iam-instance-profile-associations | \ - jq --raw-output \ - --arg instance_id "${instance_id}" \ - ' - .IamInstanceProfileAssociations | - map( - select(.InstanceId == $instance_id) - ) | - map( - .AssociationId - ) | - .[] - ' -) -aws ec2 replace-iam-instance-profile-association 1>/dev/null \ - --association-id "${association_id}" \ - --iam-instance-profile "Arn=$(get_batch_instance_profile_arn_from_ssm)" - -## END LOCAL EXECUTOR WORKAROUND ## - - -## START SAMPLESHEET AND NEXTFLOW ARGS ## - -generate_samplesheet "${MANIFEST_JSON}" -generate_nextflow_params "$(get_output_results_dir "${MANIFEST_JSON}")" - -## END SAMPLESHEET AND NEXTFLOW ARGS ## - -## CREATE NEXTFLOW CONFIGS ## -create_nextflow_config "$(get_portal_run_id "${MANIFEST_JSON}")" - -config_args_array=( \ - "-config" "${NEXTFLOW_CONFIG_PATH}" \ -) - -nf_run_args_array=( - "-ansi-log" "false" \ - "-profile" "docker" \ - "-work-dir" "$(get_output_scratch_dir "${MANIFEST_JSON}")" \ - "-params-file" "${NEXTFLOW_PARAMS_PATH}" -) - - -custom_config="$(get_custom_config "${MANIFEST_JSON}")" -if [[ -n "${custom_config}" && ! "${custom_config}" == "null" ]]; then - base64 -d <<< "${custom_config}" | gunzip > "${CUSTOM_CONFIG_PATH}" - config_args_array+=( "-config" "${CUSTOM_CONFIG_PATH}" ) -fi - -## END CREATE NEXTFLOW CONFIG ## - - -## RESUME BLOCK ## - -resume_nextflow_uri="$(get_resume_nextflow_uri "${MANIFEST_JSON}")" -if [[ -n "${resume_nextflow_uri:-}" && ! "${resume_nextflow_uri}" == "null" ]]; then - aws s3 sync \ - --no-progress \ - "${resume_nextflow_uri}/" ./.nextflow/ - nf_run_args_array+=( "-resume" ) -fi - -## END RESUME BLOCK ## - -## RUN NEXTFLOW ## -output_results_dir="$(get_output_results_dir "${MANIFEST_JSON}")" -trap 'cleanup "${output_results_dir}"' EXIT - -nextflow \ - "${config_args_array[@]}" \ - run "${MAIN_NF_PATH}" \ - "${nf_run_args_array[@]}" - -# Upload data cleanly -upload_data "${output_results_dir%/}/" - -# Then exit cleanly -trap - EXIT - -## END RUN NEXTFLOW ## diff --git a/application/pipeline-stacks/sash/assets/run.sh b/application/pipeline-stacks/sash/assets/run.sh deleted file mode 100755 index a9a8f18..0000000 --- a/application/pipeline-stacks/sash/assets/run.sh +++ /dev/null @@ -1,436 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -## GLOBALS ## - -ICA_BASE_URL="https://aps2.platform.illumina.com" -MAIN_NF_PATH="software/sash/main.nf" -TEMPLATE_CONFIG_PATH="/root/pipeline/assets/nextflow_aws.template.config" -NEXTFLOW_CONFIG_PATH="aws.config" - -## END GLOBALS ## - -## USAGE / ARGS ## - -print_help_text() { - cat <&2 - exit 1 -fi - -## END USAGE / ARGS ## - -## FUNCTIONS ## - -get_ssm_parameter_value() { - aws ssm get-parameter \ - --name "$1" \ - --output json | - jq --raw-output '.Parameter | .Value' -} - -get_refdata_basepath() { - get_ssm_parameter_value "/nextflow_stack/sash/refdata_basepath" -} - -get_batch_instance_role_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/sash/batch_instance_task_role_arn" -} - -get_batch_instance_profile_arn_from_ssm() { - get_ssm_parameter_value "/nextflow_stack/sash/batch_instance_task_profile_arn" -} - -get_ica_access_token_from_secrets_manager() { - aws secretsmanager get-secret-value \ - --secret-id IcaSecretsPortal \ - --output json | \ - jq --raw-output \ - ' - .SecretString - ' -} - -stage_gds_fp() { - - # NOTE(SW): this expects only DRAGEN directories - - local gds_dp="${1%/}/" - local gds_dn="$(sed 's#^.*/##' <<< ${gds_dp%/})/" - - # Local vars - local dst_bucket - local dst_key_base - local dst_dp - local dst_fp - local gds_volume_name - local gds_path - local gds_folder_id - local creds - local src_fp - - dst_dp_base="${output_staging_dir#s3://}" - dst_dp="${dst_dp_base}/${gds_dn%/}" - - echo s3://${dst_dp}/ - - if [[ -z "${ICA_ACCESS_TOKEN:-}" ]]; then - ICA_ACCESS_TOKEN="$(get_ica_access_token_from_secrets_manager)" - export ICA_ACCESS_TOKEN - fi - - # Get gds folder id from data path - gds_volume_name="$( \ - python3 -c "from urllib.parse import urlparse; print(urlparse('${gds_dp}').netloc)" \ - )" - gds_path="$( \ - python3 -c "from urllib.parse import urlparse; print(urlparse('${gds_dp}').path)" \ - )" - gds_folder_id="$( \ - curl --fail --silent --location --show-error \ - --request "GET" \ - --header "Accept: application/json" \ - --header "Authorization: Bearer ${ICA_ACCESS_TOKEN}" \ - --url "${ICA_BASE_URL}/v1/folders?volume.name=${gds_volume_name}&path=${gds_path}" | \ - jq --raw-output \ - ' - .items | - map(.id) | - .[] - ' \ - )" - - # Get ICA credentials for folder - creds="$( \ - curl --fail --silent --location --show-error \ - --request "PATCH" \ - --header 'Accept: application/json' \ - --header "Authorization: Bearer ${ICA_ACCESS_TOKEN}" \ - --header "Content-Type: application/json-patch+json" \ - --url "${ICA_BASE_URL}/v1/folders/${gds_folder_id}?include=ObjectStoreAccess" \ - --data '{}' | \ - jq --raw-output \ - '.objectStoreAccess.awsS3TemporaryUploadCredentials' \ - )" - - - mkdir -p ~/.config/rclone/ - - cat < ~/.config/rclone/rclone.conf -[ica] -type = s3 -provider = AWS -access_key_id = $(jq --raw-output '.access_Key_Id' <<< "${creds}") -secret_access_key = $(jq --raw-output '.secret_Access_Key' <<< "${creds}") -session_token = $(jq --raw-output '.session_Token' <<< "${creds}") -region = ap-southeast-2 - -[aws] -type = s3 -provider = AWS -env_auth = true -region = ap-southeast-2 -no_check_bucket = true -EOF - - src_dp="$( \ - jq --raw-output \ - '"\(.bucketName)/\(.keyPrefix)"' \ - <<< "${creds}" \ - )" - - echo "staging ${gds_dp} to s3://${dst_dp}/" 1>&2 - rclone copy \ - --s3-upload-concurrency 8 \ - --filter='+ /*.csv' \ - --filter='+ /*hard-filtered.vcf.gz' \ - --filter='+ /*hard-filtered.vcf.gz.tbi' \ - --filter='- *' \ - "ica:${src_dp}" "aws:${dst_dp}/" -} - -# Final upload data function -upload_data() { - aws s3 sync \ - --no-progress \ - --no-follow-symlinks \ - --exclude='software/*' \ - --exclude='assets/*' \ - --exclude='work/*' \ - ./ "${output_results_dir}/" -} - -## END FUNCTIONS ## - -## MISC SETUP ## - -# Get IMDSv2 session token to make metadata requests -IMDS_TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token) - -## END MISC SETUP ## - -## SET AWS REGION ## - -# Get the current aws region -# https://stackoverflow.com/questions/4249488/find-region-from-within-an-ec2-instance -export AWS_REGION=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/placement/region) - -## END SET AWS REGION ## - -## LOCAL EXECUTOR WORKAROUND ## - -# This stack runs the main Nextflow pipeline process as a Batch job and therefore the pipeline process is executed -# within a Docker container. Individual pipeline tasks are generally submitted as Batch jobs but can also be run -# locally. Running a process locally is useful for very short jobs. In order to run a process locally, the pipeline must -# execute the task within a Docker container. I have configured the Docker container that executes the Nextflow pipeline -# process to use the host Docker service for local jobs. -# -# A consequence of this set up is that that all task run locally using Docker containers inherit the EC2 instance IAM -# profile, which can only be set at creation of the Batch compute environment during stack deployment. In this case the -# Batch compute environment uses the non-permissive Nextflow pipeline role. This means to run Nextflow processes locally -# that can r/w to S3 (e.g. when using Fusion, S3 output directory, etc) we must manually set the EC2 instance IAM role -# at runtime to a profile with the required permissions. Here I associate the instance with the OncoanalyserStack task -# role. There may be better approaches to achieve this. - -instance_id=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/instance-id) -association_id=$( - aws ec2 describe-iam-instance-profile-associations | \ - jq --raw-output \ - --arg instance_id "${instance_id}" \ - ' - .IamInstanceProfileAssociations | - map( - select(.InstanceId == $instance_id) - ) | - map( - .AssociationId - ) | - .[] - ' -) -aws ec2 replace-iam-instance-profile-association 1>/dev/null \ - --association-id "${association_id}" \ - --iam-instance-profile "Arn=$(get_batch_instance_profile_arn_from_ssm)" - -## END LOCAL EXECUTOR WORKAROUND ## - -## RESUME BLOCK ## - -if [[ -n "${resume_nextflow_dir:-}" ]]; then - aws s3 sync \ - --no-progress \ - "${resume_nextflow_dir}/" ./.nextflow/ -fi - -## END RESUME BLOCK ## - -## STAGE DATA ## - -input_file_args=' -dragen_somatic_dir -dragen_germline_dir -oncoanalyser_dir -' - -declare -A input_fps -for fp_name in ${input_file_args}; do - fp=${!fp_name:-} - if [[ -z ${fp} ]]; then - continue - fi - - if [[ ${fp} =~ ^gds://.* ]]; then - input_fps[${fp_name}]=$(stage_gds_fp "${fp}") - else - input_fps[${fp_name}]=${fp%}/ - fi -done - -## END STAGE DATA ## - -## SAMPLESHEET PREP ## - -cat < samplesheet.csv -id,subject_name,sample_name,filetype,filepath -${subject_id}_${tumor_sample_id},${subject_id},${tumor_sample_id},dragen_somatic_dir,${input_fps['dragen_somatic_dir']} -${subject_id}_${tumor_sample_id},${subject_id},${normal_sample_id},dragen_germline_dir,${input_fps['dragen_germline_dir']} -${subject_id}_${tumor_sample_id},${subject_id},${tumor_sample_id},oncoanalyser_dir,${input_fps['oncoanalyser_dir']} -EOF - -## END SAMPLESHEET PREP ## - -## NEXTFLOW ARGS ## - -nextflow_args='' -if [[ -n "${resume_nextflow_dir:-}" ]]; then - nextflow_args+=' -resume' -fi - -## END NEXFLOW ARGS ## - -## CREATE NEXTFLOW CONFIG ## -sed \ - --regexp-extended \ - --expression \ - " - s#__BATCH_INSTANCE_ROLE__#$(get_batch_instance_role_arn_from_ssm)#g; - s#__PORTAL_RUN_ID__#${portal_run_id}#g; - " \ - "${TEMPLATE_CONFIG_PATH}" > "${NEXTFLOW_CONFIG_PATH}" - -## END CREATE NEXTFLOW CONFIG ## -trap upload_data EXIT - -nextflow \ - -config "${NEXTFLOW_CONFIG_PATH}" \ - run "${MAIN_NF_PATH}" \ - -ansi-log "false" \ - --monochrome_logs \ - -profile "docker" \ - -work-dir "${output_scratch_dir}/" \ - ${nextflow_args} \ - --input "samplesheet.csv" \ - --ref_data_path "s3://$(get_refdata_basepath)/" \ - --outdir "${output_results_dir}/" - -# Upload data cleanly -upload_data - -# Then exit cleanly -trap - EXIT diff --git a/application/pipeline-stacks/sash/lambda_functions/batch_job_submission/lambda_code.py b/application/pipeline-stacks/sash/lambda_functions/batch_job_submission/lambda_code.py deleted file mode 100644 index 7139463..0000000 --- a/application/pipeline-stacks/sash/lambda_functions/batch_job_submission/lambda_code.py +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env python3 -import json -import logging - - -import boto3 - - -LOGGER = logging.getLogger() -LOGGER.setLevel(logging.INFO) - - -CLIENT_BATCH = boto3.client('batch') -CLIENT_SSM = boto3.client('ssm') - - -def main(event, context): - """Lambda entry point. - - Event dict payload example: - { - "portal_run_id": "20230530abcdefgh", - "subject_id": "SBJ00001", - "tumor_sample_id": "PRJ230001", - "tumor_library_id": "L2300001", - "normal_sample_id": "PRJ230002", - "normal_library_id": "L2300002", - "dragen_somatic_dir": "gds://production/analysis_data/SBJ00001/wgs_tumor_normal/20230515zyxwvuts/L2300001_L2300002/", - "dragen_germline_dir": "gds://production/analysis_data/SBJ00001/wgs_tumor_normal/20230515zyxwvuts/L2300002_dragen_germline/", - "oncoanalyser_dir": "s3://org.umccr.data.oncoanalyser/analysis_data/SBJ00001/oncoanalyser/20230518poiuytre/wgs/L2300001__L2300002/" - } - - :params dict event: Event payload - :params LambdaContext context: Lambda context - :returns: Status code and message - :rtype: dict - """ - - LOGGER.info(f'Received event: {json.dumps(event)}') - - validate_response = validate_event_data(event) - if validate_response['returncode'] != 0: - return validate_response['message'] - - job_data = get_job_data(event) - - output_directory = get_output_results_dir( - event['subject_id'], - event['tumor_library_id'], - event['normal_library_id'], - event['portal_run_id'], - ) - - LOGGER.info(f'Compiled job data: {job_data}') - - response_job = CLIENT_BATCH.submit_job( - jobName=job_data['name'], - jobQueue=job_data['queue_name'], - jobDefinition=job_data['definition_arn'], - containerOverrides={ - 'command': job_data['command'], - 'resourceRequirements': [ - {'type': 'MEMORY', 'value': '15000'}, - {'type': 'VCPU', 'value': '2'}, - ], - }, - parameters={ - 'portal_run_id': event['portal_run_id'], - 'workflow': 'sash', - 'version': get_ssm_parameter_value('/nextflow_stack/sash/pipeline_version_tag'), - 'output': json.dumps({'output_directory': output_directory}), - }, - tags={ - 'Stack': 'NextflowStack', - 'SubStack': 'SashStack', - 'RunId': event['portal_run_id'], - }, - propagateTags=True - ) - - LOGGER.info(f'Received job submission response: {response_job}') - - return {'statusCode': 200, 'body': json.dumps(f'Submitted job with ID {response_job["jobId"]}')} - - -def get_job_data(event): - - job_name = f'sash__{event["subject_id"]}__{event["tumor_library_id"]}__{event["normal_library_id"]}__{event["portal_run_id"]}' - job_definition_arn = get_ssm_parameter_value('/nextflow_stack/sash/batch_job_definition_arn') - job_queue_name = 'nextflow-pipeline' - - command = get_job_command(event) - - return { - 'name': job_name, - 'definition_arn': job_definition_arn, - 'queue_name': job_queue_name, - 'command': command, - } - - -def get_ssm_parameter_value(name): - - response = CLIENT_SSM.get_parameter(Name=name) - return response['Parameter']['Value'] - - -def get_output_results_dir(subject_id, tumor_library_id, normal_library_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/sash/nf_bucket_name') - return f's3://{bucket_name}/analysis_data/{subject_id}/sash/{portal_run_id}/{tumor_library_id}_{normal_library_id}' - - -def get_output_scratch_dir(subject_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/sash/nf_bucket_name') - return f's3://{bucket_name}/temp_data/{subject_id}/sash/{portal_run_id}/scratch' - - -def get_output_staging_dir(subject_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/sash/nf_bucket_name') - return f's3://{bucket_name}/temp_data/{subject_id}/sash/{portal_run_id}/staging' - - -def get_job_command(event): - - output_results_dir = get_output_results_dir( - event['subject_id'], - event['tumor_library_id'], - event['normal_library_id'], - event['portal_run_id'], - ) - output_scratch_dir = get_output_scratch_dir(event['subject_id'], event['portal_run_id']) - output_staging_dir = get_output_staging_dir(event['subject_id'], event['portal_run_id']) - - oncoanalyser_dir = event['oncoanalyser_dir'].rstrip('/') + f'/{event["subject_id"]}_{event["tumor_sample_id"]}/' - - command_components = [ - './assets/run.sh', - f'--portal_run_id {event["portal_run_id"]}', - f'--subject_id {event["subject_id"]}', - f'--tumor_sample_id {event["tumor_sample_id"]}', - f'--tumor_library_id {event["tumor_library_id"]}', - f'--normal_sample_id {event["normal_sample_id"]}', - f'--normal_library_id {event["normal_library_id"]}', - f'--dragen_somatic_dir {event["dragen_somatic_dir"]}', - f'--dragen_germline_dir {event["dragen_germline_dir"]}', - f'--oncoanalyser_dir {oncoanalyser_dir}', - f'--output_results_dir {output_results_dir}', - f'--output_staging_dir {output_staging_dir}', - f'--output_scratch_dir {output_scratch_dir}', - ] - - return ['bash', '-o', 'pipefail', '-c', ' '.join(command_components)] - - -def validate_event_data(event): - - required_params = [ - 'portal_run_id', - 'subject_id', - 'tumor_sample_id', - 'tumor_library_id', - 'normal_sample_id', - 'normal_library_id', - 'dragen_somatic_dir', - 'dragen_germline_dir', - 'oncoanalyser_dir', - ] - - missing_params = set(required_params) - set(event) - if missing_params: - plurality = 'parameters' if len(missing_params) > 1 else 'parameter' - message = f'Missing required {plurality}: {", ".join(missing_params)}' - return get_error_response(message) - - extra_params = set(event) - set(required_params) - if extra_params: - plurality = 'parameters' if len(extra_params) > 1 else 'parameter' - message = f'Found unexpected {plurality}: {", ".join(extra_params)}' - return get_error_response(message) - - return {'returncode': 0, 'message': dict()} - - -def get_error_response(message): - - LOGGER.error(message) - message_response = {'statusCode': 400, 'body': json.dumps(message)} - return {'returncode': 1, 'message': message_response} diff --git a/application/pipeline-stacks/sash/stack.ts b/application/pipeline-stacks/sash/stack.ts deleted file mode 100644 index d7a2c5c..0000000 --- a/application/pipeline-stacks/sash/stack.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Construct } from 'constructs'; - -import * as common from '../common'; - - -export class SashStack extends common.PipelineStack { - constructor(scope: Construct, id: string, props: common.IPipelineStack) { - super(scope, id, props); - } -} diff --git a/application/pipeline-stacks/star-align-nf/Dockerfile b/application/pipeline-stacks/star-align-nf/Dockerfile deleted file mode 100644 index 347ae6c..0000000 --- a/application/pipeline-stacks/star-align-nf/Dockerfile +++ /dev/null @@ -1,101 +0,0 @@ -FROM docker.io/continuumio/miniconda3:23.10.0-1 - -# Set package versions and other info -# Generic -ARG JQ_VERSION="1.6" -ARG NEXTFLOW_VERSION="23.10.1" -ARG OPENJDK_VERSION="17.0.10" -ARG PARALLEL_VERSION="20230322" -ARG RCLONE_VERSION="1.62.2" - -# Docker packages -ARG DEBIAN_PLATFORM_VERSION="debian.11~bullseye_amd64" -ARG CONTAINERD_IO_VERSION="1.6.18-1" -ARG DOCKER_BUILDX_VERSION="0.10.2-1" -ARG DOCKER_CE_CLI_VERSION="23.0.1-1" -ARG DOCKER_CE_VERSION="23.0.1-1" -ARG DOCKER_COMPOSE_VERSION="2.16.0-1" - -# Pipeline GH URL and branch/tag -ARG PIPELINE_GITHUB_REF // NOTE(SW): must be provided as build argument -ARG PIPELINE_GITHUB_REPO_URL="https://github.com/scwatts/star-align-nf.git" - -RUN \ - test -n "${PIPELINE_GITHUB_REF}" || (echo "PIPELINE_GITHUB_REF must be set" && false) - -# Configure Conda -RUN \ - conda install --yes \ - conda-libmamba-solver && \ - echo '\ -solver: libmamba\n\ -channels:\n\ - - conda-forge\n\ - - bioconda\n\ - - defaults\n\ -' > ~/.condarc - -# Install software with apt -RUN \ - apt update -y -q && \ - apt install -y -q \ - curl \ - jq="${JQ_VERSION}*" \ - unzip \ - wget && \ - apt clean -y -q - -# Install packages with Conda -RUN \ - conda install --yes \ - "nextflow ==${NEXTFLOW_VERSION}" \ - "openjdk ==${OPENJDK_VERSION}" \ - "parallel ==${PARALLEL_VERSION}" \ - "rclone ==${RCLONE_VERSION}" && \ - conda clean --all --force-pkgs-dirs --yes - -# Install AWS CLIv2 -RUN \ - wget --quiet 'https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip' \ - --output-document "awscli.zip" && \ - unzip -qq "awscli.zip" && \ - ./aws/install && \ - rm --force --recursive aws/ "awscli.zip" - -# Install Docker; used to run additional containers via the host service -RUN \ - apt-get update && \ - mkdir -p "docker_install_temp/" && \ - ( \ - cd "docker_install_temp/" && \ - parallel --jobs 0 " \ - wget \ - --quiet \ - 'https://download.docker.com/linux/debian/dists/bullseye/pool/stable/amd64/{}' \ - " ::: \ - "containerd.io_${CONTAINERD_IO_VERSION}_amd64.deb" \ - "docker-ce_${DOCKER_CE_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-ce-cli_${DOCKER_CE_CLI_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-buildx-plugin_${DOCKER_BUILDX_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-compose-plugin_${DOCKER_COMPOSE_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" && \ - apt install --yes --quiet ./*.deb \ - ) && \ - rm --force --recursive "docker_install_temp/" && \ - apt clean --yes --quiet - -# Install pipeline software and config -RUN \ - mkdir --parents "/root/pipeline/software/" && \ - mkdir --parents "/root/pipeline/assets/" && \ - ( \ - cd "/root/pipeline/software/" && \ - git clone --branch "${PIPELINE_GITHUB_REF}" "${PIPELINE_GITHUB_REPO_URL}" \ - ) - -COPY assets/nextflow_aws.template.config /root/pipeline/assets/ -COPY assets/run.sh /root/pipeline/assets/ - -RUN \ - chmod +x "/root/pipeline/assets/run.sh" - -WORKDIR /root/pipeline/ diff --git a/application/pipeline-stacks/star-align-nf/assets/nextflow_aws.template.config b/application/pipeline-stacks/star-align-nf/assets/nextflow_aws.template.config deleted file mode 100644 index 38a62b4..0000000 --- a/application/pipeline-stacks/star-align-nf/assets/nextflow_aws.template.config +++ /dev/null @@ -1,63 +0,0 @@ -plugins { - id 'nf-amazon' -} - -fusion { - enabled = true -} - -wave { - enabled = true -} - -aws { - batch { - jobRole = '__BATCH_INSTANCE_ROLE__' - volumes = '/mnt/local_ephemeral/:/tmp/' - } -} - -process { - executor = 'awsbatch' - scratch = false - - // NOTE(SW): using docker.runOptions in 23.10.01 causes `--network host` to be included twice, triggering an error in Docker - containerOptions = '--network host' - - resourceLabels = { - return [ - 'Stack': 'NextflowStack', - 'SubStack': 'StarAlignNfStack', - 'RunId': '__PORTAL_RUN_ID__', - 'JobName': task.process, - ] - } - - withName: 'STAR' { - // NOTE(SW): Batch/ECS instances unable to pull quay.io/biocontainers/star:2.7.3a--0 without error; fixed in next star-align-nf release - container = 'docker.io/scwatts/star:2.7.3a--1' - - queue = 'nextflow-task-ondemand-8cpu_64gb-nvme_ssd' - cpus = 8 - memory = 60.GB - } - - withName: 'SAMTOOLS_SORT' { - queue = 'nextflow-task-ondemand-4cpu_16gb-nvme_ssd' - cpus = 4 - memory = 14.GB - } - - withName: 'GATK4_MARKDUPLICATES' { - queue = 'nextflow-task-ondemand-2cpu_16gb-nvme_ssd' - cpus = 1 - memory = 14.GB - } - - withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { - executor = 'local' - cpus = 1 - memory = 12.GB - } - -} diff --git a/application/pipeline-stacks/star-align-nf/assets/run.sh b/application/pipeline-stacks/star-align-nf/assets/run.sh deleted file mode 100755 index 428cac4..0000000 --- a/application/pipeline-stacks/star-align-nf/assets/run.sh +++ /dev/null @@ -1,369 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -print_help_text() { - cat <&2 - exit 1 -fi - -## SSM Parameter functions - -get_ssm_parameter_value(){ - aws ssm get-parameter \ - --name "$1" \ - --output json | - jq --raw-output '.Parameter | .Value' -} - -get_batch_instance_role_arn_from_ssm(){ - get_ssm_parameter_value "/nextflow_stack/star-align-nf/batch_instance_task_role_arn" -} - -get_batch_instance_profile_arn_from_ssm(){ - get_ssm_parameter_value "/nextflow_stack/star-align-nf/batch_instance_task_profile_arn" -} - -get_star_index_from_ssm(){ - get_ssm_parameter_value "/nextflow_stack/star-align-nf/refdata_star_index" -} - -get_ica_access_token_from_secrets_manager(){ - aws secretsmanager get-secret-value \ - --secret-id IcaSecretsPortal \ - --output json | \ - jq --raw-output \ - ' - .SecretString - ' -} - -stage_gds_fp() { - local gds_fp="${1}" - local gds_dp="${gds_fp%/*}/" - - # Local vars - local dst_bucket - local dst_key_base - local dst_dp - local dst_fp - local gds_volume_name - local gds_path - local gds_folder_id - local creds - local src_fp - - - dst_dp="${output_staging_dir#s3://}" - dst_fp="${dst_dp}/${gds_fp##*/}" - - echo s3://${dst_fp} - - if [[ -z "${ICA_ACCESS_TOKEN:-}" ]]; then - ICA_ACCESS_TOKEN="$(get_ica_access_token_from_secrets_manager)" - export ICA_ACCESS_TOKEN - fi - - # Get gds folder id from data path - gds_volume_name="$( \ - python3 -c "from urllib.parse import urlparse; print(urlparse('${gds_dp}').netloc)" \ - )" - gds_path="$( \ - python3 -c "from urllib.parse import urlparse; print(urlparse('${gds_dp}').path)" \ - )" - gds_folder_id="$( \ - curl --fail --silent --location --show-error \ - --request "GET" \ - --header "Accept: application/json" \ - --header "Authorization: Bearer ${ICA_ACCESS_TOKEN}" \ - --url "https://aps2.platform.illumina.com/v1/folders?volume.name=${gds_volume_name}&path=${gds_path}" | \ - jq --raw-output \ - ' - .items | - map(.id) | - .[] - ' \ - )" - - # Get ICA credentials for folder - creds="$( \ - curl --fail --silent --location --show-error \ - --request "PATCH" \ - --header 'Accept: application/json' \ - --header "Authorization: Bearer ${ICA_ACCESS_TOKEN}" \ - --header "Content-Type: application/json-patch+json" \ - --url "https://aps2.platform.illumina.com/v1/folders/${gds_folder_id}?include=ObjectStoreAccess" \ - --data '{}' | \ - jq --raw-output \ - '.objectStoreAccess.awsS3TemporaryUploadCredentials' \ - )" - - - mkdir -p ~/.config/rclone/ - - cat < ~/.config/rclone/rclone.conf -[ica] -type = s3 -provider = AWS -access_key_id = $(jq --raw-output '.access_Key_Id' <<< "${creds}") -secret_access_key = $(jq --raw-output '.secret_Access_Key' <<< "${creds}") -session_token = $(jq --raw-output '.session_Token' <<< "${creds}") -region = ap-southeast-2 - -[aws] -type = s3 -provider = AWS -env_auth = true -region = ap-southeast-2 -no_check_bucket = true -EOF - - src_fp="$( \ - jq --raw-output \ - --arg gds_fp "${gds_fp##*/}" \ - '"\(.bucketName)/\(.keyPrefix)\($gds_fp)"' \ - <<< "${creds}" \ - )" - - echo "staging ${gds_fp} to s3://${dst_fp}" 1>&2 - rclone copy --s3-upload-concurrency 8 \ - "ica:${src_fp}" "aws:${dst_dp}/" -} - -# Final upload data function -upload_data() { - aws s3 sync \ - --no-progress \ - --no-follow-symlinks \ - --exclude='software/*' \ - --exclude='assets/*' \ - --exclude='work/*' \ - ./ "${output_results_dir}/" -} - -## END FUNCTIONS ## - -## MISC SETUP ## - -# Get IMDSv2 session token to make metadata requests -IMDS_TOKEN=$(curl -s -X PUT -H "X-aws-ec2-metadata-token-ttl-seconds: 21600" http://169.254.169.254/latest/api/token) - -## END MISC SETUP ## - -## SET AWS REGION ## - -# Get the current aws region -# https://stackoverflow.com/questions/4249488/find-region-from-within-an-ec2-instance -export AWS_REGION=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/placement/region) - -## END SET AWS REGION ## - -## LOCAL EXECUTOR WORKAROUND ## - -# This stack runs the main Nextflow pipeline process as a Batch job and therefore the pipeline process is executed -# within a Docker container. Individual pipeline tasks are generally submitted as Batch jobs but can also be run -# locally. Running a process locally is useful for very short jobs. In order to run a process locally, the pipeline must -# execute the task within a Docker container. I have configured the Docker container that executes the Nextflow pipeline -# process to use the host Docker service for local jobs. -# -# A consequence of this set up is that that all task run locally using Docker containers inherit the EC2 instance IAM -# profile, which can only be set at creation of the Batch compute environment during stack deployment. In this case the -# Batch compute environment uses the non-permissive Nextflow pipeline role. This means to run Nextflow processes locally -# that can r/w to S3 (e.g. when using Fusion, S3 output directory, etc) we must manually set the EC2 instance IAM role -# at runtime to a profile with the required permissions. Here I associate the instance with the OncoanalyserStack task -# role. There may be better approaches to achieve this. - -instance_id=$(curl -s -H "X-aws-ec2-metadata-token: ${IMDS_TOKEN}" http://169.254.169.254/latest/meta-data/instance-id) -association_id=$( - aws ec2 describe-iam-instance-profile-associations | \ - jq --raw-output \ - --arg instance_id "${instance_id}" \ - ' - .IamInstanceProfileAssociations | - map( - select(.InstanceId == $instance_id) - ) | - map( - .AssociationId - ) | - .[] - ' -) -aws ec2 replace-iam-instance-profile-association 1>/dev/null \ - --association-id "${association_id}" \ - --iam-instance-profile "Arn=$(get_batch_instance_profile_arn_from_ssm)" - -## END LOCAL EXECUTOR WORKAROUND ## - -## SAMPLESHEET PREP ## - -input_file_args=' -fastq_fwd -fastq_rev -' - -declare -A input_fps -for fp_name in ${input_file_args}; do - fp=${!fp_name:-} - if [[ -z ${fp} ]]; then - continue - fi - - if [[ ${fp} =~ ^gds://.* ]]; then - input_fps[${fp_name}]=$(stage_gds_fp "${fp}") - else - input_fps[${fp_name}]=${fp} - fi -done - - -cat < samplesheet.csv -sample_id,fastq_fwd,fastq_rev -${sample_id},${input_fps['fastq_fwd']},${input_fps['fastq_rev']} -EOF - -## END SAMPLESHEET PREP ## - -## CREATE NEXTFLOW CONFIG ## - -TEMPLATE_CONFIG_PATH="/root/pipeline/assets/nextflow_aws.template.config" -NEXTFLOW_CONFIG_PATH="aws.config" - -sed \ - --regexp-extended \ - --expression \ - " - s#__BATCH_INSTANCE_ROLE__#$(get_batch_instance_role_arn_from_ssm)#g; - s#__PORTAL_RUN_ID__#${portal_run_id}#g; - " \ - "${TEMPLATE_CONFIG_PATH}" > "${NEXTFLOW_CONFIG_PATH}" - -## END CREATE NEXTFLOW CONFIG ## - -## RUN NEXTFLOW ## - -trap upload_data EXIT - -nextflow \ - -config ${NEXTFLOW_CONFIG_PATH} \ - run software/star-align-nf/main.nf \ - -ansi-log false \ - -profile docker \ - -work-dir "${output_scratch_dir}/" \ - --monochrome_logs \ - --input samplesheet.csv \ - --star_index_path s3://$(get_star_index_from_ssm)/ \ - --outdir ${output_results_dir}/ - -# Upload data cleanly -upload_data - -## END RUN NEXTFLOW ## - -# Then exit cleanly -trap - EXIT diff --git a/application/pipeline-stacks/star-align-nf/lambda_functions/batch_job_submission/lambda_code.py b/application/pipeline-stacks/star-align-nf/lambda_functions/batch_job_submission/lambda_code.py deleted file mode 100644 index 4d462ba..0000000 --- a/application/pipeline-stacks/star-align-nf/lambda_functions/batch_job_submission/lambda_code.py +++ /dev/null @@ -1,178 +0,0 @@ -#!/usr/bin/env python3 -import json -import logging - - -import boto3 - - -LOGGER = logging.getLogger() -LOGGER.setLevel(logging.INFO) - - -CLIENT_BATCH = boto3.client('batch') -CLIENT_SSM = boto3.client('ssm') - - -def main(event, context): - """Lambda entry point. - - Event dict payload example: - { - "portal_run_id": "20230530abcdefgh", - "subject_id": "SBJ00001", - "sample_id": "PRJ230002", - "library_id": "L2300002", - "fastq_fwd": "gds://production/primary_data/230430_A00001_0001_AH1VLHDSX1/20230430qazwsxed/WTS_NebRNA/PRJ230002_L2300002_S1_L001_R1_001.fastq.gz", - "fastq_rev": "gds://production/primary_data/230430_A00001_0001_AH1VLHDSX1/20230430qazwsxed/WTS_NebRNA/PRJ230002_L2300002_S1_L001_R2_001.fastq.gz", - } - - :params dict event: Event payload - :params LambdaContext context: Lambda context - :returns: Status code and message - :rtype: dict - """ - - LOGGER.info(f'Received event: {json.dumps(event)}') - - validate_response = validate_event_data(event) - if validate_response['returncode'] != 0: - return validate_response['message'] - - job_data = get_job_data(event) - - output_directory = get_output_results_dir( - event['subject_id'], - event['library_id'], - event['portal_run_id'], - ) - - LOGGER.info(f'Compiled job data: {job_data}') - - response_job = CLIENT_BATCH.submit_job( - jobName=job_data['name'], - jobQueue=job_data['queue_name'], - jobDefinition=job_data['definition_arn'], - containerOverrides={ - 'command': job_data['command'], - 'resourceRequirements': [ - {'type': 'MEMORY', 'value': '15000'}, - {'type': 'VCPU', 'value': '2'}, - ], - }, - parameters={ - 'portal_run_id': event['portal_run_id'], - 'workflow': 'star_alignment', - 'version': get_ssm_parameter_value('/nextflow_stack/star-align-nf/pipeline_version_tag'), - 'output': json.dumps({'output_directory': output_directory}), - }, - tags={ - 'Stack': 'NextflowStack', - 'SubStack': 'StarAlignNfStack', - 'RunId': event['portal_run_id'], - }, - propagateTags=True - ) - - LOGGER.info(f'Received job submission response: {response_job}') - - return {'statusCode': 200, 'body': json.dumps(f'Submitted job with ID {response_job["jobId"]}')} - - -def get_job_data(event): - - job_name = f'star-align-nf__{event["subject_id"]}__{event["library_id"]}__{event["portal_run_id"]}' - job_definition_arn = get_ssm_parameter_value('/nextflow_stack/star-align-nf/batch_job_definition_arn') - job_queue_name = 'nextflow-pipeline' - - command = get_job_command(event) - - return { - 'name': job_name, - 'definition_arn': job_definition_arn, - 'queue_name': job_queue_name, - 'command': command, - } - - -def get_ssm_parameter_value(name): - - response = CLIENT_SSM.get_parameter(Name=name) - return response['Parameter']['Value'] - - -def get_output_results_dir(subject_id, library_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/star-align-nf/nf_bucket_name') - return f's3://{bucket_name}/analysis_data/{subject_id}/star-align-nf/{portal_run_id}/{library_id}' - - -def get_output_scratch_dir(subject_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/star-align-nf/nf_bucket_name') - return f's3://{bucket_name}/temp_data/{subject_id}/star-align-nf/{portal_run_id}/scratch' - - -def get_output_staging_dir(subject_id, portal_run_id): - - bucket_name = get_ssm_parameter_value('/nextflow_stack/star-align-nf/nf_bucket_name') - return f's3://{bucket_name}/temp_data/{subject_id}/star-align-nf/{portal_run_id}/staging' - - -def get_job_command(event): - - output_results_dir = get_output_results_dir( - event['subject_id'], - event['library_id'], - event['portal_run_id'], - ) - output_scratch_dir = get_output_scratch_dir(event['subject_id'], event['portal_run_id']) - output_staging_dir = get_output_staging_dir(event['subject_id'], event['portal_run_id']) - - command_components = [ - './assets/run.sh', - f'--portal_run_id {event["portal_run_id"]}', - f'--subject_id {event["subject_id"]}', - f'--sample_id {event["sample_id"]}', - f'--library_id {event["library_id"]}', - f'--fastq_fwd {event["fastq_fwd"]}', - f'--fastq_rev {event["fastq_rev"]}', - f'--output_results_dir {output_results_dir}', - f'--output_staging_dir {output_staging_dir}', - f'--output_scratch_dir {output_scratch_dir}', - ] - - return ['bash', '-o', 'pipefail', '-c', ' '.join(command_components)] - - -def validate_event_data(event): - - required_params = [ - 'portal_run_id', - 'subject_id', - 'sample_id', - 'library_id', - 'fastq_fwd', - 'fastq_rev', - ] - - missing_params = set(required_params) - set(event) - if missing_params: - plurality = 'parameters' if len(missing_params) > 1 else 'parameter' - message = f'Missing required {plurality}: {", ".join(missing_params)}' - return get_error_response(message) - - extra_params = set(event) - set(required_params) - if extra_params: - plurality = 'parameters' if len(extra_params) > 1 else 'parameter' - message = f'Found unexpected {plurality}: {", ".join(extra_params)}' - return get_error_response(message) - - return {'returncode': 0, 'message': dict()} - - -def get_error_response(message): - - LOGGER.error(message) - message_response = {'statusCode': 400, 'body': json.dumps(message)} - return {'returncode': 1, 'message': message_response} diff --git a/application/pipeline-stacks/star-align-nf/stack.ts b/application/pipeline-stacks/star-align-nf/stack.ts deleted file mode 100644 index b9e4432..0000000 --- a/application/pipeline-stacks/star-align-nf/stack.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Construct } from 'constructs'; - -import * as common from '../common'; - - -export class StarAlignNfStack extends common.PipelineStack { - constructor(scope: Construct, id: string, props: common.IPipelineStack) { - super(scope, id, props); - } -} diff --git a/application/resources/launch_templates/ebs.txt b/application/resources/launch_templates/ebs.txt deleted file mode 100644 index 9c7487d..0000000 --- a/application/resources/launch_templates/ebs.txt +++ /dev/null @@ -1,32 +0,0 @@ -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="==BOUNDARY==" - ---==BOUNDARY== -Content-Type: text/cloud-config; charset="us-ascii" - -packages: - - btrfs-progs - - git - - jq - - lvm2 - - sed - - unzip - - wget - ---==BOUNDARY== -Content-Type: text/x-shellscript; charset="us-ascii" - -#!/bin/bash -curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip -unzip -q /tmp/awscliv2.zip -d /tmp/ - -/tmp/aws/install --install-dir /opt/awscliv2/aws-cli/ --bin-dir /opt/awscliv2/bin/ -ln -s /opt/awscliv2/bin/aws /usr/local/bin/ - -git clone https://github.com/awslabs/amazon-ebs-autoscale /tmp/amazon-ebs-autoscale/ -(cd /tmp/amazon-ebs-autoscale/ && git checkout 6db0c70) - -bash /tmp/amazon-ebs-autoscale/install.sh --imdsv2 - -rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ ---==BOUNDARY==-- diff --git a/application/resources/launch_templates/nvme.txt b/application/resources/launch_templates/nvme.txt deleted file mode 100644 index 3961708..0000000 --- a/application/resources/launch_templates/nvme.txt +++ /dev/null @@ -1,13 +0,0 @@ -MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="==BOUNDARY==" - ---==BOUNDARY== -Content-Type: text/x-shellscript; charset="us-ascii" - -#!/bin/bash -mkdir -p /mnt/local_ephemeral/ -mkfs.ext4 /dev/nvme1n1 -mount /dev/nvme1n1 /mnt/local_ephemeral/ -chmod 777 /mnt/local_ephemeral/ - ---==BOUNDARY==-- diff --git a/application/settings.ts b/application/settings.ts deleted file mode 100644 index df6cb1c..0000000 --- a/application/settings.ts +++ /dev/null @@ -1,126 +0,0 @@ -import * as constants from './constants' -import {data} from "aws-cdk/lib/logging"; - - -export const taskQueueTypes = [ - constants.QueueType.Ondemand, - //constants.QueueType.Spot, -]; - -export const taskInstanceStorageTypes = [ - constants.InstanceStorageType.EbsOnly, - constants.InstanceStorageType.NvmeSsdOnly, -]; - -export const maxvCpusDefault = 128; - -export const dataAccountId = '503977275616'; -export const defaultRegion = 'ap-southeast-2'; - -class Shared { - constructor(public envName: string, public workflowName: string) {}; - - getNfBucket() { - return this.envName == 'prod' ? 'org.umccr.data.oncoanalyser' : `umccr-temp-${this.envName}`; - } - - getOrcabusDataBucket() { - return `pipeline-${this.envName}-cache-${dataAccountId}-${defaultRegion}` - } - - getOrcabusDataPrefix(): string { - if (this.envName == 'dev'){ - return 'byob-icav2/development/' - } - if (this.envName == 'stg'){ - return 'byob-icav2/staging/' - } - if (this.envName == 'prod'){ - return 'byob-icav2/production/' - } - throw new Error("Don't know how to handle envName: " + this.envName); - } - - getRefdataBasePath() { - return `${this.getS3Data().get('refdataBucketName')}/${this.getS3Data().get('refdataPrefix')}`; - } - - getS3Data() { - return new Map([ - ['nfBucketName', this.getNfBucket()], - ['nfPrefixTemp', 'temp_data'], - ['nfPrefixOutput', 'analysis_data'], - ['orcabusS3BucketName', this.getOrcabusDataBucket()], - ['orcabusS3ByobPrefix', this.getOrcabusDataPrefix()], - ['orcabusS3PrefixTemp', `${this.getOrcabusDataPrefix()}cache/${this.workflowName}`], - ['orcabusS3PrefixOutput', `${this.getOrcabusDataPrefix()}analysis/${this.workflowName}`], - ['refdataBucketName', `umccr-refdata-${this.envName}`], - ['refdataPrefix', 'workflow_data'], - ]); - } - - getSsmParameters() { - return new Map([ - [`/nextflow_stack/${this.workflowName}/nf_bucket_name`, this.getS3Data().get('nfBucketName')!], - [`/nextflow_stack/${this.workflowName}/nf_bucket_temp_prefix`, this.getS3Data().get('nfPrefixTemp')!], - [`/nextflow_stack/${this.workflowName}/nf_bucket_output_prefix`, this.getS3Data().get('nfPrefixOutput')!], - ]); - } -} - - -export class StarAlignNf extends Shared { - readonly versionTag = 'v0.1.0' - - getS3Data() { - return new Map([ - ...super.getS3Data().entries(), - ['refdataStarIndexPath', 'genomes/GRCh38_umccr/star_index/gencode_38/2.7.3a'], - ]); - } - - getSsmParameters() { - return new Map([ - ...super.getSsmParameters().entries(), - [`/nextflow_stack/${this.workflowName}/refdata_star_index`, `${this.getRefdataBasePath()}/${this.getS3Data().get('refdataStarIndexPath')!}`], - [`/nextflow_stack/${this.workflowName}/pipeline_version_tag`, this.versionTag], - ]); - } -} - - -export class Oncoanalyser extends Shared { - readonly versionTag = '42ee926' - - getS3Data() { - return new Map([ - ...super.getS3Data().entries(), - ['refdataGenomesPath', 'genomes'], - ['refdataHmfPath', 'hmf_reference_data/hmftools/5.34_38--2'], - ['refDataVirusbreakendDbPath', 'databases/virusbreakend/virusbreakenddb_20210401'], - ]); - } - - getSsmParameters() { - return new Map([ - ...super.getSsmParameters().entries(), - [`/nextflow_stack/${this.workflowName}/refdata_genomes`, `${this.getRefdataBasePath()}/${this.getS3Data().get('refdataGenomesPath')!}`], - [`/nextflow_stack/${this.workflowName}/refdata_hmf`, `${this.getRefdataBasePath()}/${this.getS3Data().get('refdataHmfPath')!}`], - [`/nextflow_stack/${this.workflowName}/refdata_virusbreakend`, `${this.getRefdataBasePath()}/${this.getS3Data().get('refDataVirusbreakendDbPath')!}`], - [`/nextflow_stack/${this.workflowName}/pipeline_version_tag`, this.versionTag], - ]); - } -} - - -export class Sash extends Shared { - readonly versionTag = 'v0.5.0' - - getSsmParameters() { - return new Map([ - ...super.getSsmParameters().entries(), - [`/nextflow_stack/${this.workflowName}/refdata_basepath`, `${this.getRefdataBasePath()}`], - [`/nextflow_stack/${this.workflowName}/pipeline_version_tag`, this.versionTag], - ]); - } -} diff --git a/application/shared/base-roles.ts b/application/shared/base-roles.ts deleted file mode 100644 index 0c69f99..0000000 --- a/application/shared/base-roles.ts +++ /dev/null @@ -1,210 +0,0 @@ -import * as cdk from 'aws-cdk-lib'; - -import * as iam from 'aws-cdk-lib/aws-iam'; -import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager'; - - -export function createPipelineRoles(args: { context: cdk.Stack, workflowName: string, jobQueueArns: string[] }) { - // Task and pipeline role - const roleBatchInstanceTask = getRoleBatchInstanceTask(args); - const roleBatchInstancePipeline = getBaseBatchInstancePipelineRole(args); - - // Profiles - const profileBatchInstanceTask = new iam.CfnInstanceProfile(args.context, `TaskBatchInstanceProfile-${args.workflowName}`, { - instanceProfileName: `nextflow-${args.workflowName}-task-batch-instance-profile`, - roles: [roleBatchInstanceTask.roleName], - }); - const profileBatchInstancePipeline = new iam.CfnInstanceProfile(args.context, `PipelineBatchInstanceProfile-${args.workflowName}`, { - instanceProfileName: `nextflow-${args.workflowName}-pipeline-batch-instance-profile`, - roles: [roleBatchInstancePipeline.roleName], - }); - - // Additional policies for pipelines - // * iam:PassRole - // - Nextflow requirement for Batch job submission - // - // * ec2:DescribeIamInstanceProfileAssociations - // - required for locally launched Docker containers - // - these containers inherit instance role, which is the SharedStack pipeline role - // - usually need at least S3 write permissions hence require setting the correct role to inherit at runtime - // - // * secretsmanager:DescribeSecret, secretsmanager:GetSecretValue - // - required staging data from GDS - // - roleBatchInstancePipeline.attachInlinePolicy( - new iam.Policy(args.context, `PipelinePolicyPassRole-${args.workflowName}`, { - statements: [ - new iam.PolicyStatement({ - actions: ['iam:PassRole'], - resources: [roleBatchInstanceTask.roleArn], - }) - ], - }) - ); - - roleBatchInstancePipeline.attachInlinePolicy( - new iam.Policy(args.context, `PipelinePolicySetInstanceRole-${args.workflowName}`, { - statements: [ - new iam.PolicyStatement({ - actions: [ - 'ec2:DescribeIamInstanceProfileAssociations', - // NOTE(SW): this /only/ allows passing the task role that is defined above - 'ec2:ReplaceIamInstanceProfileAssociation', - ], - resources: ['*'], - }) - ], - }) - ); - - const icaSecret = secretsmanager.Secret.fromSecretNameV2(args.context, `IcaSecret-${args.workflowName}`, 'IcaSecretsPortal'); - icaSecret.grantRead(roleBatchInstancePipeline); - - return { - taskRole: roleBatchInstanceTask, - taskProfile: profileBatchInstanceTask, - pipelineRole: roleBatchInstancePipeline, - pipelineProfile: profileBatchInstancePipeline, - } -} - - -export function getRoleBatchInstanceTask(args: { context: cdk.Stack, workflowName: string }) { - const roleTask = new iam.Role(args.context, `TaskBatchInstanceRole-${args.workflowName}`, { - roleName: `nextflow-${args.workflowName}-task-batch-instance-role`, - assumedBy: new iam.CompositePrincipal( - new iam.ServicePrincipal('ec2.amazonaws.com'), - new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), - ), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3ReadOnlyAccess'), - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), - iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceforEC2Role'), - ], - }); - - // TODO(SW): restrict instances this applies to using a condition with some stack-specific value - // such as instance name (NextflowApplication*), instance profile (defined in stack) or some - // other tag. Some condition keys: ec2:Attribute/${n}, ec2:ResourceTag/${n}, ec2:InstanceProfile - new iam.Policy(args.context, `TaskPolicyEbsAutoScale-${args.workflowName}`, { - roles: [roleTask], - statements: [new iam.PolicyStatement({ - actions: [ - 'ec2:AttachVolume', - 'ec2:CreateTags', - 'ec2:CreateVolume', - 'ec2:DeleteVolume', - 'ec2:DescribeTags', - 'ec2:DescribeVolumeAttribute', - 'ec2:DescribeVolumeStatus', - 'ec2:DescribeVolumes', - 'ec2:ModifyInstanceAttribute', - ], - resources: ['*'], - })], - }); - - return roleTask; -} - - -export function getBaseBatchInstancePipelineRole(args: { context: cdk.Stack, workflowName: string, jobQueueArns: string[] }) { - - const rolePipeline = new iam.Role(args.context, `PipelineBatchInstanceRole-${args.workflowName}`, { - roleName: `nextflow-${args.workflowName}-pipeline-batch-instance-role`, - assumedBy: new iam.CompositePrincipal( - new iam.ServicePrincipal('ec2.amazonaws.com'), - new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), - ), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3ReadOnlyAccess'), - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), - iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceforEC2Role'), - ], - }); - - // NOTE(SW): the below policies are mostly those described by the Nextflow documents, some minor changes have been - // made so that the access is less permissive - - new iam.Policy(args.context, `PipelinePolicyBatchJobs-${args.workflowName}`, { - roles: [rolePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'batch:CancelJob', - 'batch:SubmitJob', - 'batch:TagResource', - 'batch:TerminateJob', - ], - - resources: [ - ...args.jobQueueArns, - `arn:aws:batch:${args.context.region}:${args.context.account}:job-definition/nf-*` - ], - })], - }); - - new iam.Policy(args.context, `PipelinePolicyBatchGeneral-${args.workflowName}`, { - roles: [rolePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'batch:ListJobs', - 'batch:DescribeJobs', - 'batch:DescribeJobQueues', - 'batch:DescribeComputeEnvironments', - 'batch:RegisterJobDefinition', - 'batch:DescribeJobDefinitions', - ], - resources: ['*'] - })], - }); - - new iam.Policy(args.context, `PipelinePolicyInstances-${args.workflowName}`, { - roles: [rolePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'ecs:DescribeTasks', - 'ec2:DescribeInstances', - 'ec2:DescribeInstanceTypes', - 'ec2:DescribeInstanceAttribute', - 'ecs:DescribeContainerInstances', - 'ec2:DescribeInstanceStatus', - ], - resources: ['*'], - })], - }); - - new iam.Policy(args.context, `PipelinePolicyECR-${args.workflowName}`, { - roles: [rolePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'ecr:GetAuthorizationToken', - 'ecr:BatchCheckLayerAvailability', - 'ecr:GetDownloadUrlForLayer', - 'ecr:GetRepositoryPolicy', - 'ecr:DescribeRepositories', - 'ecr:ListImages', - 'ecr:DescribeImages', - 'ecr:BatchGetImage', - 'ecr:GetLifecyclePolicy', - 'ecr:GetLifecyclePolicyPreview', - 'ecr:ListTagsForResource', - 'ecr:DescribeImageScanFindings', - ], - resources: ['*'], - })], - }); - - new iam.Policy(args.context, `CloudWatchLogEvents-${args.workflowName}`, { - roles: [rolePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'logs:GetLogEvents', - ], - resources: [ - `arn:aws:logs:${args.context.region}:${args.context.account}:log-group:/aws/batch/job/:nf-*` - ], - })], - }); - - return rolePipeline; -} diff --git a/application/shared/batch-queues.ts b/application/shared/batch-queues.ts deleted file mode 100644 index af23fbc..0000000 --- a/application/shared/batch-queues.ts +++ /dev/null @@ -1,120 +0,0 @@ -import * as constants from '../constants'; - - -export function getQueueName(args: { - queueBaseName: string, - queueType: constants.QueueType, - storageType: constants.InstanceStorageType, - serviceType: constants.ServiceType, -}) { - let queueName; - const nameSuffix = `${args.queueType.toLowerCase()}-${args.storageType.toLowerCase()}`; - switch (args.serviceType) { - case (constants.ServiceType.Task): - queueName = `task-${args.queueType.toLowerCase()}-${args.queueBaseName}-${args.storageType.toLowerCase()}`; - break; - case (constants.ServiceType.Pipeline): - queueName = `${args.queueBaseName}-${args.queueType.toLowerCase()}-${args.storageType.toLowerCase()}`; - break; - default: - throw new Error('Got bad service type'); - } - - return queueName -} - - -export interface IQueueData { - name: string; - instances: Map; - maxvCpus?: number; -} - - -export const pipelineQueue : IQueueData = { - name: 'pipeline', - instances: new Map([ - ['standard', ['r6i.large']], - ['nvme_ssd', ['r6id.large']], - ]), -}; - -export const taskQueues: IQueueData[] = [ - - { - name: '2cpu_16gb', - instances: new Map([ - ['standard', ['r5.large', 'r5n.large', 'r6i.large']], - ['nvme_ssd', ['r5d.large', 'r5dn.large', 'r6id.large']], - ]), - }, - - { - name: '4cpu_16gb', - instances: new Map([ - ['standard', ['m5.xlarge', 'm6i.xlarge']], - ['nvme_ssd', ['m5d.xlarge', 'm6id.xlarge']], - ]), - }, - - { - name: '4cpu_32gb', - instances: new Map([ - ['standard', ['r5.xlarge', 'r5n.xlarge', 'r6i.xlarge']], - ['nvme_ssd', ['r5d.xlarge', 'r5dn.xlarge', 'r6id.xlarge']], - ]), - }, - - { - name: '8cpu_32gb', - instances: new Map([ - ['standard', ['m5.2xlarge', 'm6i.2xlarge']], - ['nvme_ssd', ['m5d.2xlarge', 'm6id.2xlarge']], - ]), - }, - - { - name: '8cpu_64gb', - instances: new Map([ - ['standard', ['r5.2xlarge', 'r5n.2xlarge', 'r6i.2xlarge']], - ['nvme_ssd', ['r5d.2xlarge', 'r5dn.2xlarge', 'r6id.2xlarge']], - ]), - }, - - { - name: '16cpu_32gb', - instances: new Map([ - ['standard', ['c5.4xlarge', 'c6i.4xlarge']], - ['nvme_ssd', ['c5d.4xlarge', 'c6id.4xlarge']], - ]), - maxvCpus: 256, - }, - - { - name: '16cpu_64gb', - instances: new Map([ - ['standard', ['m5.4xlarge', 'm6i.4xlarge']], - ['nvme_ssd', ['m5d.4xlarge', 'm6id.4xlarge']], - ]), - maxvCpus: 256, - }, - - { - name: '16cpu_128gb', - instances: new Map([ - ['standard', ['r5.4xlarge', 'r6i.4xlarge']], - ['nvme_ssd', ['r5d.4xlarge', 'r6id.4xlarge']], - ]), - maxvCpus: 256, - }, - - { - name: '32cpu_64gb', - instances: new Map([ - ['standard', ['c5a.8xlarge', 'c6a.8xlarge']], - ['nvme_ssd', ['c5ad.8xlarge', 'c6id.8xlarge']], - ]), - maxvCpus: 2048, - }, - -]; diff --git a/bin/oncoanalyser-stack.ts b/bin/oncoanalyser-stack.ts new file mode 100644 index 0000000..f080e34 --- /dev/null +++ b/bin/oncoanalyser-stack.ts @@ -0,0 +1,15 @@ +#!/usr/bin/env node +import * as cdk from 'aws-cdk-lib'; + +import * as settings from '../lib/settings'; +import * as stack from '../lib/application-stack'; + +const app = new cdk.App() +const oncoanalyserStack = new stack.ApplicationStack(app, 'OncoanalyserStack', { + env: { + account: settings.AWS_ACCOUNT, + region: settings.AWS_REGION, + }, +}); + +cdk.Tags.of(oncoanalyserStack).add('Stack', 'OncoanalyserStack'); diff --git a/cdk.json b/cdk.json index de3510a..9559e86 100644 --- a/cdk.json +++ b/cdk.json @@ -1,5 +1,5 @@ { - "app": "npx ts-node --prefer-ts-exts deployment/nextflow-stack.ts", + "app": "npx ts-node --prefer-ts-exts bin/oncoanalyser-stack.ts", "watch": { "include": [ "**" @@ -34,7 +34,6 @@ "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, "@aws-cdk/core:enablePartitionLiterals": true, "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, - "@aws-cdk/aws-iam:standardizedServicePrincipals": true, "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, @@ -44,6 +43,44 @@ "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, - "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, + "@aws-cdk/aws-ecs:enableImdsBlockingDeprecatedFeature": false, + "@aws-cdk/aws-ecs:disableEcsImdsBlocking": true, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, + "@aws-cdk/aws-dynamodb:resourcePolicyPerReplica": true, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true, + "@aws-cdk/aws-stepfunctions-tasks:fixRunEcsTaskPolicy": true, + "@aws-cdk/aws-ec2:bastionHostUseAmazonLinux2023ByDefault": true, + "@aws-cdk/aws-route53-targets:userPoolDomainNameMethodWithoutCustomResource": true, + "@aws-cdk/aws-elasticloadbalancingV2:albDualstackWithoutPublicIpv4SecurityGroupRulesDefault": true, + "@aws-cdk/aws-iam:oidcRejectUnauthorizedConnections": true } } diff --git a/deployment/codepipeline-stack.ts b/deployment/codepipeline-stack.ts deleted file mode 100644 index 4689e44..0000000 --- a/deployment/codepipeline-stack.ts +++ /dev/null @@ -1,124 +0,0 @@ -import {Construct} from "constructs"; - -import * as moment from 'moment'; - -import {Environment, pipelines, Stack, StackProps} from "aws-cdk-lib"; -import {StringParameter} from "aws-cdk-lib/aws-ssm"; -import {Effect, PolicyStatement} from "aws-cdk-lib/aws-iam"; -import {ComputeType, LinuxBuildImage} from "aws-cdk-lib/aws-codebuild"; - -import {AWS_ENV_STG, AWS_ENV_PROD} from './settings-umccr'; -import {ApplicationBuildStage} from "../application/application-stack"; - - -interface ICodePipelineStackProps extends StackProps { - env: Environment -} - -export class CodePipelineStack extends Stack { - constructor(scope: Construct, id: string, props: ICodePipelineStackProps) { - super(scope, id, props); - - // The pipeline initialisation has been heavily lifted from https://github.com/umccr/holmes/blob/main/holmes-pipeline-stack.ts - // Credit Andrew Patterson - - // these are *build* parameters that we either want to re-use across lots of stacks, or are - // 'sensitive' enough we don't want them checked into Git - but not sensitive enough to record as a Secret - const codeStarArn = StringParameter.valueFromLookup( - this, - "codestar_github_arn" - ); - - const inputSource = pipelines.CodePipelineSource.connection("umccr/nextflow-stack", "main", { - connectionArn: codeStarArn, - codeBuildCloneOutput: true - }) - - const pipeline = new pipelines.CodePipeline(this, "NextflowBuildPipeline", { - // should normally be commented out - only use when debugging pipeline itself - // selfMutation: false, - // turned on because our stack makes docker assets - dockerEnabledForSynth: true, - dockerEnabledForSelfMutation: true, - synth: new pipelines.CodeBuildStep("Synth", { - // Use a connection created using the AWS console to authenticate to GitHub - // Other sources are available. - input: inputSource, - commands: [ - "npm ci", - // our cdk is configured to use ts-node - so we don't need any build step - just synth - "npx cdk synth", - ], - env: { - // See https://github.com/aws/aws-cdk/issues/20643#issuecomment-1219565988 for more info as to how this works - // We need to call this source attribute then we use it below to generate the tag name - "COMMIT_ID": inputSource.sourceAttribute("CommitId"), - }, - rolePolicyStatements: [ - new PolicyStatement({ - effect: Effect.ALLOW, - actions: ["sts:AssumeRole"], - resources: ["*"], - //conditions: { - // StringEquals: { - // "iam:ResourceTag/aws-cdk:bootstrap-role": "lookup", - // }, - //}, - }), - ], - }), - codeBuildDefaults: { - buildEnvironment: { - buildImage: LinuxBuildImage.STANDARD_6_0, - computeType: ComputeType.LARGE - }, - // we need to give the codebuild engines permissions to assume a role in DEV - in order that they - // can invoke the tests - we don't know the name of the role yet (as it is built by CDK) - so we - // are quite permissive (it is limited to one non-prod account though) - rolePolicy: [ - new PolicyStatement({ - effect: Effect.ALLOW, - actions: ["sts:AssumeRole"], - resources: [`arn:aws:iam::${props.env.account}:role/*`], - }), - ], - }, - crossAccountKeys: true, - }); - - // Build Docker images for each workflow with a Wave; images hosted on build account and shared across staging and production - const tagDate = (moment(new Date())).format('YYYYMMDDHHmmSS') - // Collect the commit id (use 'latest' if running synth locally) - const commitId = (process.env.CODEBUILD_RESOLVED_SOURCE_VERSION || "latest").substring(0, 8) - const dockerTag = tagDate + "--" + commitId - - // Staging account - { - const stgStage = new ApplicationBuildStage(this, "BuildStg", { - env: AWS_ENV_STG, - envName: AWS_ENV_STG.name!, - envBuild: props.env, - dockerTag: dockerTag, - }); - - pipeline.addStage(stgStage); - } - - // Production account - { - const prodStage = new ApplicationBuildStage(this, "BuildProd", { - env: AWS_ENV_PROD, - envName: AWS_ENV_PROD.name!, - envBuild: props.env, - dockerTag: dockerTag, - }); - - pipeline.addStage(prodStage, { - pre: [new pipelines.ManualApprovalStep("PromoteToProd")], - }); - } - - // Build pipeline - pipeline.buildPipeline() - } -} diff --git a/deployment/nextflow-stack.ts b/deployment/nextflow-stack.ts deleted file mode 100644 index 15b1428..0000000 --- a/deployment/nextflow-stack.ts +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env node -import 'source-map-support/register'; - -import {App} from "aws-cdk-lib"; - -import {AWS_ENV_DEV, AWS_ENV_BUILD} from './settings-umccr'; -import {ApplicationStack} from "../application/application-stack"; -import {CodePipelineStack} from "./codepipeline-stack"; - - -const app = new App() - -const devApplicationStack = new ApplicationStack(app, 'NextflowApplicationDevStack', { - env: AWS_ENV_DEV, - envName: AWS_ENV_DEV.name!, - envBuild: AWS_ENV_DEV, -}); - -const buildStack = new CodePipelineStack(app, "NextflowBuildStack", { - env: AWS_ENV_BUILD -}) diff --git a/deployment/settings-umccr.ts b/deployment/settings-umccr.ts deleted file mode 100644 index 7764057..0000000 --- a/deployment/settings-umccr.ts +++ /dev/null @@ -1,30 +0,0 @@ -// TODO(SW): VPC, security group, etc - -import {Environment} from "aws-cdk-lib"; - -interface IEnvironmentExtra extends Environment { - name?: string; -} - -export const AWS_ENV_DEV: IEnvironmentExtra = { - name: "dev", - account: "843407916570", - region: "ap-southeast-2", -}; - -export const AWS_ENV_BUILD: IEnvironmentExtra = { - account: "383856791668", - region: "ap-southeast-2", -}; - -export const AWS_ENV_STG: IEnvironmentExtra = { - name: "stg", - account: "455634345446", - region: "ap-southeast-2", -}; - -export const AWS_ENV_PROD: IEnvironmentExtra = { - name: "prod", - account: "472057503814", - region: "ap-southeast-2", -}; diff --git a/lib/application-stack.ts b/lib/application-stack.ts new file mode 100644 index 0000000..453216f --- /dev/null +++ b/lib/application-stack.ts @@ -0,0 +1,376 @@ +import { Construct } from 'constructs' + +import * as path from 'path'; + +import * as batch from 'aws-cdk-lib/aws-batch'; +import * as cdk from 'aws-cdk-lib'; +import * as ec2 from 'aws-cdk-lib/aws-ec2'; +import * as ecr from 'aws-cdk-lib/aws-ecr'; +import * as ecrAssets from 'aws-cdk-lib/aws-ecr-assets'; +import * as ecs from 'aws-cdk-lib/aws-ecs'; +import * as iam from 'aws-cdk-lib/aws-iam'; +import * as s3 from 'aws-cdk-lib/aws-s3'; +import * as ssm from 'aws-cdk-lib/aws-ssm'; + +import * as ecrDeployment from 'cdk-ecr-deployment'; + +import * as settings from './settings'; + +export class ApplicationStack extends cdk.Stack { + constructor(scope: Construct, id: string, props: cdk.StackProps) { + super(scope, id, props); + + + // Collect existing resources + const vpc = ec2.Vpc.fromLookup(this, 'VPC', { + vpcName: settings.VPC_NAME, + }); + + const securityGroup = ec2.SecurityGroup.fromLookupByName( + this, + 'SecurityGroup', + settings.SECURITY_GROUP_NAME, + vpc, + ); + + + // Create Batch resources and co for Nextflow ***task*** jobs + const roleBatchInstanceTask = new iam.Role(this, 'BatchInstanceRoleTask', { + roleName: 'batch-instance-role-task', + assumedBy: new iam.CompositePrincipal( + new iam.ServicePrincipal('ec2.amazonaws.com'), + new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), + ), + managedPolicies: [ + iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), + iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceforEC2Role'), + ], + }); + + const launchTemplateTask = this.getLaunchTemplateTask({ + securityGroup: securityGroup, + }); + + const instanceTypesTask = settings.TASK_INSTANCE_TYPES + .map((typeStr) => { + return new ec2.InstanceType(typeStr); + }); + + const computeEnvironmentTask = new batch.ManagedEc2EcsComputeEnvironment(this, 'ComputeEnvironmentTask', { + allocationStrategy: batch.AllocationStrategy.BEST_FIT, + instanceRole: roleBatchInstanceTask, + instanceTypes: instanceTypesTask, + launchTemplate: launchTemplateTask, + maxvCpus: settings.MAX_TASK_CE_VCPUS, + securityGroups: [], + useOptimalInstanceClasses: false, + vpc: vpc, + vpcSubnets: { + subnetType: ec2.SubnetType.PUBLIC, + }, + }); + + const jobQueueTask = new batch.JobQueue(this, 'JobQueueTask', { + jobQueueName: 'oncoanalyser-tasks', + computeEnvironments: [ + { computeEnvironment: computeEnvironmentTask, order: 1 }, + ], + }); + + + // Create Batch resources and co for Nextflow ***pipeline*** jobs + const roleBatchInstancePipeline = new iam.Role(this, 'BatchInstanceRolePipeline', { + roleName: 'batch-instance-role-pipeline', + assumedBy: new iam.CompositePrincipal( + new iam.ServicePrincipal('ec2.amazonaws.com'), + new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), + ), + managedPolicies: [ + iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3ReadOnlyAccess'), + iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), + iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceforEC2Role'), + ], + }); + + // NOTE(SW): the below policies are mostly those described by the Nextflow documents, some minor changes have been + // made so that the access is less permissive + + new iam.Policy(this, 'PipelinePolicyBatchJobs', { + roles: [roleBatchInstancePipeline], + statements: [new iam.PolicyStatement({ + actions: [ + 'batch:CancelJob', + 'batch:SubmitJob', + 'batch:TagResource', + 'batch:TerminateJob', + ], + + resources: [ + jobQueueTask.jobQueueArn, + `arn:aws:batch:${this.region}:${this.account}:job-definition/nf-*` + ], + })], + }); + + new iam.Policy(this, 'PipelinePolicyBatchGeneral', { + roles: [roleBatchInstancePipeline], + statements: [new iam.PolicyStatement({ + actions: [ + 'batch:ListJobs', + 'batch:DescribeJobs', + 'batch:DescribeJobQueues', + 'batch:DescribeComputeEnvironments', + 'batch:RegisterJobDefinition', + 'batch:DescribeJobDefinitions', + ], + resources: ['*'] + })], + }); + + new iam.Policy(this, 'PipelinePolicyInstances', { + roles: [roleBatchInstancePipeline], + statements: [new iam.PolicyStatement({ + actions: [ + 'ecs:DescribeTasks', + 'ec2:DescribeInstances', + 'ec2:DescribeInstanceTypes', + 'ec2:DescribeInstanceAttribute', + 'ecs:DescribeContainerInstances', + 'ec2:DescribeInstanceStatus', + ], + resources: ['*'], + })], + }); + + new iam.Policy(this, 'PipelinePolicyECR', { + roles: [roleBatchInstancePipeline], + statements: [new iam.PolicyStatement({ + actions: [ + 'ecr:GetAuthorizationToken', + 'ecr:BatchCheckLayerAvailability', + 'ecr:GetDownloadUrlForLayer', + 'ecr:GetRepositoryPolicy', + 'ecr:DescribeRepositories', + 'ecr:ListImages', + 'ecr:DescribeImages', + 'ecr:BatchGetImage', + 'ecr:GetLifecyclePolicy', + 'ecr:GetLifecyclePolicyPreview', + 'ecr:ListTagsForResource', + 'ecr:DescribeImageScanFindings', + ], + resources: ['*'], + })], + }); + + new iam.Policy(this, 'PipelinePolicyCloudWatchLogEvents', { + roles: [roleBatchInstancePipeline], + statements: [new iam.PolicyStatement({ + actions: [ + 'logs:GetLogEvents', + ], + resources: [ + `arn:aws:logs:${this.region}:${this.account}:log-group:/aws/batch/job/:nf-*` + ], + })], + }); + + roleBatchInstancePipeline.attachInlinePolicy( + new iam.Policy(this, 'PipelinePolicyPassRole', { + statements: [ + new iam.PolicyStatement({ + actions: ['iam:PassRole'], + resources: [roleBatchInstanceTask.roleArn], + }) + ], + }) + ); + + const launchTemplatePipeline = this.getLaunchTemplatePipeline({ + securityGroup: securityGroup, + }); + + const instanceTypesPipeline = settings.PIPELINE_INSTANCE_TYPES + .map((typeStr) => { + return new ec2.InstanceType(typeStr); + }); + + const computeEnvironmentPipeline = new batch.ManagedEc2EcsComputeEnvironment(this, 'ComputeEnvironmentPipeline', { + allocationStrategy: batch.AllocationStrategy.BEST_FIT, + instanceRole: roleBatchInstancePipeline, + instanceTypes: instanceTypesPipeline, + launchTemplate: launchTemplatePipeline, + maxvCpus: settings.MAX_PIPELINE_CE_VCPUS, + securityGroups: [], + useOptimalInstanceClasses: false, + vpc: vpc, + vpcSubnets: { + subnetType: ec2.SubnetType.PUBLIC, + }, + }); + + const jobQueuePipeline = new batch.JobQueue(this, 'JobQueuePipeline', { + jobQueueName: 'oncoanalyser-pipeline', + computeEnvironments: [ + { computeEnvironment: computeEnvironmentPipeline, order: 1 }, + ], + }); + + + // Create Docker image and deploy + const dockerStack = new DockerImageBuildStack(this, 'DockerImageBuildStack', { + env: props.env, + }); + + // Bucket permissions + const nfBucket = s3.Bucket.fromBucketName(this, 'S3Bucket', + settings.S3_BUCKET_NAME, + ); + + nfBucket.grantRead(roleBatchInstancePipeline, `${settings.S3_BUCKET_INPUT_PREFIX}/*`); + nfBucket.grantRead(roleBatchInstanceTask, `${settings.S3_BUCKET_INPUT_PREFIX}/*`); + + nfBucket.grantRead(roleBatchInstancePipeline, `${settings.S3_BUCKET_REFDATA_PREFIX}/*`); + nfBucket.grantRead(roleBatchInstanceTask, `${settings.S3_BUCKET_REFDATA_PREFIX}/*`); + + nfBucket.grantReadWrite(roleBatchInstancePipeline, `${settings.S3_BUCKET_OUTPUT_PREFIX}/*`); + nfBucket.grantReadWrite(roleBatchInstanceTask, `${settings.S3_BUCKET_OUTPUT_PREFIX}/*`); + + // Create job definition for pipeline execution + const jobDefinition = new batch.EcsJobDefinition(this, 'JobDefinition', { + jobDefinitionName: 'oncoanalyser-job-definition', + container: new batch.EcsEc2ContainerDefinition(this, 'EcsEc2ContainerDefinition', { + cpu: 1, + image: dockerStack.image, + command: ['true'], + memory: cdk.Size.mebibytes(1000), + jobRole: roleBatchInstancePipeline, + }), + }); + + // Create SSM parameters + new ssm.StringParameter(this, 'SsmParameter-batch_job_queue_name', { + parameterName: '/oncoanalyser_stack/batch_job_queue_name', + stringValue: jobQueueTask.jobQueueName, + }); + + new ssm.StringParameter(this, 'SsmParameter-batch_instance_task_role_arn', { + parameterName: '/oncoanalyser_stack/batch_instance_task_role_arn', + stringValue: roleBatchInstanceTask.roleArn, + }); + + new ssm.StringParameter(this, 'SsmParameter-s3_bucket_name', { + parameterName: '/oncoanalyser_stack/s3_bucket_name', + stringValue: settings.S3_BUCKET_NAME, + }); + + new ssm.StringParameter(this, 'SsmParameter-s3_refdata_prefix', { + parameterName: '/oncoanalyser_stack/s3_refdata_prefix', + stringValue: settings.S3_BUCKET_REFDATA_PREFIX, + }); + } + + getLaunchTemplateTask(args: { + securityGroup: ec2.ISecurityGroup, + }) { + + const userData = ec2.UserData.custom( +`MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="==BOUNDARY==" + +--==BOUNDARY== +Content-Type: text/x-shellscript; charset="us-ascii" + +#!/bin/bash +mkdir -p /mnt/local_ephemeral/ +mkfs.ext4 /dev/nvme1n1 +mount /dev/nvme1n1 /mnt/local_ephemeral/ +chmod 777 /mnt/local_ephemeral/ + +--==BOUNDARY==--` + ); + + const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplateTask', { + launchTemplateName: 'oncoanalyser-task', + associatePublicIpAddress: true, + userData: userData, + securityGroup: args.securityGroup, + }); + + cdk.Tags.of(launchTemplate).add('Name', 'nextflow-task'); + return launchTemplate; + } + + getLaunchTemplatePipeline(args: { + securityGroup: ec2.ISecurityGroup, + }) { + + const userData = ec2.UserData.custom( +`MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="==BOUNDARY==" + +--==BOUNDARY== +Content-Type: text/cloud-config; charset="us-ascii" + +packages: + - btrfs-progs + - git + - jq + - lvm2 + - sed + - unzip + - wget + +--==BOUNDARY== +Content-Type: text/x-shellscript; charset="us-ascii" + +#!/bin/bash +curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip +unzip -q /tmp/awscliv2.zip -d /tmp/ + +/tmp/aws/install --install-dir /opt/awscliv2/aws-cli/ --bin-dir /opt/awscliv2/bin/ +ln -s /opt/awscliv2/bin/aws /usr/local/bin/ + +git clone https://github.com/awslabs/amazon-ebs-autoscale /tmp/amazon-ebs-autoscale/ +(cd /tmp/amazon-ebs-autoscale/ && git checkout 6db0c70) + +bash /tmp/amazon-ebs-autoscale/install.sh + +rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ +--==BOUNDARY==--` + ); + + const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplatePipeline', { + launchTemplateName: 'oncoanalyser-pipeline', + associatePublicIpAddress: true, + userData: userData, + securityGroup: args.securityGroup, + }); + + cdk.Tags.of(launchTemplate).add('Name', 'nextflow-pipeline'); + return launchTemplate; + } +} + + +export class DockerImageBuildStack extends cdk.Stack { + public readonly image: ecs.EcrImage; + + constructor(scope: Construct, id: string, props: cdk.StackProps) { + super(scope, id, props); + + const image = new ecrAssets.DockerImageAsset(this, 'DockerImage', { + directory: path.join(__dirname, 'resources'), + }); + + const dockerDestBase = `${props.env!.account}.dkr.ecr.${props.env!.region}.amazonaws.com`; + + new ecrDeployment.ECRDeployment(this, 'DeployDockerImage', { + src: new ecrDeployment.DockerImageName(image.imageUri), + dest: new ecrDeployment.DockerImageName(`${dockerDestBase}/${settings.ECR_REPO}:${settings.DOCKER_IMAGE_TAG}`), + }); + + const ecrRepository = ecr.Repository.fromRepositoryName(this, 'EcrRespository', settings.ECR_REPO); + this.image = ecs.EcrImage.fromEcrRepository(ecrRepository, settings.DOCKER_IMAGE_TAG); + } +} diff --git a/application/pipeline-stacks/oncoanalyser/Dockerfile b/lib/resources/Dockerfile similarity index 77% rename from application/pipeline-stacks/oncoanalyser/Dockerfile rename to lib/resources/Dockerfile index 209dc20..df8ec2b 100644 --- a/application/pipeline-stacks/oncoanalyser/Dockerfile +++ b/lib/resources/Dockerfile @@ -17,12 +17,8 @@ ARG DOCKER_CE_VERSION="23.0.1-1" ARG DOCKER_COMPOSE_VERSION="2.16.0-1" # Pipeline GH URL and branch/tag -# NOTE(SW): PIPELINE_GITHUB_REF must be provided as build argument -ARG PIPELINE_GITHUB_REF -ARG PIPELINE_GITHUB_REPO_URL="https://github.com/nf-core/oncoanalyser" - -RUN \ - test -n "${PIPELINE_GITHUB_REF}" || (echo "PIPELINE_GITHUB_REF must be set" && false) +ARG ONCOANALYSER_GIT_REF="pipeline_v6.0" +ARG ONCOANALYSER_GIT_URL="https://github.com/nf-core/oncoanalyser" # Configure Conda RUN \ @@ -91,20 +87,15 @@ RUN \ # Install pipeline software and config RUN \ mkdir --parents "/root/pipeline/software/" && \ - mkdir --parents "/root/pipeline/assets/" && \ - ( \ - cd "/root/pipeline/software/" && \ - git clone "${PIPELINE_GITHUB_REPO_URL}" oncoanalyser/ && \ - cd oncoanalyser && \ - git checkout ${PIPELINE_GITHUB_REF} \ - ) + git clone -b ${ONCOANALYSER_GIT_REF} ${ONCOANALYSER_GIT_URL} software/oncoanalyser/ + +RUN \ + mkdir --parents "/root/pipeline/other/" -COPY assets/nextflow_aws.template.config /root/pipeline/assets/ -COPY assets/run.sh /root/pipeline/assets/ -COPY assets/run-v2.sh /root/pipeline/assets/ +COPY nextflow_aws.template.config /root/pipeline/other/ +COPY run.sh /root/pipeline/other/ RUN \ - chmod +x "/root/pipeline/assets/run.sh" && \ - chmod +x "/root/pipeline/assets/run-v2.sh" + chmod +x "/root/pipeline/other/run.sh" WORKDIR /root/pipeline/ diff --git a/lib/resources/nextflow_aws.template.config b/lib/resources/nextflow_aws.template.config new file mode 100644 index 0000000..2a39187 --- /dev/null +++ b/lib/resources/nextflow_aws.template.config @@ -0,0 +1,254 @@ +plugins { + id 'nf-amazon' +} + +fusion { + enabled = true +} + +wave { + enabled = true +} + +aws { + batch { + jobRole = '__BATCH_INSTANCE_ROLE__' + volumes = '/mnt/local_ephemeral/:/tmp/' + } +} + +params { + + max_fastq_records = 250000000 + + genomes { + GRCh38_hmf { + fasta = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna' + fai = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai' + dict = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.dict' + img = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/bwa_index_image/0.7.17-r1188/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.img' + bwamem2_index = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/gridss_index/2.13.2/' + gridss_index = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/gridss_index/2.13.2/' + star_index = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/bwa-mem2_index/2.2.1/' + } + } + +} + +process { + executor = 'awsbatch' + scratch = false + + // NOTE(SW): using docker.runOptions in 23.10.01 causes `--network host` to be included twice, triggering an error in Docker + containerOptions = '--network host' + + resourceLabels = { + return [ + 'Stack': 'OncoanalyserStack', + 'JobName': task.process, + ] + } + + queue = '__BATCH_JOB_QUEUE_NAME__' + + withName: 'FASTP' { + cpus = 16 + memory = 30.GB + } + + withName: 'BWAMEM2_ALIGN' { + cpus = 32 + memory = 60.GB + } + + withName: 'REDUX' { + cpus = 16 + memory = 120.GB + } + + withName: 'STAR_ALIGN' { + cpus = 8 + memory = 60.GB + } + + withName: 'SAMTOOLS_SORT' { + cpus = 8 + memory = 30.GB + } + + withName: 'SAMBAMBA_MERGE' { + cpus = 8 + memory = 30.GB + } + + withName: 'GATK4_MARKDUPLICATES' { + cpus = 8 + memory = 30.GB + } + + withName: 'AMBER' { + cpus = 8 + memory = 30.GB + } + + withName: 'COBALT' { + cpus = 8 + memory = 30.GB + } + + withName: 'ESVEE_PREP' { + errorStrategy = 'retry' + maxRetries = 1 + + cpus = { task.attempt == 1 ? 16 : 8 } + memory = { task.attempt == 1 ? 60.GB : 122.GB } + } + + withName: 'ESVEE_PREP' { + errorStrategy = 'retry' + maxRetries = 1 + + time = 12.h + + cpus = 16 + memory = { task.attempt == 1 ? 30.GB : 122.GB } + } + + withName: 'ESVEE_CALL' { + cpus = 16 + memory = 30.GB + } + + withName: 'ESVEE_DEPTH_ANNOTATOR' { + errorStrategy = 'retry' + maxRetries = 1 + + cpus = { task.attempt == 1 ? 16 : 8 } + memory = { task.attempt == 1 ? 60.GB : 122.GB } + } + + withName: '.*:GRIPSS_FILTERING:(?:GERMLINE|SOMATIC)' { + cpus = 4 + memory = 30.GB + } + + withName: '.*:SAGE_CALLING:GERMLINE' { + cpus = 4 + memory = 30.GB + } + + withName: '.*:SAGE_CALLING:SOMATIC' { + cpus = 16 + memory = 30.GB + } + + withName: '.*:SAGE_APPEND:(?:GERMLINE|SOMATIC)' { + cpus = 2 + memory = 14.GB + } + + withName: '.*:PAVE_ANNOTATION:GERMLINE' { + cpus = 2 + memory = 14.GB + } + + // NOTE(SW): PAVE somatic uses a significant amount of memory, runtime is usually less than 5-10 minutes + + withName: '.*:PAVE_ANNOTATION:SOMATIC' { + cpus = 4 + memory = 30.GB + } + + withName: 'PURPLE' { + errorStrategy = 'retry' + maxRetries = 1 + + cpus = { task.attempt == 1 ? 4 : 8 } + memory = { task.attempt == 1 ? 30.GB : 60.GB } + } + + withName: '.*:LINX_ANNOTATION:(?:GERMLINE|SOMATIC)' { + cpus = 1 + memory = 12.GB + } + + withName: '.*:LINX_PLOTTING:VISUALISER' { + errorStrategy = 'retry' + maxRetries = 1 + + cpus = 8 + memory = 60.GB + } + + withName: '.*:LINX_PLOTTING:REPORT' { + cpus = 1 + memory = 12.GB + } + + withName: 'BAMTOOLS' { + cpus = 8 + memory = 30.GB + time = 24.h + } + + withName: 'CHORD' { + cpus = 1 + memory = 12.GB + } + + withName: 'LILAC' { + cpus = 4 + memory = 30.GB + } + + withName: '.*:LILAC_CALLING:EXTRACTCONTIG' { + cpus = 4 + memory = 30.GB + } + + withName: '.*:LILAC_CALLING:REALIGNREADS' { + cpus = 4 + memory = 30.GB + } + + withName: '.*:LILAC_CALLING:SLICEBAM' { + cpus = 4 + memory = 30.GB + } + + withName: 'SIGS' { + cpus = 1 + memory = 12.GB + } + + withName: 'VIRUSBREAKEND' { + cpus = 8 + memory = 60.GB + } + + withName: 'VIRUSINTERPRETER' { + cpus = 1 + memory = 12.GB + } + + withName: 'ISOFOX' { + cpus = 8 + memory = 30.GB + } + + withName: 'CUPPA' { + cpus = 1 + memory = 12.GB + } + + withName: 'ORANGE' { + cpus = 1 + memory = 12.GB + } + + withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { + cpus = 1 + memory = 12.GB + } + +} diff --git a/lib/resources/run.sh b/lib/resources/run.sh new file mode 100755 index 0000000..58555f6 --- /dev/null +++ b/lib/resources/run.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Get command line arguments +print_help_text() { + cat <&2 + exit 1 +fi + +# Download params file and get output directory base +aws s3 cp ${params_fp} params.json +output_base=$(jq -r .outdir params.json) + +# Prepare AWS configuration file +get_ssm_parameter_value() { + aws ssm get-parameter \ + --name "$1" \ + --output json | + jq --raw-output '.Parameter | .Value' +} + +sed \ + --regexp-extended \ + --expression \ + " + s#__BATCH_INSTANCE_ROLE__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_instance_task_role_arn)#g; + s#__S3_BUCKET_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_bucket_name)#g; + s#__S3_BUCKET_REFDATA_PREFIX__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_refdata_prefix)#g; + s#__BATCH_JOB_QUEUE_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_job_queue_name)#g; + " \ + /root/pipeline/other/nextflow_aws.template.config > aws.config + + +# Run oncoanalyser +upload_data() { + aws s3 sync \ + --no-progress \ + --no-follow-symlinks \ + --exclude='software/*' \ + --exclude='assets/*' \ + --exclude='work/*' \ + ./ ${output_base%/}/; +} + +trap upload_data EXIT + +nextflow run software/oncoanalyser/main.nf \ + -config aws.config \ + -params-file params.json \ + -profile docker \ + -work-dir ${output_base}/work/ \ + -ansi-log false \ + --monochrome_logs \ + +# Upload data then exit cleanly +upload_data +trap - EXIT diff --git a/lib/settings.ts b/lib/settings.ts new file mode 100644 index 0000000..6af3417 --- /dev/null +++ b/lib/settings.ts @@ -0,0 +1,19 @@ +export const AWS_ACCOUNT = '843407916570'; +export const AWS_REGION = 'ap-southeast-2'; + +export const VPC_NAME = 'main-vpc'; +export const SECURITY_GROUP_NAME = 'main-vpc-sg-outbound'; + +export const S3_BUCKET_NAME = 'umccr-temp-dev'; +export const S3_BUCKET_INPUT_PREFIX = 'inputs'; +export const S3_BUCKET_OUTPUT_PREFIX = 'outputs'; +export const S3_BUCKET_REFDATA_PREFIX = 'refdata'; + +export const PIPELINE_INSTANCE_TYPES = ['r6a.large']; +export const TASK_INSTANCE_TYPES = ['r6id.large']; + +export const ECR_REPO = 'oncoanalyser'; +export const DOCKER_IMAGE_TAG = 'latest-pmcc'; + +export const MAX_PIPELINE_CE_VCPUS = 64; +export const MAX_TASK_CE_VCPUS = 256; diff --git a/package-lock.json b/package-lock.json index 4c7e3ba..5384a07 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,31 +1,28 @@ { - "name": "nextflow-stack", + "name": "oncoanalyser-stack", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "nextflow-stack", + "name": "oncoanalyser-stack", "version": "0.1.0", "dependencies": { - "aws-cdk-lib": "^2.131.0", + "aws-cdk-lib": "2.177.0", "cdk-ecr-deployment": "^3.0.33", - "constructs": "^10.0.0", - "moment": "^2.29.4", - "source-map-support": "^0.5.21", - "util": "^0.12.5" + "constructs": "^10.0.0" }, "bin": { - "nextflow-stack": "bin/nextflow-stack.js" + "oncoanalyser-stack": "bin/oncoanalyser-stack.js" }, "devDependencies": { - "@types/jest": "^29.4.0", - "@types/node": "18.14.2", - "aws-cdk": "^2.131.0", - "jest": "^29.4.3", - "ts-jest": "^29.0.5", - "ts-node": "^10.9.1", - "typescript": "~4.9.5" + "@types/jest": "^29.5.14", + "@types/node": "22.7.9", + "aws-cdk": "2.177.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", + "typescript": "~5.6.3" } }, "node_modules/@ampproject/remapping": { @@ -42,134 +39,103 @@ } }, "node_modules/@aws-cdk/asset-awscli-v1": { - "version": "2.2.202", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.202.tgz", - "integrity": "sha512-JqlF0D4+EVugnG5dAsNZMqhu3HW7ehOXm5SDMxMbXNDMdsF0pxtQKNHRl52z1U9igsHmaFpUgSGjbhAJ+0JONg==" + "version": "2.2.225", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.225.tgz", + "integrity": "sha512-fMPfR7PwiwQZwAux9tQ5LRrFJJfl5Vp3kR8GMc+H/PA/wql9+w8mk5gs6SDpwBFpT7n3XkZ5H98Ns5+g7/WMIg==", + "license": "Apache-2.0" }, "node_modules/@aws-cdk/asset-kubectl-v20": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz", - "integrity": "sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg==" + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.4.tgz", + "integrity": "sha512-Ps2MkmjYgMyflagqQ4dgTElc7Vwpqj8spw8dQVFiSeaaMPsuDSNsPax3/HjuDuwqsmLdaCZc6umlxYLpL0kYDA==", + "license": "Apache-2.0" }, "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.0.1.tgz", - "integrity": "sha512-DDt4SLdLOwWCjGtltH4VCST7hpOI5DzieuhGZsBpZ+AgJdSI2GCjklCXm0GCTwJG/SolkL5dtQXyUKgg9luBDg==" + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz", + "integrity": "sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A==", + "license": "Apache-2.0" }, - "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, + "node_modules/@aws-cdk/cloud-assembly-schema": { + "version": "39.2.20", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-39.2.20.tgz", + "integrity": "sha512-RI7S8jphGA8mak154ElnEJQPNTTV4PZmA7jgqnBBHQGyOPJIXxtACubNQ5m4YgjpkK3UJHsWT+/cOAfM/Au/Wg==", + "bundleDependencies": [ + "jsonschema", + "semver" + ], + "license": "Apache-2.0", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "engines": { - "node": ">=6.9.0" + "jsonschema": "~1.4.1", + "semver": "^7.7.1" } }, - "node_modules/@babel/code-frame/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" - }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { + "version": "1.4.1", + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=4" + "node": "*" } }, - "node_modules/@babel/code-frame/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" + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { + "version": "7.7.1", + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/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/code-frame/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/code-frame/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/code-frame/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": ">=10" } }, - "node_modules/@babel/code-frame/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==", + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz", - "integrity": "sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz", - "integrity": "sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", "dev": true, + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.21.4", - "@babel/generator": "^7.21.4", - "@babel/helper-compilation-targets": "^7.21.4", - "@babel/helper-module-transforms": "^7.21.2", - "@babel/helpers": "^7.21.0", - "@babel/parser": "^7.21.4", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.4", - "@babel/types": "^7.21.4", - "convert-source-map": "^1.7.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -179,275 +145,135 @@ "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.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", + "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz", - "integrity": "sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==", + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", + "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.21.4", - "@babel/helper-validator-option": "^7.21.0", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz", - "integrity": "sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.21.4" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.21.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz", - "integrity": "sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==", + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", "dev": true, + "license": "MIT", "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.21.2", - "@babel/types": "^7.21.2" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "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" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", + "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", "dev": true, - "dependencies": { - "@babel/types": "^7.22.5" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz", - "integrity": "sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz", - "integrity": "sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==", - "dev": true, - "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.21.0", - "@babel/types": "^7.21.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", + "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9" }, "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==", + "node_modules/@babel/parser": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", + "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@babel/types": "^7.26.9" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.0.tgz", - "integrity": "sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==", - "dev": true, "bin": { "parser": "bin/babel-parser.js" }, @@ -516,12 +342,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz", - "integrity": "sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -618,12 +445,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.21.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz", - "integrity": "sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==", + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.20.2" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -633,33 +461,32 @@ } }, "node_modules/@babel/template": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz", - "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", + "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.26.9", + "@babel/types": "^7.26.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.0.tgz", - "integrity": "sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.24.0", - "@babel/types": "^7.24.0", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", + "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/types": "^7.26.9", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -668,14 +495,14 @@ } }, "node_modules/@babel/types": { - "version": "7.24.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz", - "integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", + "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -685,13 +512,15 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -704,6 +533,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -735,16 +565,17 @@ } }, "node_modules/@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -752,37 +583,38 @@ } }, "node_modules/@jest/core": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", - "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@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.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -799,89 +631,95 @@ } }, "node_modules/@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0" + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, + "license": "MIT", "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.4.3" + "jest-get-type": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", - "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -889,13 +727,13 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -913,25 +751,57 @@ } } }, + "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" }, @@ -940,13 +810,14 @@ } }, "node_modules/@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -955,14 +826,15 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", - "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.5.0", + "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -970,22 +842,23 @@ } }, "node_modules/@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "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.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -996,12 +869,13 @@ } }, "node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1013,14 +887,15 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -1036,10 +911,11 @@ } }, "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==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } @@ -1051,74 +927,77 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jridgewell/trace-mapping/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/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" }, "node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^2.0.0" + "@sinonjs/commons": "^3.0.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 + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "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 + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/babel__core": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", - "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -1128,38 +1007,42 @@ } }, "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==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, + "license": "MIT", "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==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "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==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, "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==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1189,26 +1072,25 @@ } }, "node_modules/@types/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-3Emr5VOl/aoBwnWcH/EFQvlSAmjV+XtV9GGu5mwdYew5vhQh0IUZx/60x0TzHDu09Bi7HMx10t/namdJw5QIcg==", + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, + "license": "MIT", "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, "node_modules/@types/node": { - "version": "18.14.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.14.2.tgz", - "integrity": "sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA==", - "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 + "version": "22.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.9.tgz", + "integrity": "sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.19.2" + } }, "node_modules/@types/stack-utils": { "version": "2.0.1", @@ -1232,10 +1114,11 @@ "dev": true }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1244,10 +1127,14 @@ } }, "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==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -1257,6 +1144,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1272,6 +1160,7 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1296,6 +1185,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1308,7 +1198,8 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "1.0.10", @@ -1319,25 +1210,19 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" }, "node_modules/aws-cdk": { - "version": "2.132.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.132.0.tgz", - "integrity": "sha512-C2j9iQqpl21YGuip02tIAAkgkDZNDDWeEoWfPcdXCJlQ9DVpYTJG24QxtY0rWflJ7Xkn+iAozdjlCrXSxYeAfA==", + "version": "2.177.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.177.0.tgz", + "integrity": "sha512-TiBoyE5wMB5q4jX1bELwkklgbs5eLY1Phjfnb4Mof0K9tOSRJ9UEq6xEamF0esMS+TuYU7a/ESTpmKX3iYqA3w==", "dev": true, + "license": "Apache-2.0", "bin": { "cdk": "bin/cdk" }, @@ -1349,9 +1234,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.132.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.132.0.tgz", - "integrity": "sha512-auztTTYy8j62MmRZNdM7Vd8eQ5eP3xLMhrrILhDZf3DiSDD0lyYL0hv98VD4XPkWGMQ8yOmo5nZ3s/zD7cnKlw==", + "version": "2.177.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.177.0.tgz", + "integrity": "sha512-nTnHAwjZaPJ5gfJjtzE/MyK6q0a66nWthoJl7l8srucRb+I30dczhbbXor6QCdVpJaTRAEliMOMq23aglsAQbg==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -1365,20 +1250,22 @@ "yaml", "mime-types" ], + "license": "Apache-2.0", "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.202", - "@aws-cdk/asset-kubectl-v20": "^2.1.2", - "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.1", + "@aws-cdk/asset-awscli-v1": "^2.2.208", + "@aws-cdk/asset-kubectl-v20": "^2.1.3", + "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0", + "@aws-cdk/cloud-assembly-schema": "^39.2.0", "@balena/dockerignore": "^1.0.2", "case": "1.6.3", "fs-extra": "^11.2.0", - "ignore": "^5.3.1", + "ignore": "^5.3.2", "jsonschema": "^1.4.1", "mime-types": "^2.1.35", "minimatch": "^3.1.2", "punycode": "^2.3.1", - "semver": "^7.6.0", - "table": "^6.8.1", + "semver": "^7.6.3", + "table": "^6.8.2", "yaml": "1.10.2" }, "engines": { @@ -1394,14 +1281,14 @@ "license": "Apache-2.0" }, "node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.12.0", + "version": "8.17.1", "inBundle": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -1491,6 +1378,11 @@ "inBundle": true, "license": "MIT" }, + "node_modules/aws-cdk-lib/node_modules/fast-uri": { + "version": "3.0.3", + "inBundle": true, + "license": "BSD-3-Clause" + }, "node_modules/aws-cdk-lib/node_modules/fs-extra": { "version": "11.2.0", "inBundle": true, @@ -1510,7 +1402,7 @@ "license": "ISC" }, "node_modules/aws-cdk-lib/node_modules/ignore": { - "version": "5.3.1", + "version": "5.3.2", "inBundle": true, "license": "MIT", "engines": { @@ -1554,17 +1446,6 @@ "inBundle": true, "license": "MIT" }, - "node_modules/aws-cdk-lib/node_modules/lru-cache": { - "version": "6.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/aws-cdk-lib/node_modules/mime-db": { "version": "1.52.0", "inBundle": true, @@ -1612,12 +1493,9 @@ } }, "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.6.0", + "version": "7.6.3", "inBundle": true, "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, "bin": { "semver": "bin/semver.js" }, @@ -1666,7 +1544,7 @@ } }, "node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.8.1", + "version": "6.8.2", "inBundle": true, "license": "BSD-3-Clause", "dependencies": { @@ -1688,19 +1566,6 @@ "node": ">= 10.0.0" } }, - "node_modules/aws-cdk-lib/node_modules/uri-js": { - "version": "4.4.1", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/yallist": { - "version": "4.0.0", - "inBundle": true, - "license": "ISC" - }, "node_modules/aws-cdk-lib/node_modules/yaml": { "version": "1.10.2", "inBundle": true, @@ -1710,15 +1575,16 @@ } }, "node_modules/babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/transform": "^29.5.0", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -1747,10 +1613,11 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -1785,12 +1652,13 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -1829,9 +1697,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -1841,13 +1709,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" @@ -1873,6 +1746,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -1880,31 +1754,15 @@ "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==" - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "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, + "license": "MIT", "engines": { "node": ">=6" } @@ -1919,9 +1777,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001479", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001479.tgz", - "integrity": "sha512-6nuRFim5dx8Eu2tO+KJ9PiBdPHs7WB5Hdf+klDcyefyEuOAcfhihIv7pS+JFknJLUiNQbm1AJYKm0c9QOlQS/Q==", + "version": "1.0.30001700", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", + "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", "dev": true, "funding": [ { @@ -1936,7 +1794,8 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/cdk-ecr-deployment": { "version": "3.0.33", @@ -2295,6 +2154,7 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -2315,16 +2175,18 @@ } }, "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 + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" }, "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, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2339,16 +2201,18 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "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 + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", @@ -2388,17 +2252,41 @@ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "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 + "dev": true, + "license": "MIT" }, "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==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2426,41 +2314,36 @@ } }, "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 + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "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, + "license": "MIT", "engines": { "node": ">=8" } @@ -2470,30 +2353,50 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/electron-to-chromium": { - "version": "1.4.365", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.365.tgz", - "integrity": "sha512-FRHZO+1tUNO4TOPXmlxetkoaIY8uwHzd1kKopK/Gx2SKn1L47wJXWD44wxP5CGRyyP98z/c8e1eBzJrgPeiBOg==", - "dev": true + "version": "1.5.104", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.104.tgz", + "integrity": "sha512-Us9M2L4cO/zMBqVkJtnj353nQhMju9slHm62NprKTmdF3HH8wYOtNvDFq/JB2+ZRoGLzdvYDiATlMHs98XBM1g==", + "dev": true, + "license": "ISC" }, "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, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2505,41 +2408,25 @@ "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 + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2571,6 +2458,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -2599,16 +2487,17 @@ } }, "node_modules/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -2625,10 +2514,44 @@ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -2654,14 +2577,6 @@ "node": ">=8" } }, - "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", @@ -2686,6 +2601,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2704,28 +2620,11 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "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", @@ -2740,6 +2639,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2772,39 +2672,17 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "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.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "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", @@ -2814,57 +2692,11 @@ "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/hasown": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -2876,22 +2708,25 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "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, + "license": "Apache-2.0", "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==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -2928,47 +2763,27 @@ "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" - } + "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-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" - } + "dev": true, + "license": "MIT" }, "node_modules/is-core-module": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz", - "integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, + "license": "MIT", "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2979,6 +2794,7 @@ "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, + "license": "MIT", "engines": { "node": ">=8" } @@ -2988,24 +2804,11 @@ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "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", @@ -3020,6 +2823,7 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -3027,25 +2831,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.0", @@ -3073,17 +2864,18 @@ } }, "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==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -3091,6 +2883,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -3101,10 +2894,11 @@ } }, "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==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -3113,16 +2907,36 @@ "node": ">=8" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.5.0" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" @@ -3140,12 +2954,14 @@ } }, "node_modules/jest-changed-files": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0" }, "engines": { @@ -3153,28 +2969,29 @@ } }, "node_modules/jest-circus": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -3184,22 +3001,22 @@ } }, "node_modules/jest-cli": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", - "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", + "create-jest": "^29.7.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "yargs": "^17.3.1" }, "bin": { @@ -3218,31 +3035,32 @@ } }, "node_modules/jest-config": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", - "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "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.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -3263,25 +3081,27 @@ } }, "node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -3290,62 +3110,66 @@ } }, "node_modules/jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", - "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@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.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -3357,46 +3181,49 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", - "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -3405,14 +3232,15 @@ } }, "node_modules/jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.5.0" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3423,6 +3251,7 @@ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -3436,26 +3265,28 @@ } }, "node_modules/jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -3465,43 +3296,45 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", - "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, + "license": "MIT", "dependencies": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", - "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -3514,37 +3347,39 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "node_modules/jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@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.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -3553,59 +3388,43 @@ } }, "node_modules/jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, + "license": "MIT", "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.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.5.0", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/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/jest-snapshot/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -3613,19 +3432,14 @@ "node": ">=10" } }, - "node_modules/jest-snapshot/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/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -3637,17 +3451,18 @@ } }, "node_modules/jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^29.5.0" + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3658,6 +3473,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3666,18 +3482,19 @@ } }, "node_modules/jest-watcher": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", - "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "string-length": "^4.0.1" }, "engines": { @@ -3685,13 +3502,14 @@ } }, "node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -3704,6 +3522,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -3718,7 +3537,8 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.1", @@ -3734,22 +3554,24 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "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 + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", @@ -3768,6 +3590,7 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3777,6 +3600,7 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3785,7 +3609,8 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "version": "5.0.0", @@ -3810,25 +3635,40 @@ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "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==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", @@ -3840,6 +3680,7 @@ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -3848,7 +3689,8 @@ "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 + "dev": true, + "license": "MIT" }, "node_modules/micromatch": { "version": "4.0.8", @@ -3868,6 +3710,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3884,14 +3727,6 @@ "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", @@ -3902,25 +3737,29 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "dev": true, + "license": "MIT" }, "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 + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", - "dev": true + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" }, "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, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3930,6 +3769,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -3951,6 +3791,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -3966,6 +3807,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -4017,6 +3859,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -4053,6 +3896,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4061,13 +3905,15 @@ "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 + "dev": true, + "license": "MIT" }, "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 + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", @@ -4095,6 +3941,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -4102,21 +3949,14 @@ "node": ">=8" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, "node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4141,6 +3981,7 @@ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -4150,9 +3991,9 @@ } }, "node_modules/pure-rand": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", - "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ { @@ -4163,7 +4004,8 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/react-is": { "version": "18.2.0", @@ -4176,23 +4018,28 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/resolve": { - "version": "1.22.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz", - "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, + "license": "MIT", "dependencies": { - "is-core-module": "^2.12.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -4202,6 +4049,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -4219,10 +4067,11 @@ } }, "node_modules/resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -4236,27 +4085,12 @@ "semver": "bin/semver.js" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -4269,6 +4103,7 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4283,7 +4118,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", @@ -4298,19 +4134,11 @@ "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.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "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", @@ -4334,6 +4162,7 @@ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -4347,6 +4176,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4361,6 +4191,7 @@ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -4373,6 +4204,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4382,6 +4214,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4391,6 +4224,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4415,6 +4249,7 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -4440,16 +4275,8 @@ "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" - } + "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { "version": "5.0.1", @@ -4464,28 +4291,31 @@ } }, "node_modules/ts-jest": { - "version": "29.1.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", - "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", + "version": "29.2.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.6.tgz", + "integrity": "sha512-yTNZVZqc8lSixm+QGVFcPe6+yj7+TWZwIesuOWvfcn4B9bz5x4NDzVCQQjOs7Hfouu36aEqfEbo9Qpo+gq8dDg==", "dev": true, + "license": "MIT", "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", + "bs-logger": "^0.2.6", + "ejs": "^3.1.10", + "fast-json-stable-stringify": "^2.1.0", "jest-util": "^29.0.0", "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.1", + "yargs-parser": "^21.1.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", @@ -4495,6 +4325,9 @@ "@babel/core": { "optional": true }, + "@jest/transform": { + "optional": true + }, "@jest/types": { "optional": true }, @@ -4506,26 +4339,12 @@ } } }, - "node_modules/ts-jest/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/ts-jest/node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -4533,17 +4352,12 @@ "node": ">=10" } }, - "node_modules/ts-jest/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/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -4587,6 +4401,7 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -4596,6 +4411,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -4604,22 +4420,30 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" + }, "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "dev": true, "funding": [ { @@ -4635,9 +4459,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "escalade": "^3.2.0", + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" @@ -4646,49 +4471,34 @@ "browserslist": ">= 4.21.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/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 + "dev": true, + "license": "MIT" }, "node_modules/v8-to-istanbul": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "license": "ISC", "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" + "convert-source-map": "^2.0.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, + "license": "Apache-2.0", "dependencies": { "makeerror": "1.0.12" } @@ -4698,6 +4508,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -4708,29 +4519,12 @@ "node": ">= 8" } }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "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, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4767,6 +4561,7 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -4775,13 +4570,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -4809,6 +4606,7 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4818,6 +4616,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index ad1a66f..de92ce0 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { - "name": "nextflow-stack", + "name": "oncoanalyser-stack", "version": "0.1.0", "author": "Stephen Watts", "bin": { - "nextflow-stack": "bin/nextflow-stack.js" + "oncoanalyser-stack": "bin/oncoanalyser-stack.js" }, "scripts": { "build": "tsc", @@ -12,20 +12,17 @@ "cdk": "cdk" }, "devDependencies": { - "@types/jest": "^29.4.0", - "@types/node": "18.14.2", - "aws-cdk": "^2.131.0", - "jest": "^29.4.3", - "ts-jest": "^29.0.5", - "ts-node": "^10.9.1", - "typescript": "~4.9.5" + "@types/jest": "^29.5.14", + "@types/node": "22.7.9", + "jest": "^29.7.0", + "ts-jest": "^29.2.5", + "aws-cdk": "2.177.0", + "ts-node": "^10.9.2", + "typescript": "~5.6.3" }, "dependencies": { - "aws-cdk-lib": "^2.131.0", "cdk-ecr-deployment": "^3.0.33", - "constructs": "^10.0.0", - "moment": "^2.29.4", - "source-map-support": "^0.5.21", - "util": "^0.12.5" + "aws-cdk-lib": "2.177.0", + "constructs": "^10.0.0" } } diff --git a/test/nextflow-stack.test.ts b/test/oncoanalyser-stack.test.ts similarity index 65% rename from test/nextflow-stack.test.ts rename to test/oncoanalyser-stack.test.ts index b97e528..df77870 100644 --- a/test/nextflow-stack.test.ts +++ b/test/oncoanalyser-stack.test.ts @@ -1,13 +1,13 @@ // import * as cdk from 'aws-cdk-lib'; // import { Template } from 'aws-cdk-lib/assertions'; -// import * as NextflowStack from '../lib/nextflow-stack-stack'; +// import * as OncoanalyserStack from '../lib/oncoanalyser-stack-stack'; // example test. To run these tests, uncomment this file along with the -// example resource in lib/nextflow-stack-stack.ts +// example resource in lib/oncoanalyser-stack-stack.ts test('SQS Queue Created', () => { // const app = new cdk.App(); // // WHEN -// const stack = new NextflowStack.NextflowStackStack(app, 'MyTestStack'); +// const stack = new OncoanalyserStack.OncoanalyserStackStack(app, 'MyTestStack'); // // THEN // const template = Template.fromStack(stack); diff --git a/tsconfig.json b/tsconfig.json index fc44377..aaa7dc5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,8 @@ "target": "ES2020", "module": "commonjs", "lib": [ - "es2020" + "es2020", + "dom" ], "declaration": true, "strict": true, From a4cd04d9d6f4d6323c909b1041a3f4ab21551202 Mon Sep 17 00:00:00 2001 From: Marko Malenic Date: Wed, 26 Feb 2025 15:33:46 +1100 Subject: [PATCH 02/11] refactor: remove account and region settings and convert to props (#11) * refactor: remove account and region settings, and convert to constructs and props * refactor: minimize changes and add settings.ts --- bin/oncoanalyser-stack.ts | 31 ++- bin/settings.ts | 27 ++ lib/application-stack.ts | 523 ++++++++++++++++++++++---------------- lib/settings.ts | 19 -- 4 files changed, 348 insertions(+), 252 deletions(-) create mode 100644 bin/settings.ts delete mode 100644 lib/settings.ts diff --git a/bin/oncoanalyser-stack.ts b/bin/oncoanalyser-stack.ts index f080e34..034a63f 100644 --- a/bin/oncoanalyser-stack.ts +++ b/bin/oncoanalyser-stack.ts @@ -1,15 +1,30 @@ #!/usr/bin/env node -import * as cdk from 'aws-cdk-lib'; +import * as cdk from "aws-cdk-lib"; -import * as settings from '../lib/settings'; -import * as stack from '../lib/application-stack'; +import * as ec2 from "aws-cdk-lib/aws-ec2"; +import { Construct } from "constructs"; +import { Oncoanalyser, OncoanalyserProps } from "../lib/application-stack"; +import {SETTINGS} from "./settings"; -const app = new cdk.App() -const oncoanalyserStack = new stack.ApplicationStack(app, 'OncoanalyserStack', { +export class OncoanalyserStack extends cdk.Stack { + constructor( + scope: Construct, + id: string, + settings: cdk.StackProps & OncoanalyserProps, + ) { + super(scope, id, settings); + + new Oncoanalyser(this, "Oncoanalyser", settings); + } +} + +const app = new cdk.App(); +const oncoanalyserStack = new OncoanalyserStack(app, "OncoanalyserStack", { env: { - account: settings.AWS_ACCOUNT, - region: settings.AWS_REGION, + account: process.env.CDK_DEFAULT_ACCOUNT, + region: process.env.CDK_DEFAULT_REGION, }, + ...SETTINGS, }); -cdk.Tags.of(oncoanalyserStack).add('Stack', 'OncoanalyserStack'); +cdk.Tags.of(oncoanalyserStack).add("Stack", "OncoanalyserStack"); diff --git a/bin/settings.ts b/bin/settings.ts new file mode 100644 index 0000000..f15714e --- /dev/null +++ b/bin/settings.ts @@ -0,0 +1,27 @@ +import { OncoanalyserProps } from "../lib/application-stack"; +import * as ec2 from "aws-cdk-lib/aws-ec2"; + +/** + * Configurable settings for the oncoanalyser construct. + */ +export const SETTINGS: OncoanalyserProps = { + bucket: { + bucket: "umccr-temp-dev", + inputPrefix: "inputs", + outputPrefix: "outputs", + refDataPrefix: "refdata", + }, + docker: { + ecrRepo: "oncoanalyser", + dockerImageTag: "latest-pmcc", + }, + maxPipelineCpus: 64, + maxTaskCpus: 256, + pipelineInstanceTypes: [ + ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), + ], + taskInstanceTypes: [ + ec2.InstanceType.of(ec2.InstanceClass.R6ID, ec2.InstanceSize.LARGE), + ], + vpc: undefined, +}; \ No newline at end of file diff --git a/lib/application-stack.ts b/lib/application-stack.ts index 453216f..bba2fda 100644 --- a/lib/application-stack.ts +++ b/lib/application-stack.ts @@ -1,49 +1,75 @@ -import { Construct } from 'constructs' - -import * as path from 'path'; - -import * as batch from 'aws-cdk-lib/aws-batch'; -import * as cdk from 'aws-cdk-lib'; -import * as ec2 from 'aws-cdk-lib/aws-ec2'; -import * as ecr from 'aws-cdk-lib/aws-ecr'; -import * as ecrAssets from 'aws-cdk-lib/aws-ecr-assets'; -import * as ecs from 'aws-cdk-lib/aws-ecs'; -import * as iam from 'aws-cdk-lib/aws-iam'; -import * as s3 from 'aws-cdk-lib/aws-s3'; -import * as ssm from 'aws-cdk-lib/aws-ssm'; - -import * as ecrDeployment from 'cdk-ecr-deployment'; - -import * as settings from './settings'; - -export class ApplicationStack extends cdk.Stack { - constructor(scope: Construct, id: string, props: cdk.StackProps) { - super(scope, id, props); - - - // Collect existing resources - const vpc = ec2.Vpc.fromLookup(this, 'VPC', { - vpcName: settings.VPC_NAME, - }); - - const securityGroup = ec2.SecurityGroup.fromLookupByName( - this, - 'SecurityGroup', - settings.SECURITY_GROUP_NAME, +import { Construct } from "constructs"; + +import * as path from "path"; + +import * as batch from "aws-cdk-lib/aws-batch"; +import * as cdk from "aws-cdk-lib"; +import * as ec2 from "aws-cdk-lib/aws-ec2"; +import * as ecr from "aws-cdk-lib/aws-ecr"; +import * as ecrAssets from "aws-cdk-lib/aws-ecr-assets"; +import * as ecs from "aws-cdk-lib/aws-ecs"; +import * as iam from "aws-cdk-lib/aws-iam"; +import * as s3 from "aws-cdk-lib/aws-s3"; +import * as ssm from "aws-cdk-lib/aws-ssm"; + +import * as ecrDeployment from "cdk-ecr-deployment"; +import { Aws } from "aws-cdk-lib"; + +export type BucketProps = { + bucket: string; + inputPrefix: string; + outputPrefix: string; + refDataPrefix: string; +}; + +export type OncoanalyserProps = { + vpc?: ec2.IVpc | string; + pipelineInstanceTypes: ec2.InstanceType[]; + taskInstanceTypes: ec2.InstanceType[]; + maxPipelineCpus: number; + maxTaskCpus: number; + bucket: BucketProps; + docker: DockerImageBuildProps; +}; + +export class Oncoanalyser extends Construct { + constructor(scope: Construct, id: string, props: OncoanalyserProps) { + super(scope, id); + + let vpc; + if (props.vpc === undefined) { + vpc = ec2.Vpc.fromLookup(this, "VPC", { + isDefault: true, + }); + } else if (typeof props.vpc == "string") { + vpc = ec2.Vpc.fromLookup(this, "VPC", { + vpcName: props.vpc, + }); + } else { + vpc = props.vpc; + } + + /// Allows all outbound connections. + const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", { + allowAllOutbound: true, + description: "oncoanalyser security group", vpc, - ); - + }); // Create Batch resources and co for Nextflow ***task*** jobs - const roleBatchInstanceTask = new iam.Role(this, 'BatchInstanceRoleTask', { - roleName: 'batch-instance-role-task', + const roleBatchInstanceTask = new iam.Role(this, "BatchInstanceRoleTask", { + roleName: "batch-instance-role-task", assumedBy: new iam.CompositePrincipal( - new iam.ServicePrincipal('ec2.amazonaws.com'), - new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), + new iam.ServicePrincipal("ec2.amazonaws.com"), + new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), ), managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), - iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceforEC2Role'), + iam.ManagedPolicy.fromAwsManagedPolicyName( + "AmazonSSMManagedInstanceCore", + ), + iam.ManagedPolicy.fromAwsManagedPolicyName( + "service-role/AmazonEC2ContainerServiceforEC2Role", + ), ], }); @@ -51,231 +77,264 @@ export class ApplicationStack extends cdk.Stack { securityGroup: securityGroup, }); - const instanceTypesTask = settings.TASK_INSTANCE_TYPES - .map((typeStr) => { - return new ec2.InstanceType(typeStr); - }); - - const computeEnvironmentTask = new batch.ManagedEc2EcsComputeEnvironment(this, 'ComputeEnvironmentTask', { - allocationStrategy: batch.AllocationStrategy.BEST_FIT, - instanceRole: roleBatchInstanceTask, - instanceTypes: instanceTypesTask, - launchTemplate: launchTemplateTask, - maxvCpus: settings.MAX_TASK_CE_VCPUS, - securityGroups: [], - useOptimalInstanceClasses: false, - vpc: vpc, - vpcSubnets: { - subnetType: ec2.SubnetType.PUBLIC, + const computeEnvironmentTask = new batch.ManagedEc2EcsComputeEnvironment( + this, + "ComputeEnvironmentTask", + { + allocationStrategy: batch.AllocationStrategy.BEST_FIT, + instanceRole: roleBatchInstanceTask, + instanceTypes: props.taskInstanceTypes, + launchTemplate: launchTemplateTask, + maxvCpus: props.maxTaskCpus, + securityGroups: [], + useOptimalInstanceClasses: false, + vpc: vpc, + vpcSubnets: { + subnetType: ec2.SubnetType.PUBLIC, + }, }, - }); + ); - const jobQueueTask = new batch.JobQueue(this, 'JobQueueTask', { - jobQueueName: 'oncoanalyser-tasks', + const jobQueueTask = new batch.JobQueue(this, "JobQueueTask", { + jobQueueName: "oncoanalyser-tasks", computeEnvironments: [ { computeEnvironment: computeEnvironmentTask, order: 1 }, ], }); - // Create Batch resources and co for Nextflow ***pipeline*** jobs - const roleBatchInstancePipeline = new iam.Role(this, 'BatchInstanceRolePipeline', { - roleName: 'batch-instance-role-pipeline', - assumedBy: new iam.CompositePrincipal( - new iam.ServicePrincipal('ec2.amazonaws.com'), - new iam.ServicePrincipal('ecs-tasks.amazonaws.com'), - ), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonS3ReadOnlyAccess'), - iam.ManagedPolicy.fromAwsManagedPolicyName('AmazonSSMManagedInstanceCore'), - iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AmazonEC2ContainerServiceforEC2Role'), - ], - }); + const roleBatchInstancePipeline = new iam.Role( + this, + "BatchInstanceRolePipeline", + { + roleName: "batch-instance-role-pipeline", + assumedBy: new iam.CompositePrincipal( + new iam.ServicePrincipal("ec2.amazonaws.com"), + new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), + ), + managedPolicies: [ + iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonS3ReadOnlyAccess"), + iam.ManagedPolicy.fromAwsManagedPolicyName( + "AmazonSSMManagedInstanceCore", + ), + iam.ManagedPolicy.fromAwsManagedPolicyName( + "service-role/AmazonEC2ContainerServiceforEC2Role", + ), + ], + }, + ); // NOTE(SW): the below policies are mostly those described by the Nextflow documents, some minor changes have been // made so that the access is less permissive - new iam.Policy(this, 'PipelinePolicyBatchJobs', { + new iam.Policy(this, "PipelinePolicyBatchJobs", { roles: [roleBatchInstancePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'batch:CancelJob', - 'batch:SubmitJob', - 'batch:TagResource', - 'batch:TerminateJob', - ], - - resources: [ - jobQueueTask.jobQueueArn, - `arn:aws:batch:${this.region}:${this.account}:job-definition/nf-*` - ], - })], + statements: [ + new iam.PolicyStatement({ + actions: [ + "batch:CancelJob", + "batch:SubmitJob", + "batch:TagResource", + "batch:TerminateJob", + ], + + resources: [ + jobQueueTask.jobQueueArn, + `arn:aws:batch:${Aws.REGION}:${Aws.ACCOUNT_ID}:job-definition/nf-*`, + ], + }), + ], }); - new iam.Policy(this, 'PipelinePolicyBatchGeneral', { + new iam.Policy(this, "PipelinePolicyBatchGeneral", { roles: [roleBatchInstancePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'batch:ListJobs', - 'batch:DescribeJobs', - 'batch:DescribeJobQueues', - 'batch:DescribeComputeEnvironments', - 'batch:RegisterJobDefinition', - 'batch:DescribeJobDefinitions', - ], - resources: ['*'] - })], + statements: [ + new iam.PolicyStatement({ + actions: [ + "batch:ListJobs", + "batch:DescribeJobs", + "batch:DescribeJobQueues", + "batch:DescribeComputeEnvironments", + "batch:RegisterJobDefinition", + "batch:DescribeJobDefinitions", + ], + resources: ["*"], + }), + ], }); - new iam.Policy(this, 'PipelinePolicyInstances', { + new iam.Policy(this, "PipelinePolicyInstances", { roles: [roleBatchInstancePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'ecs:DescribeTasks', - 'ec2:DescribeInstances', - 'ec2:DescribeInstanceTypes', - 'ec2:DescribeInstanceAttribute', - 'ecs:DescribeContainerInstances', - 'ec2:DescribeInstanceStatus', - ], - resources: ['*'], - })], + statements: [ + new iam.PolicyStatement({ + actions: [ + "ecs:DescribeTasks", + "ec2:DescribeInstances", + "ec2:DescribeInstanceTypes", + "ec2:DescribeInstanceAttribute", + "ecs:DescribeContainerInstances", + "ec2:DescribeInstanceStatus", + ], + resources: ["*"], + }), + ], }); - new iam.Policy(this, 'PipelinePolicyECR', { + new iam.Policy(this, "PipelinePolicyECR", { roles: [roleBatchInstancePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'ecr:GetAuthorizationToken', - 'ecr:BatchCheckLayerAvailability', - 'ecr:GetDownloadUrlForLayer', - 'ecr:GetRepositoryPolicy', - 'ecr:DescribeRepositories', - 'ecr:ListImages', - 'ecr:DescribeImages', - 'ecr:BatchGetImage', - 'ecr:GetLifecyclePolicy', - 'ecr:GetLifecyclePolicyPreview', - 'ecr:ListTagsForResource', - 'ecr:DescribeImageScanFindings', - ], - resources: ['*'], - })], + statements: [ + new iam.PolicyStatement({ + actions: [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:DescribeImages", + "ecr:BatchGetImage", + "ecr:GetLifecyclePolicy", + "ecr:GetLifecyclePolicyPreview", + "ecr:ListTagsForResource", + "ecr:DescribeImageScanFindings", + ], + resources: ["*"], + }), + ], }); - new iam.Policy(this, 'PipelinePolicyCloudWatchLogEvents', { + new iam.Policy(this, "PipelinePolicyCloudWatchLogEvents", { roles: [roleBatchInstancePipeline], - statements: [new iam.PolicyStatement({ - actions: [ - 'logs:GetLogEvents', - ], - resources: [ - `arn:aws:logs:${this.region}:${this.account}:log-group:/aws/batch/job/:nf-*` - ], - })], + statements: [ + new iam.PolicyStatement({ + actions: ["logs:GetLogEvents"], + resources: [ + `arn:aws:logs:${Aws.REGION}:${Aws.ACCOUNT_ID}:log-group:/aws/batch/job/:nf-*`, + ], + }), + ], }); roleBatchInstancePipeline.attachInlinePolicy( - new iam.Policy(this, 'PipelinePolicyPassRole', { + new iam.Policy(this, "PipelinePolicyPassRole", { statements: [ new iam.PolicyStatement({ - actions: ['iam:PassRole'], + actions: ["iam:PassRole"], resources: [roleBatchInstanceTask.roleArn], - }) + }), ], - }) + }), ); const launchTemplatePipeline = this.getLaunchTemplatePipeline({ securityGroup: securityGroup, }); - const instanceTypesPipeline = settings.PIPELINE_INSTANCE_TYPES - .map((typeStr) => { - return new ec2.InstanceType(typeStr); - }); - - const computeEnvironmentPipeline = new batch.ManagedEc2EcsComputeEnvironment(this, 'ComputeEnvironmentPipeline', { - allocationStrategy: batch.AllocationStrategy.BEST_FIT, - instanceRole: roleBatchInstancePipeline, - instanceTypes: instanceTypesPipeline, - launchTemplate: launchTemplatePipeline, - maxvCpus: settings.MAX_PIPELINE_CE_VCPUS, - securityGroups: [], - useOptimalInstanceClasses: false, - vpc: vpc, - vpcSubnets: { - subnetType: ec2.SubnetType.PUBLIC, - }, - }); - - const jobQueuePipeline = new batch.JobQueue(this, 'JobQueuePipeline', { - jobQueueName: 'oncoanalyser-pipeline', + const computeEnvironmentPipeline = + new batch.ManagedEc2EcsComputeEnvironment( + this, + "ComputeEnvironmentPipeline", + { + allocationStrategy: batch.AllocationStrategy.BEST_FIT, + instanceRole: roleBatchInstancePipeline, + instanceTypes: props.pipelineInstanceTypes, + launchTemplate: launchTemplatePipeline, + maxvCpus: props.maxPipelineCpus, + securityGroups: [], + useOptimalInstanceClasses: false, + vpc: vpc, + vpcSubnets: { + subnetType: ec2.SubnetType.PUBLIC, + }, + }, + ); + + const jobQueuePipeline = new batch.JobQueue(this, "JobQueuePipeline", { + jobQueueName: "oncoanalyser-pipeline", computeEnvironments: [ { computeEnvironment: computeEnvironmentPipeline, order: 1 }, ], }); - // Create Docker image and deploy - const dockerStack = new DockerImageBuildStack(this, 'DockerImageBuildStack', { - env: props.env, - }); + const docker = new DockerImageBuild( + this, + "DockerImageBuildStack", + props.docker, + ); // Bucket permissions - const nfBucket = s3.Bucket.fromBucketName(this, 'S3Bucket', - settings.S3_BUCKET_NAME, + const nfBucket = s3.Bucket.fromBucketName( + this, + "S3Bucket", + props.bucket.bucket, ); - nfBucket.grantRead(roleBatchInstancePipeline, `${settings.S3_BUCKET_INPUT_PREFIX}/*`); - nfBucket.grantRead(roleBatchInstanceTask, `${settings.S3_BUCKET_INPUT_PREFIX}/*`); + nfBucket.grantRead( + roleBatchInstancePipeline, + `${props.bucket.inputPrefix}/*`, + ); + nfBucket.grantRead(roleBatchInstanceTask, `${props.bucket.inputPrefix}/*`); - nfBucket.grantRead(roleBatchInstancePipeline, `${settings.S3_BUCKET_REFDATA_PREFIX}/*`); - nfBucket.grantRead(roleBatchInstanceTask, `${settings.S3_BUCKET_REFDATA_PREFIX}/*`); + nfBucket.grantRead( + roleBatchInstancePipeline, + `${props.bucket.refDataPrefix}/*`, + ); + nfBucket.grantRead( + roleBatchInstanceTask, + `${props.bucket.refDataPrefix}/*`, + ); - nfBucket.grantReadWrite(roleBatchInstancePipeline, `${settings.S3_BUCKET_OUTPUT_PREFIX}/*`); - nfBucket.grantReadWrite(roleBatchInstanceTask, `${settings.S3_BUCKET_OUTPUT_PREFIX}/*`); + nfBucket.grantReadWrite( + roleBatchInstancePipeline, + `${props.bucket.outputPrefix}/*`, + ); + nfBucket.grantReadWrite( + roleBatchInstanceTask, + `${props.bucket.outputPrefix}/*`, + ); // Create job definition for pipeline execution - const jobDefinition = new batch.EcsJobDefinition(this, 'JobDefinition', { - jobDefinitionName: 'oncoanalyser-job-definition', - container: new batch.EcsEc2ContainerDefinition(this, 'EcsEc2ContainerDefinition', { - cpu: 1, - image: dockerStack.image, - command: ['true'], - memory: cdk.Size.mebibytes(1000), - jobRole: roleBatchInstancePipeline, - }), + const jobDefinition = new batch.EcsJobDefinition(this, "JobDefinition", { + jobDefinitionName: "oncoanalyser-job-definition", + container: new batch.EcsEc2ContainerDefinition( + this, + "EcsEc2ContainerDefinition", + { + cpu: 1, + image: docker.image, + command: ["true"], + memory: cdk.Size.mebibytes(1000), + jobRole: roleBatchInstancePipeline, + }, + ), }); // Create SSM parameters - new ssm.StringParameter(this, 'SsmParameter-batch_job_queue_name', { - parameterName: '/oncoanalyser_stack/batch_job_queue_name', + new ssm.StringParameter(this, "SsmParameter-batch_job_queue_name", { + parameterName: "/oncoanalyser_stack/batch_job_queue_name", stringValue: jobQueueTask.jobQueueName, }); - new ssm.StringParameter(this, 'SsmParameter-batch_instance_task_role_arn', { - parameterName: '/oncoanalyser_stack/batch_instance_task_role_arn', + new ssm.StringParameter(this, "SsmParameter-batch_instance_task_role_arn", { + parameterName: "/oncoanalyser_stack/batch_instance_task_role_arn", stringValue: roleBatchInstanceTask.roleArn, }); - new ssm.StringParameter(this, 'SsmParameter-s3_bucket_name', { - parameterName: '/oncoanalyser_stack/s3_bucket_name', - stringValue: settings.S3_BUCKET_NAME, + new ssm.StringParameter(this, "SsmParameter-s3_bucket_name", { + parameterName: "/oncoanalyser_stack/s3_bucket_name", + stringValue: props.bucket.bucket, }); - new ssm.StringParameter(this, 'SsmParameter-s3_refdata_prefix', { - parameterName: '/oncoanalyser_stack/s3_refdata_prefix', - stringValue: settings.S3_BUCKET_REFDATA_PREFIX, + new ssm.StringParameter(this, "SsmParameter-s3_refdata_prefix", { + parameterName: "/oncoanalyser_stack/s3_refdata_prefix", + stringValue: props.bucket.refDataPrefix, }); } - getLaunchTemplateTask(args: { - securityGroup: ec2.ISecurityGroup, - }) { - + getLaunchTemplateTask(args: { securityGroup: ec2.ISecurityGroup }) { const userData = ec2.UserData.custom( -`MIME-Version: 1.0 + `MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="==BOUNDARY==" --==BOUNDARY== @@ -287,26 +346,23 @@ mkfs.ext4 /dev/nvme1n1 mount /dev/nvme1n1 /mnt/local_ephemeral/ chmod 777 /mnt/local_ephemeral/ ---==BOUNDARY==--` +--==BOUNDARY==--`, ); - const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplateTask', { - launchTemplateName: 'oncoanalyser-task', + const launchTemplate = new ec2.LaunchTemplate(this, "LaunchTemplateTask", { + launchTemplateName: "oncoanalyser-task", associatePublicIpAddress: true, userData: userData, securityGroup: args.securityGroup, }); - cdk.Tags.of(launchTemplate).add('Name', 'nextflow-task'); + cdk.Tags.of(launchTemplate).add("Name", "nextflow-task"); return launchTemplate; } - getLaunchTemplatePipeline(args: { - securityGroup: ec2.ISecurityGroup, - }) { - + getLaunchTemplatePipeline(args: { securityGroup: ec2.ISecurityGroup }) { const userData = ec2.UserData.custom( -`MIME-Version: 1.0 + `MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="==BOUNDARY==" --==BOUNDARY== @@ -337,40 +393,57 @@ git clone https://github.com/awslabs/amazon-ebs-autoscale /tmp/amazon-ebs-autosc bash /tmp/amazon-ebs-autoscale/install.sh rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ ---==BOUNDARY==--` +--==BOUNDARY==--`, ); - const launchTemplate = new ec2.LaunchTemplate(this, 'LaunchTemplatePipeline', { - launchTemplateName: 'oncoanalyser-pipeline', - associatePublicIpAddress: true, - userData: userData, - securityGroup: args.securityGroup, - }); + const launchTemplate = new ec2.LaunchTemplate( + this, + "LaunchTemplatePipeline", + { + launchTemplateName: "oncoanalyser-pipeline", + associatePublicIpAddress: true, + userData: userData, + securityGroup: args.securityGroup, + }, + ); - cdk.Tags.of(launchTemplate).add('Name', 'nextflow-pipeline'); + cdk.Tags.of(launchTemplate).add("Name", "nextflow-pipeline"); return launchTemplate; } } +export type DockerImageBuildProps = { + ecrRepo: string; + dockerImageTag: string; +}; -export class DockerImageBuildStack extends cdk.Stack { +export class DockerImageBuild extends Construct { public readonly image: ecs.EcrImage; - constructor(scope: Construct, id: string, props: cdk.StackProps) { - super(scope, id, props); + constructor(scope: Construct, id: string, props: DockerImageBuildProps) { + super(scope, id); - const image = new ecrAssets.DockerImageAsset(this, 'DockerImage', { - directory: path.join(__dirname, 'resources'), + const image = new ecrAssets.DockerImageAsset(this, "DockerImage", { + directory: path.join(__dirname, "resources"), }); - const dockerDestBase = `${props.env!.account}.dkr.ecr.${props.env!.region}.amazonaws.com`; + const dockerDestBase = `${Aws.ACCOUNT_ID}.dkr.ecr.${Aws.REGION}.amazonaws.com`; - new ecrDeployment.ECRDeployment(this, 'DeployDockerImage', { + new ecrDeployment.ECRDeployment(this, "DeployDockerImage", { src: new ecrDeployment.DockerImageName(image.imageUri), - dest: new ecrDeployment.DockerImageName(`${dockerDestBase}/${settings.ECR_REPO}:${settings.DOCKER_IMAGE_TAG}`), + dest: new ecrDeployment.DockerImageName( + `${dockerDestBase}/${props.ecrRepo}:${props.dockerImageTag}`, + ), }); - const ecrRepository = ecr.Repository.fromRepositoryName(this, 'EcrRespository', settings.ECR_REPO); - this.image = ecs.EcrImage.fromEcrRepository(ecrRepository, settings.DOCKER_IMAGE_TAG); + const ecrRepository = ecr.Repository.fromRepositoryName( + this, + "EcrRespository", + props.ecrRepo, + ); + this.image = ecs.EcrImage.fromEcrRepository( + ecrRepository, + props.dockerImageTag, + ); } } diff --git a/lib/settings.ts b/lib/settings.ts deleted file mode 100644 index 6af3417..0000000 --- a/lib/settings.ts +++ /dev/null @@ -1,19 +0,0 @@ -export const AWS_ACCOUNT = '843407916570'; -export const AWS_REGION = 'ap-southeast-2'; - -export const VPC_NAME = 'main-vpc'; -export const SECURITY_GROUP_NAME = 'main-vpc-sg-outbound'; - -export const S3_BUCKET_NAME = 'umccr-temp-dev'; -export const S3_BUCKET_INPUT_PREFIX = 'inputs'; -export const S3_BUCKET_OUTPUT_PREFIX = 'outputs'; -export const S3_BUCKET_REFDATA_PREFIX = 'refdata'; - -export const PIPELINE_INSTANCE_TYPES = ['r6a.large']; -export const TASK_INSTANCE_TYPES = ['r6id.large']; - -export const ECR_REPO = 'oncoanalyser'; -export const DOCKER_IMAGE_TAG = 'latest-pmcc'; - -export const MAX_PIPELINE_CE_VCPUS = 64; -export const MAX_TASK_CE_VCPUS = 256; From 9cf401aa8d50aa679b26d74d33ed5fb99af3ff33 Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Wed, 26 Feb 2025 16:04:23 +1100 Subject: [PATCH 03/11] Feature/better passing config (#13) * Ignore idea * Moved created the config up to the CDK level * Force x86 platform build --- .gitignore | 1 + lib/application-stack.ts | 59 +++++++++++----------- lib/resources/nextflow_aws.template.config | 20 ++++---- lib/resources/run.sh | 35 +++++++------ package-lock.json | 59 +++++++++++++++++++++- package.json | 7 +-- 6 files changed, 120 insertions(+), 61 deletions(-) diff --git a/.gitignore b/.gitignore index 932eb1a..dff5ab5 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ TODO.*md NOTES.md prev/ temp/ +/.idea/ diff --git a/lib/application-stack.ts b/lib/application-stack.ts index bba2fda..e5be9c3 100644 --- a/lib/application-stack.ts +++ b/lib/application-stack.ts @@ -1,6 +1,7 @@ import { Construct } from "constructs"; import * as path from "path"; +import * as fs from "fs"; import * as batch from "aws-cdk-lib/aws-batch"; import * as cdk from "aws-cdk-lib"; @@ -12,8 +13,13 @@ import * as iam from "aws-cdk-lib/aws-iam"; import * as s3 from "aws-cdk-lib/aws-s3"; import * as ssm from "aws-cdk-lib/aws-ssm"; +import * as Handlebars from "handlebars"; import * as ecrDeployment from "cdk-ecr-deployment"; import { Aws } from "aws-cdk-lib"; +import {ContainerImage} from "aws-cdk-lib/aws-ecs"; +import {Platform} from "aws-cdk-lib/aws-ecr-assets"; + +const BATCH_VOLUME_MOUNT_POINT = "/mnt/local_ephemeral/" export type BucketProps = { bucket: string; @@ -257,11 +263,10 @@ export class Oncoanalyser extends Construct { }); // Create Docker image and deploy - const docker = new DockerImageBuild( - this, - "DockerImageBuildStack", - props.docker, - ); + const image = new ecrAssets.DockerImageAsset(this, 'DockerImage', { + directory: path.join(__dirname, 'resources'), + platform: Platform.LINUX_AMD64 + }); // Bucket permissions const nfBucket = s3.Bucket.fromBucketName( @@ -294,6 +299,18 @@ export class Oncoanalyser extends Construct { `${props.bucket.outputPrefix}/*`, ); + const nextflowConfigTemplate = fs.readFileSync(path.join(__dirname, "resources/nextflow_aws.template.config"), { encoding: "utf-8"}); + + const nextflowConfigTemplateCompiled = Handlebars.compile(nextflowConfigTemplate); + + const nextflowConfig = nextflowConfigTemplateCompiled({ + BATCH_INSTANCE_TASK_ROLE_ARN: roleBatchInstanceTask.roleArn, + BATCH_JOB_QUEUE_NAME: jobQueueTask.jobQueueName, + S3_BUCKET_NAME: props.bucket.bucket, + S3_BUCKET_REFDATA_PREFIX: props.bucket.refDataPrefix, + BATCH_VOLUME_MOUNT_POINT: BATCH_VOLUME_MOUNT_POINT + }, { }); + // Create job definition for pipeline execution const jobDefinition = new batch.EcsJobDefinition(this, "JobDefinition", { jobDefinitionName: "oncoanalyser-job-definition", @@ -302,34 +319,16 @@ export class Oncoanalyser extends Construct { "EcsEc2ContainerDefinition", { cpu: 1, - image: docker.image, + image: ContainerImage.fromDockerImageAsset(image), command: ["true"], memory: cdk.Size.mebibytes(1000), jobRole: roleBatchInstancePipeline, + environment: { + ONCOANALYSER_NEXTFLOW_CONFIG_BASE64: Buffer.from(nextflowConfig).toString('base64') + } }, ), }); - - // Create SSM parameters - new ssm.StringParameter(this, "SsmParameter-batch_job_queue_name", { - parameterName: "/oncoanalyser_stack/batch_job_queue_name", - stringValue: jobQueueTask.jobQueueName, - }); - - new ssm.StringParameter(this, "SsmParameter-batch_instance_task_role_arn", { - parameterName: "/oncoanalyser_stack/batch_instance_task_role_arn", - stringValue: roleBatchInstanceTask.roleArn, - }); - - new ssm.StringParameter(this, "SsmParameter-s3_bucket_name", { - parameterName: "/oncoanalyser_stack/s3_bucket_name", - stringValue: props.bucket.bucket, - }); - - new ssm.StringParameter(this, "SsmParameter-s3_refdata_prefix", { - parameterName: "/oncoanalyser_stack/s3_refdata_prefix", - stringValue: props.bucket.refDataPrefix, - }); } getLaunchTemplateTask(args: { securityGroup: ec2.ISecurityGroup }) { @@ -341,10 +340,10 @@ Content-Type: multipart/mixed; boundary="==BOUNDARY==" Content-Type: text/x-shellscript; charset="us-ascii" #!/bin/bash -mkdir -p /mnt/local_ephemeral/ +mkdir -p ${BATCH_VOLUME_MOUNT_POINT} mkfs.ext4 /dev/nvme1n1 -mount /dev/nvme1n1 /mnt/local_ephemeral/ -chmod 777 /mnt/local_ephemeral/ +mount /dev/nvme1n1 ${BATCH_VOLUME_MOUNT_POINT} +chmod 777 ${BATCH_VOLUME_MOUNT_POINT} --==BOUNDARY==--`, ); diff --git a/lib/resources/nextflow_aws.template.config b/lib/resources/nextflow_aws.template.config index 2a39187..c97e747 100644 --- a/lib/resources/nextflow_aws.template.config +++ b/lib/resources/nextflow_aws.template.config @@ -12,8 +12,8 @@ wave { aws { batch { - jobRole = '__BATCH_INSTANCE_ROLE__' - volumes = '/mnt/local_ephemeral/:/tmp/' + jobRole = '{{BATCH_INSTANCE_TASK_ROLE_ARN}}' + volumes = '{{BATCH_VOLUME_MOUNT_POINT}}:/tmp/' } } @@ -23,13 +23,13 @@ params { genomes { GRCh38_hmf { - fasta = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna' - fai = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai' - dict = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.dict' - img = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/bwa_index_image/0.7.17-r1188/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.img' - bwamem2_index = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/gridss_index/2.13.2/' - gridss_index = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/gridss_index/2.13.2/' - star_index = 's3://__S3_BUCKET_NAME__/__S3_BUCKET_REFDATA_PREFIX__/genomes/GRCh38_hmf/bwa-mem2_index/2.2.1/' + fasta = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna' + fai = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai' + dict = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.dict' + img = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/bwa_index_image/0.7.17-r1188/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.img' + bwamem2_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/gridss_index/2.13.2/' + gridss_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/gridss_index/2.13.2/' + star_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/bwa-mem2_index/2.2.1/' } } @@ -49,7 +49,7 @@ process { ] } - queue = '__BATCH_JOB_QUEUE_NAME__' + queue = '{{BATCH_JOB_QUEUE_NAME}}' withName: 'FASTP' { cpus = 16 diff --git a/lib/resources/run.sh b/lib/resources/run.sh index 58555f6..ceeaf54 100755 --- a/lib/resources/run.sh +++ b/lib/resources/run.sh @@ -35,24 +35,27 @@ fi aws s3 cp ${params_fp} params.json output_base=$(jq -r .outdir params.json) +# Nextflow config comes from an environment variable prepared by the deploying CDK +echo $ONCOANALYSER_NEXTFLOW_CONFIG_BASE64 | base64 --decode > aws.config + # Prepare AWS configuration file -get_ssm_parameter_value() { - aws ssm get-parameter \ - --name "$1" \ - --output json | - jq --raw-output '.Parameter | .Value' -} +#get_ssm_parameter_value() { +# aws ssm get-parameter \ +# --name "$1" \ +# --output json | +# jq --raw-output '.Parameter | .Value' +#} -sed \ - --regexp-extended \ - --expression \ - " - s#__BATCH_INSTANCE_ROLE__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_instance_task_role_arn)#g; - s#__S3_BUCKET_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_bucket_name)#g; - s#__S3_BUCKET_REFDATA_PREFIX__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_refdata_prefix)#g; - s#__BATCH_JOB_QUEUE_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_job_queue_name)#g; - " \ - /root/pipeline/other/nextflow_aws.template.config > aws.config +#sed \ +# --regexp-extended \ +# --expression \ +# " +# s#__BATCH_INSTANCE_ROLE__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_instance_task_role_arn)#g; +# s#__S3_BUCKET_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_bucket_name)#g; +# s#__S3_BUCKET_REFDATA_PREFIX__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_refdata_prefix)#g; +# s#__BATCH_JOB_QUEUE_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_job_queue_name)#g; +# " \ +# /root/pipeline/other/nextflow_aws.template.config > aws.config # Run oncoanalyser diff --git a/package-lock.json b/package-lock.json index 5384a07..740b097 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,8 @@ "dependencies": { "aws-cdk-lib": "2.177.0", "cdk-ecr-deployment": "^3.0.33", - "constructs": "^10.0.0" + "constructs": "^10.0.0", + "handlebars": "^4.7.8" }, "bin": { "oncoanalyser-stack": "bin/oncoanalyser-stack.js" @@ -2683,6 +2684,27 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3727,6 +3749,15 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3740,6 +3771,12 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -4134,7 +4171,6 @@ "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" } @@ -4433,6 +4469,19 @@ "node": ">=14.17" } }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -4519,6 +4568,12 @@ "node": ">= 8" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index de92ce0..b4688da 100644 --- a/package.json +++ b/package.json @@ -14,15 +14,16 @@ "devDependencies": { "@types/jest": "^29.5.14", "@types/node": "22.7.9", + "aws-cdk": "2.177.0", "jest": "^29.7.0", "ts-jest": "^29.2.5", - "aws-cdk": "2.177.0", "ts-node": "^10.9.2", "typescript": "~5.6.3" }, "dependencies": { - "cdk-ecr-deployment": "^3.0.33", "aws-cdk-lib": "2.177.0", - "constructs": "^10.0.0" + "cdk-ecr-deployment": "^3.0.33", + "constructs": "^10.0.0", + "handlebars": "^4.7.8" } } From c9af0b69c72d74e846bb1465048e9c5f5347496d Mon Sep 17 00:00:00 2001 From: Stephen Watts Date: Thu, 27 Feb 2025 12:47:08 +1100 Subject: [PATCH 04/11] Apply bug fixes for oncoanalyser and enable stub runs (#16) * Apply bug fixes, clean-up, expose stub mode * Avoid changing quotation mark types once again --- .bumpversion.cfg | 9 --- bin/settings.ts | 9 ++- lib/application-stack.ts | 4 +- lib/resources/Dockerfile | 92 +++------------------- lib/resources/nextflow_aws.template.config | 25 +++++- lib/resources/run.sh | 68 +++++++--------- 6 files changed, 70 insertions(+), 137 deletions(-) delete mode 100644 .bumpversion.cfg diff --git a/.bumpversion.cfg b/.bumpversion.cfg deleted file mode 100644 index 9eab70e..0000000 --- a/.bumpversion.cfg +++ /dev/null @@ -1,9 +0,0 @@ -[bumpversion] -current_version = 0.1.0 -commit = True -tag = False -parse = (?P\d+)\.(?P\d+)\.(?P[a-z0-9+]+) - -[bumpversion:file:package.json] -search = "version": "{current_version}" -replace = "version": "{new_version}" diff --git a/bin/settings.ts b/bin/settings.ts index f15714e..ce59ae5 100644 --- a/bin/settings.ts +++ b/bin/settings.ts @@ -15,8 +15,11 @@ export const SETTINGS: OncoanalyserProps = { ecrRepo: "oncoanalyser", dockerImageTag: "latest-pmcc", }, - maxPipelineCpus: 64, - maxTaskCpus: 256, + // NOTE(SW): temporary reduction for testing during dev + //maxPipelineCpus: 64, + //maxTaskCpus: 256, + maxPipelineCpus: 2, + maxTaskCpus: 4, pipelineInstanceTypes: [ ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), ], @@ -24,4 +27,4 @@ export const SETTINGS: OncoanalyserProps = { ec2.InstanceType.of(ec2.InstanceClass.R6ID, ec2.InstanceSize.LARGE), ], vpc: undefined, -}; \ No newline at end of file +}; diff --git a/lib/application-stack.ts b/lib/application-stack.ts index e5be9c3..e8a59b2 100644 --- a/lib/application-stack.ts +++ b/lib/application-stack.ts @@ -355,7 +355,7 @@ chmod 777 ${BATCH_VOLUME_MOUNT_POINT} securityGroup: args.securityGroup, }); - cdk.Tags.of(launchTemplate).add("Name", "nextflow-task"); + cdk.Tags.of(launchTemplate).add("Name", "oncoanalyser-task"); return launchTemplate; } @@ -406,7 +406,7 @@ rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ }, ); - cdk.Tags.of(launchTemplate).add("Name", "nextflow-pipeline"); + cdk.Tags.of(launchTemplate).add("Name", "oncoanalyser-pipeline"); return launchTemplate; } } diff --git a/lib/resources/Dockerfile b/lib/resources/Dockerfile index df8ec2b..092f102 100644 --- a/lib/resources/Dockerfile +++ b/lib/resources/Dockerfile @@ -1,29 +1,7 @@ -FROM docker.io/continuumio/miniconda3:23.10.0-1 - -# Set package versions and other info -# Generic -ARG JQ_VERSION="1.7.1" -ARG NEXTFLOW_VERSION="24.04.4" -ARG OPENJDK_VERSION="17.0.10" -ARG PARALLEL_VERSION="20230322" -ARG RCLONE_VERSION="1.62.2" - -# Docker packages -ARG DEBIAN_PLATFORM_VERSION="debian.11~bullseye_amd64" -ARG CONTAINERD_IO_VERSION="1.6.18-1" -ARG DOCKER_BUILDX_VERSION="0.10.2-1" -ARG DOCKER_CE_CLI_VERSION="23.0.1-1" -ARG DOCKER_CE_VERSION="23.0.1-1" -ARG DOCKER_COMPOSE_VERSION="2.16.0-1" - -# Pipeline GH URL and branch/tag -ARG ONCOANALYSER_GIT_REF="pipeline_v6.0" -ARG ONCOANALYSER_GIT_URL="https://github.com/nf-core/oncoanalyser" +FROM docker.io/continuumio/miniconda3:25.1.1-2 # Configure Conda RUN \ - conda install --yes \ - conda-libmamba-solver && \ echo '\ solver: libmamba\n\ channels:\n\ @@ -32,70 +10,20 @@ channels:\n\ - defaults\n\ ' > ~/.condarc -# Install software with apt -RUN \ - apt update -y -q && \ - apt install -y -q \ - curl \ - unzip \ - wget && \ - apt clean -y -q - -# Install jq 1.7 custom -RUN wget \ - --output-document /usr/bin/jq \ - "https://github.com/jqlang/jq/releases/download/jq-${JQ_VERSION}/jq-linux-amd64" && \ - chmod +x /usr/bin/jq - -# Install packages with Conda -RUN \ - conda install --yes \ - "nextflow ==${NEXTFLOW_VERSION}" \ - "openjdk ==${OPENJDK_VERSION}" \ - "parallel ==${PARALLEL_VERSION}" \ - "rclone ==${RCLONE_VERSION}" && \ - conda clean --all --force-pkgs-dirs --yes - -# Install AWS CLIv2 -RUN \ - wget --quiet 'https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip' \ - --output-document "awscli.zip" && \ - unzip -qq "awscli.zip" && \ - ./aws/install && \ - rm --force --recursive aws/ "awscli.zip" - -# Install Docker; used to run additional containers via the host service +# Install dependencies RUN \ - mkdir -p "docker_install_temp/" && \ - ( \ - cd "docker_install_temp/" && \ - parallel --jobs 0 " \ - wget \ - --quiet \ - 'https://download.docker.com/linux/debian/dists/bullseye/pool/stable/amd64/{}' \ - " ::: \ - "containerd.io_${CONTAINERD_IO_VERSION}_amd64.deb" \ - "docker-ce_${DOCKER_CE_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-ce-cli_${DOCKER_CE_CLI_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-buildx-plugin_${DOCKER_BUILDX_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" \ - "docker-compose-plugin_${DOCKER_COMPOSE_VERSION}~${DEBIAN_PLATFORM_VERSION}.deb" && \ - apt install --yes --quiet $(pwd)/*.deb \ - ) && \ - rm --force --recursive "docker_install_temp/" && \ - apt clean --yes --quiet + conda install -y \ + 'awscli=2.24.12' \ + 'jq=1.7.1' \ + 'nextflow=24.10.4' \ + 'openjdk=17.0.10' && \ + conda clean -yaf -# Install pipeline software and config +# Install oncoanalyser and config template RUN \ - mkdir --parents "/root/pipeline/software/" && \ - git clone -b ${ONCOANALYSER_GIT_REF} ${ONCOANALYSER_GIT_URL} software/oncoanalyser/ - -RUN \ - mkdir --parents "/root/pipeline/other/" + git clone -b aws-stack-testing https://github.com/scwatts/oncoanalyser-aws-stack-testing /root/pipeline/software/oncoanalyser/ COPY nextflow_aws.template.config /root/pipeline/other/ COPY run.sh /root/pipeline/other/ -RUN \ - chmod +x "/root/pipeline/other/run.sh" - WORKDIR /root/pipeline/ diff --git a/lib/resources/nextflow_aws.template.config b/lib/resources/nextflow_aws.template.config index c97e747..2197cd3 100644 --- a/lib/resources/nextflow_aws.template.config +++ b/lib/resources/nextflow_aws.template.config @@ -19,18 +19,30 @@ aws { params { - max_fastq_records = 250000000 + max_fastq_records = 0 genomes { + + GRCh37_hmf { + fasta = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh37_hmf/Homo_sapiens.GRCh37.GATK.illumina.fasta' + fai = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh37_hmf/samtools_index/1.16/Homo_sapiens.GRCh37.GATK.illumina.fasta.fai' + dict = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh37_hmf/samtools_index/1.16/Homo_sapiens.GRCh37.GATK.illumina.fasta.dict' + img = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh37_hmf/bwa_index_image/0.7.17-r1188/Homo_sapiens.GRCh37.GATK.illumina.fasta.img' + bwamem2_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh37_hmf/bwa-mem2_index/2.2.1/' + gridss_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh37_hmf/gridss_index/2.13.2/' + star_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh37_hmf/star_index/gencode_19/2.7.3a/' + } + GRCh38_hmf { fasta = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna' fai = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.fai' dict = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/samtools_index/1.16/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.dict' img = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/bwa_index_image/0.7.17-r1188/GCA_000001405.15_GRCh38_no_alt_analysis_set.fna.img' - bwamem2_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/gridss_index/2.13.2/' + bwamem2_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/bwa-mem2_index/2.2.1/' gridss_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/gridss_index/2.13.2/' - star_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/bwa-mem2_index/2.2.1/' + star_index = 's3://{{S3_BUCKET_NAME}}/{{S3_BUCKET_REFDATA_PREFIX}}/genomes/GRCh38_hmf/star_index/gencode_38/2.7.3a/' } + } } @@ -49,6 +61,13 @@ process { ] } + // NOTE(SW): to be used in dev only + resourceLimits = [ + cpus: 4, + memory: 30.GB, + time: 6.hour, + ] + queue = '{{BATCH_JOB_QUEUE_NAME}}' withName: 'FASTP' { diff --git a/lib/resources/run.sh b/lib/resources/run.sh index ceeaf54..b15945a 100755 --- a/lib/resources/run.sh +++ b/lib/resources/run.sh @@ -8,27 +8,32 @@ Usage example: run.sh --params_fp FILE Options: --params_fp FILE S3 path to the Nextflow JSON params file + --stub_run Enable stub run EOF } while [ $# -gt 0 ]; do - case "$1" in + case ${1} in --params_fp) - params_fp="$2" - shift 1 + params_fp=${2}; + shift 1; + ;; + + --stub_run) + stub_run='true'; ;; -h|--help) - print_help_text - exit 0 - esac - shift + print_help_text; + exit 0; + esac; + shift; done -if [[ -z "${params_fp:-}" ]]; then - print_help_text - echo -e "\nERROR: --params_fp is required" 1>&2 - exit 1 +if [[ -z ${params_fp:-} ]]; then + print_help_text; + echo -e '\nERROR: --params_fp is required' 1>&2; + exit 1; fi # Download params file and get output directory base @@ -38,25 +43,11 @@ output_base=$(jq -r .outdir params.json) # Nextflow config comes from an environment variable prepared by the deploying CDK echo $ONCOANALYSER_NEXTFLOW_CONFIG_BASE64 | base64 --decode > aws.config -# Prepare AWS configuration file -#get_ssm_parameter_value() { -# aws ssm get-parameter \ -# --name "$1" \ -# --output json | -# jq --raw-output '.Parameter | .Value' -#} - -#sed \ -# --regexp-extended \ -# --expression \ -# " -# s#__BATCH_INSTANCE_ROLE__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_instance_task_role_arn)#g; -# s#__S3_BUCKET_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_bucket_name)#g; -# s#__S3_BUCKET_REFDATA_PREFIX__#$(get_ssm_parameter_value /oncoanalyser_stack/s3_refdata_prefix)#g; -# s#__BATCH_JOB_QUEUE_NAME__#$(get_ssm_parameter_value /oncoanalyser_stack/batch_job_queue_name)#g; -# " \ -# /root/pipeline/other/nextflow_aws.template.config > aws.config - +# Set additional Nextflow arguments +nf_arg_stub='' +if [[ -n ${stub_run:-} ]]; then + nf_arg_stub='-stub' +fi # Run oncoanalyser upload_data() { @@ -64,20 +55,21 @@ upload_data() { --no-progress \ --no-follow-symlinks \ --exclude='software/*' \ - --exclude='assets/*' \ + --exclude='other/*' \ --exclude='work/*' \ - ./ ${output_base%/}/; + ./ ${output_base%/}/ } trap upload_data EXIT nextflow run software/oncoanalyser/main.nf \ - -config aws.config \ - -params-file params.json \ - -profile docker \ - -work-dir ${output_base}/work/ \ - -ansi-log false \ - --monochrome_logs \ + -config aws.config \ + -params-file params.json \ + -profile docker \ + ${nf_arg_stub} \ + -work-dir ${output_base%/}/work/ \ + -ansi-log false \ + --monochrome_logs \ # Upload data then exit cleanly upload_data From 9c8c639787086f0d9650210bcaeba4b00bfc16c9 Mon Sep 17 00:00:00 2001 From: Quentin Clayssen <37511834+qclayssen@users.noreply.github.com> Date: Thu, 27 Feb 2025 15:49:32 +1100 Subject: [PATCH 05/11] Transition to EBS Auto-Scaling and Remove Fusion for Batch Jobs (#15) * change volumes to use scratch for autoscalling instead of fusion * remove BATCH_VOLUME_MOUNT_POINT use for fusion, and use only one launchTemplate use by "pipeline and task" * Add two different launchTemplate with name in parameters * Add tag as variable for template name * change EBS-Only storage instead NVMe SSD since we not using Fusion * linting --- bin/settings.ts | 2 +- lib/application-stack.ts | 50 +++++----------------- lib/resources/nextflow_aws.template.config | 12 +----- 3 files changed, 14 insertions(+), 50 deletions(-) diff --git a/bin/settings.ts b/bin/settings.ts index ce59ae5..dd72a38 100644 --- a/bin/settings.ts +++ b/bin/settings.ts @@ -24,7 +24,7 @@ export const SETTINGS: OncoanalyserProps = { ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), ], taskInstanceTypes: [ - ec2.InstanceType.of(ec2.InstanceClass.R6ID, ec2.InstanceSize.LARGE), + ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.LARGE), ], vpc: undefined, }; diff --git a/lib/application-stack.ts b/lib/application-stack.ts index e8a59b2..3442662 100644 --- a/lib/application-stack.ts +++ b/lib/application-stack.ts @@ -19,8 +19,6 @@ import { Aws } from "aws-cdk-lib"; import {ContainerImage} from "aws-cdk-lib/aws-ecs"; import {Platform} from "aws-cdk-lib/aws-ecr-assets"; -const BATCH_VOLUME_MOUNT_POINT = "/mnt/local_ephemeral/" - export type BucketProps = { bucket: string; inputPrefix: string; @@ -79,8 +77,9 @@ export class Oncoanalyser extends Construct { ], }); - const launchTemplateTask = this.getLaunchTemplateTask({ - securityGroup: securityGroup, + const launchTemplateTask = this.getLaunchTemplate({ + securityGroup: securityGroup, + launchTemplateName: "oncoanalyser-task" }); const computeEnvironmentTask = new batch.ManagedEc2EcsComputeEnvironment( @@ -232,8 +231,9 @@ export class Oncoanalyser extends Construct { }), ); - const launchTemplatePipeline = this.getLaunchTemplatePipeline({ + const launchTemplatePipeline = this.getLaunchTemplate({ securityGroup: securityGroup, + launchTemplateName: "oncoanalyser-pipeline" }); const computeEnvironmentPipeline = @@ -308,7 +308,6 @@ export class Oncoanalyser extends Construct { BATCH_JOB_QUEUE_NAME: jobQueueTask.jobQueueName, S3_BUCKET_NAME: props.bucket.bucket, S3_BUCKET_REFDATA_PREFIX: props.bucket.refDataPrefix, - BATCH_VOLUME_MOUNT_POINT: BATCH_VOLUME_MOUNT_POINT }, { }); // Create job definition for pipeline execution @@ -331,35 +330,7 @@ export class Oncoanalyser extends Construct { }); } - getLaunchTemplateTask(args: { securityGroup: ec2.ISecurityGroup }) { - const userData = ec2.UserData.custom( - `MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="==BOUNDARY==" - ---==BOUNDARY== -Content-Type: text/x-shellscript; charset="us-ascii" - -#!/bin/bash -mkdir -p ${BATCH_VOLUME_MOUNT_POINT} -mkfs.ext4 /dev/nvme1n1 -mount /dev/nvme1n1 ${BATCH_VOLUME_MOUNT_POINT} -chmod 777 ${BATCH_VOLUME_MOUNT_POINT} - ---==BOUNDARY==--`, - ); - - const launchTemplate = new ec2.LaunchTemplate(this, "LaunchTemplateTask", { - launchTemplateName: "oncoanalyser-task", - associatePublicIpAddress: true, - userData: userData, - securityGroup: args.securityGroup, - }); - - cdk.Tags.of(launchTemplate).add("Name", "oncoanalyser-task"); - return launchTemplate; - } - - getLaunchTemplatePipeline(args: { securityGroup: ec2.ISecurityGroup }) { + getLaunchTemplate(args: { securityGroup: ec2.ISecurityGroup; launchTemplateName?: string }) { const userData = ec2.UserData.custom( `MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="==BOUNDARY==" @@ -394,19 +365,20 @@ bash /tmp/amazon-ebs-autoscale/install.sh rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ --==BOUNDARY==--`, ); - + const ltName = args.launchTemplateName ?? "oncoanalyser"; + const constructId = `LaunchTemplate-${ltName}`; const launchTemplate = new ec2.LaunchTemplate( this, - "LaunchTemplatePipeline", + constructId, { - launchTemplateName: "oncoanalyser-pipeline", + launchTemplateName: ltName, associatePublicIpAddress: true, userData: userData, securityGroup: args.securityGroup, }, ); - cdk.Tags.of(launchTemplate).add("Name", "oncoanalyser-pipeline"); + cdk.Tags.of(launchTemplate).add("Name", ltName); return launchTemplate; } } diff --git a/lib/resources/nextflow_aws.template.config b/lib/resources/nextflow_aws.template.config index 2197cd3..2a221ca 100644 --- a/lib/resources/nextflow_aws.template.config +++ b/lib/resources/nextflow_aws.template.config @@ -2,18 +2,10 @@ plugins { id 'nf-amazon' } -fusion { - enabled = true -} - -wave { - enabled = true -} - aws { batch { jobRole = '{{BATCH_INSTANCE_TASK_ROLE_ARN}}' - volumes = '{{BATCH_VOLUME_MOUNT_POINT}}:/tmp/' + volumes = '/scratch' } } @@ -49,7 +41,7 @@ params { process { executor = 'awsbatch' - scratch = false + scratch = '/scratch/' // NOTE(SW): using docker.runOptions in 23.10.01 causes `--network host` to be included twice, triggering an error in Docker containerOptions = '--network host' From 47a10338f44b8a64b6cd727477f7d6881fad5591 Mon Sep 17 00:00:00 2001 From: Quentin Clayssen <37511834+qclayssen@users.noreply.github.com> Date: Fri, 28 Feb 2025 10:35:06 +1100 Subject: [PATCH 06/11] add cli path in aws.path config (#21) --- lib/resources/nextflow_aws.template.config | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/resources/nextflow_aws.template.config b/lib/resources/nextflow_aws.template.config index 2a221ca..d8d35a3 100644 --- a/lib/resources/nextflow_aws.template.config +++ b/lib/resources/nextflow_aws.template.config @@ -7,6 +7,9 @@ aws { jobRole = '{{BATCH_INSTANCE_TASK_ROLE_ARN}}' volumes = '/scratch' } + batch { + cliPath = '/usr/local/bin/aws' + } } params { From 841486fdcc879ead49bd5380dde7b48930fe3619 Mon Sep 17 00:00:00 2001 From: Marko Malenic Date: Fri, 28 Feb 2025 10:35:22 +1100 Subject: [PATCH 07/11] feat: install plugins inside docker file (#19) --- bin/oncoanalyser-stack.ts | 2 +- bin/settings.ts | 44 +++++++++++----------- lib/application-stack.ts | 15 +++++--- lib/dependencies.ts | 8 ++++ lib/resources/Dockerfile | 5 +++ lib/resources/nextflow_aws.template.config | 4 +- 6 files changed, 49 insertions(+), 29 deletions(-) create mode 100644 lib/dependencies.ts diff --git a/bin/oncoanalyser-stack.ts b/bin/oncoanalyser-stack.ts index 034a63f..2c25cc7 100644 --- a/bin/oncoanalyser-stack.ts +++ b/bin/oncoanalyser-stack.ts @@ -4,7 +4,7 @@ import * as cdk from "aws-cdk-lib"; import * as ec2 from "aws-cdk-lib/aws-ec2"; import { Construct } from "constructs"; import { Oncoanalyser, OncoanalyserProps } from "../lib/application-stack"; -import {SETTINGS} from "./settings"; +import { SETTINGS } from "./settings"; export class OncoanalyserStack extends cdk.Stack { constructor( diff --git a/bin/settings.ts b/bin/settings.ts index dd72a38..e85e814 100644 --- a/bin/settings.ts +++ b/bin/settings.ts @@ -5,26 +5,26 @@ import * as ec2 from "aws-cdk-lib/aws-ec2"; * Configurable settings for the oncoanalyser construct. */ export const SETTINGS: OncoanalyserProps = { - bucket: { - bucket: "umccr-temp-dev", - inputPrefix: "inputs", - outputPrefix: "outputs", - refDataPrefix: "refdata", - }, - docker: { - ecrRepo: "oncoanalyser", - dockerImageTag: "latest-pmcc", - }, - // NOTE(SW): temporary reduction for testing during dev - //maxPipelineCpus: 64, - //maxTaskCpus: 256, - maxPipelineCpus: 2, - maxTaskCpus: 4, - pipelineInstanceTypes: [ - ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), - ], - taskInstanceTypes: [ - ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.LARGE), - ], - vpc: undefined, + bucket: { + bucket: "umccr-temp-dev", + inputPrefix: "inputs", + outputPrefix: "outputs", + refDataPrefix: "refdata", + }, + docker: { + ecrRepo: "oncoanalyser", + dockerImageTag: "latest-pmcc", + }, + // NOTE(SW): temporary reduction for testing during dev + //maxPipelineCpus: 64, + //maxTaskCpus: 256, + maxPipelineCpus: 2, + maxTaskCpus: 4, + pipelineInstanceTypes: [ + ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), + ], + taskInstanceTypes: [ + ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.LARGE), + ], + vpc: undefined, }; diff --git a/lib/application-stack.ts b/lib/application-stack.ts index 3442662..336a633 100644 --- a/lib/application-stack.ts +++ b/lib/application-stack.ts @@ -16,8 +16,9 @@ import * as ssm from "aws-cdk-lib/aws-ssm"; import * as Handlebars from "handlebars"; import * as ecrDeployment from "cdk-ecr-deployment"; import { Aws } from "aws-cdk-lib"; -import {ContainerImage} from "aws-cdk-lib/aws-ecs"; -import {Platform} from "aws-cdk-lib/aws-ecr-assets"; +import { ContainerImage } from "aws-cdk-lib/aws-ecs"; +import { Platform } from "aws-cdk-lib/aws-ecr-assets"; +import { NEXTFLOW_PLUGINS } from "./dependencies"; export type BucketProps = { bucket: string; @@ -78,8 +79,8 @@ export class Oncoanalyser extends Construct { }); const launchTemplateTask = this.getLaunchTemplate({ - securityGroup: securityGroup, - launchTemplateName: "oncoanalyser-task" + securityGroup: securityGroup, + launchTemplateName: "oncoanalyser-task" }); const computeEnvironmentTask = new batch.ManagedEc2EcsComputeEnvironment( @@ -265,7 +266,10 @@ export class Oncoanalyser extends Construct { // Create Docker image and deploy const image = new ecrAssets.DockerImageAsset(this, 'DockerImage', { directory: path.join(__dirname, 'resources'), - platform: Platform.LINUX_AMD64 + platform: Platform.LINUX_AMD64, + buildArgs: { + NEXTFLOW_PLUGINS: NEXTFLOW_PLUGINS.join(",") + } }); // Bucket permissions @@ -308,6 +312,7 @@ export class Oncoanalyser extends Construct { BATCH_JOB_QUEUE_NAME: jobQueueTask.jobQueueName, S3_BUCKET_NAME: props.bucket.bucket, S3_BUCKET_REFDATA_PREFIX: props.bucket.refDataPrefix, + PLUGINS: NEXTFLOW_PLUGINS, }, { }); // Create job definition for pipeline execution diff --git a/lib/dependencies.ts b/lib/dependencies.ts new file mode 100644 index 0000000..ba3faab --- /dev/null +++ b/lib/dependencies.ts @@ -0,0 +1,8 @@ +/** + * Define the required Nextflow plugins. + */ +export const NEXTFLOW_PLUGINS: string[] = [ + "nf-amazon@2.9.2", + "nf-schema@2.3.0", + "nf-wave@1.7.4", +]; diff --git a/lib/resources/Dockerfile b/lib/resources/Dockerfile index 092f102..f16ab7c 100644 --- a/lib/resources/Dockerfile +++ b/lib/resources/Dockerfile @@ -1,5 +1,7 @@ FROM docker.io/continuumio/miniconda3:25.1.1-2 +ARG NEXTFLOW_PLUGINS + # Configure Conda RUN \ echo '\ @@ -19,6 +21,9 @@ RUN \ 'openjdk=17.0.10' && \ conda clean -yaf +# Install plugins for offline usage +RUN nextflow plugin install ${NEXTFLOW_PLUGINS} + # Install oncoanalyser and config template RUN \ git clone -b aws-stack-testing https://github.com/scwatts/oncoanalyser-aws-stack-testing /root/pipeline/software/oncoanalyser/ diff --git a/lib/resources/nextflow_aws.template.config b/lib/resources/nextflow_aws.template.config index d8d35a3..e5d4eb8 100644 --- a/lib/resources/nextflow_aws.template.config +++ b/lib/resources/nextflow_aws.template.config @@ -1,5 +1,7 @@ plugins { - id 'nf-amazon' + {{#PLUGINS}} + id '{{.}}' + {{/PLUGINS}} } aws { From 3516d437c5338296f63735f42e1a2c196f9dcbe2 Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Fri, 28 Feb 2025 15:20:45 +1100 Subject: [PATCH 08/11] First cut of CDK control of process images (#14) * First cut of CDK control of process images * Removed base64 encoding as it hides the CDK tokenisation techniques * Started filling in docker assets used by the pipeline * All stages have a docker reference (unfilled for some) - but will error until I correctly fill them in * Pivot to using appconfig * Fix task machine size Use container not queue in config * Pretty code Split into config construct * Switched off ECR bundling * Added plugins in anticipation of a merged feature * Use plugins correctly * add more docker image uri * Correct aws cli path * prettier --------- Co-authored-by: qclayssen --- bin/settings.ts | 6 +- lib/application-stack.ts | 129 +++------ lib/nextflow-config-construct.ts | 307 +++++++++++++++++++++ lib/resources/Dockerfile | 1 + lib/resources/nextflow_aws.template.config | 40 ++- lib/resources/run.sh | 14 +- lib/task_docker_images/Dockerfile | 4 + package-lock.json | 17 ++ package.json | 1 + 9 files changed, 427 insertions(+), 92 deletions(-) create mode 100644 lib/nextflow-config-construct.ts create mode 100644 lib/task_docker_images/Dockerfile diff --git a/bin/settings.ts b/bin/settings.ts index e85e814..a497e6a 100644 --- a/bin/settings.ts +++ b/bin/settings.ts @@ -11,10 +11,6 @@ export const SETTINGS: OncoanalyserProps = { outputPrefix: "outputs", refDataPrefix: "refdata", }, - docker: { - ecrRepo: "oncoanalyser", - dockerImageTag: "latest-pmcc", - }, // NOTE(SW): temporary reduction for testing during dev //maxPipelineCpus: 64, //maxTaskCpus: 256, @@ -24,7 +20,7 @@ export const SETTINGS: OncoanalyserProps = { ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), ], taskInstanceTypes: [ - ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.LARGE), + ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.XLARGE), ], vpc: undefined, }; diff --git a/lib/application-stack.ts b/lib/application-stack.ts index 336a633..744f5ac 100644 --- a/lib/application-stack.ts +++ b/lib/application-stack.ts @@ -1,23 +1,17 @@ import { Construct } from "constructs"; import * as path from "path"; -import * as fs from "fs"; import * as batch from "aws-cdk-lib/aws-batch"; import * as cdk from "aws-cdk-lib"; +import { Aws } from "aws-cdk-lib"; import * as ec2 from "aws-cdk-lib/aws-ec2"; -import * as ecr from "aws-cdk-lib/aws-ecr"; import * as ecrAssets from "aws-cdk-lib/aws-ecr-assets"; -import * as ecs from "aws-cdk-lib/aws-ecs"; +import { Platform } from "aws-cdk-lib/aws-ecr-assets"; +import { ContainerImage } from "aws-cdk-lib/aws-ecs"; import * as iam from "aws-cdk-lib/aws-iam"; import * as s3 from "aws-cdk-lib/aws-s3"; -import * as ssm from "aws-cdk-lib/aws-ssm"; - -import * as Handlebars from "handlebars"; -import * as ecrDeployment from "cdk-ecr-deployment"; -import { Aws } from "aws-cdk-lib"; -import { ContainerImage } from "aws-cdk-lib/aws-ecs"; -import { Platform } from "aws-cdk-lib/aws-ecr-assets"; +import { NextflowConfigConstruct } from "./nextflow-config-construct"; import { NEXTFLOW_PLUGINS } from "./dependencies"; export type BucketProps = { @@ -34,7 +28,6 @@ export type OncoanalyserProps = { maxPipelineCpus: number; maxTaskCpus: number; bucket: BucketProps; - docker: DockerImageBuildProps; }; export class Oncoanalyser extends Construct { @@ -80,14 +73,14 @@ export class Oncoanalyser extends Construct { const launchTemplateTask = this.getLaunchTemplate({ securityGroup: securityGroup, - launchTemplateName: "oncoanalyser-task" + launchTemplateName: "oncoanalyser-task", }); const computeEnvironmentTask = new batch.ManagedEc2EcsComputeEnvironment( this, "ComputeEnvironmentTask", { - allocationStrategy: batch.AllocationStrategy.BEST_FIT, + allocationStrategy: batch.AllocationStrategy.BEST_FIT_PROGRESSIVE, instanceRole: roleBatchInstanceTask, instanceTypes: props.taskInstanceTypes, launchTemplate: launchTemplateTask, @@ -146,6 +139,7 @@ export class Oncoanalyser extends Construct { resources: [ jobQueueTask.jobQueueArn, + // this is the naming format of the job definitions made by the pipeline node `arn:aws:batch:${Aws.REGION}:${Aws.ACCOUNT_ID}:job-definition/nf-*`, ], }), @@ -221,6 +215,20 @@ export class Oncoanalyser extends Construct { ], }); + new iam.Policy(this, "PipelinePolicyAppConfig", { + roles: [roleBatchInstancePipeline], + statements: [ + new iam.PolicyStatement({ + actions: [ + "appconfig:GetLatestConfiguration", + "appconfig:StartConfigurationSession", + ], + // should be tightened + resources: [`*`], + }), + ], + }); + roleBatchInstancePipeline.attachInlinePolicy( new iam.Policy(this, "PipelinePolicyPassRole", { statements: [ @@ -234,7 +242,7 @@ export class Oncoanalyser extends Construct { const launchTemplatePipeline = this.getLaunchTemplate({ securityGroup: securityGroup, - launchTemplateName: "oncoanalyser-pipeline" + launchTemplateName: "oncoanalyser-pipeline", }); const computeEnvironmentPipeline = @@ -242,7 +250,7 @@ export class Oncoanalyser extends Construct { this, "ComputeEnvironmentPipeline", { - allocationStrategy: batch.AllocationStrategy.BEST_FIT, + allocationStrategy: batch.AllocationStrategy.BEST_FIT_PROGRESSIVE, instanceRole: roleBatchInstancePipeline, instanceTypes: props.pipelineInstanceTypes, launchTemplate: launchTemplatePipeline, @@ -263,13 +271,13 @@ export class Oncoanalyser extends Construct { ], }); - // Create Docker image and deploy - const image = new ecrAssets.DockerImageAsset(this, 'DockerImage', { - directory: path.join(__dirname, 'resources'), + // create Docker image for pipeline + const image = new ecrAssets.DockerImageAsset(this, "DockerImage", { + directory: path.join(__dirname, "resources"), platform: Platform.LINUX_AMD64, buildArgs: { - NEXTFLOW_PLUGINS: NEXTFLOW_PLUGINS.join(",") - } + NEXTFLOW_PLUGINS: NEXTFLOW_PLUGINS.join(","), + }, }); // Bucket permissions @@ -303,17 +311,12 @@ export class Oncoanalyser extends Construct { `${props.bucket.outputPrefix}/*`, ); - const nextflowConfigTemplate = fs.readFileSync(path.join(__dirname, "resources/nextflow_aws.template.config"), { encoding: "utf-8"}); - - const nextflowConfigTemplateCompiled = Handlebars.compile(nextflowConfigTemplate); - - const nextflowConfig = nextflowConfigTemplateCompiled({ - BATCH_INSTANCE_TASK_ROLE_ARN: roleBatchInstanceTask.roleArn, - BATCH_JOB_QUEUE_NAME: jobQueueTask.jobQueueName, - S3_BUCKET_NAME: props.bucket.bucket, - S3_BUCKET_REFDATA_PREFIX: props.bucket.refDataPrefix, - PLUGINS: NEXTFLOW_PLUGINS, - }, { }); + const config = new NextflowConfigConstruct(this, "NextflowConfig", { + bucket: props.bucket, + tasksInstanceRole: roleBatchInstanceTask, + tasksJobQueue: jobQueueTask, + copyToLocalEcr: false, + }); // Create job definition for pipeline execution const jobDefinition = new batch.EcsJobDefinition(this, "JobDefinition", { @@ -325,17 +328,18 @@ export class Oncoanalyser extends Construct { cpu: 1, image: ContainerImage.fromDockerImageAsset(image), command: ["true"], - memory: cdk.Size.mebibytes(1000), + memory: cdk.Size.gibibytes(1), jobRole: roleBatchInstancePipeline, - environment: { - ONCOANALYSER_NEXTFLOW_CONFIG_BASE64: Buffer.from(nextflowConfig).toString('base64') - } + environment: config.getEnvironmentVariables(), }, ), }); } - getLaunchTemplate(args: { securityGroup: ec2.ISecurityGroup; launchTemplateName?: string }) { + getLaunchTemplate(args: { + securityGroup: ec2.ISecurityGroup; + launchTemplateName?: string; + }) { const userData = ec2.UserData.custom( `MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="==BOUNDARY==" @@ -372,54 +376,13 @@ rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ ); const ltName = args.launchTemplateName ?? "oncoanalyser"; const constructId = `LaunchTemplate-${ltName}`; - const launchTemplate = new ec2.LaunchTemplate( - this, - constructId, - { - launchTemplateName: ltName, - associatePublicIpAddress: true, - userData: userData, - securityGroup: args.securityGroup, - }, - ); + const launchTemplate = new ec2.LaunchTemplate(this, constructId, { + associatePublicIpAddress: true, + userData: userData, + securityGroup: args.securityGroup, + }); cdk.Tags.of(launchTemplate).add("Name", ltName); return launchTemplate; } -} - -export type DockerImageBuildProps = { - ecrRepo: string; - dockerImageTag: string; -}; - -export class DockerImageBuild extends Construct { - public readonly image: ecs.EcrImage; - - constructor(scope: Construct, id: string, props: DockerImageBuildProps) { - super(scope, id); - - const image = new ecrAssets.DockerImageAsset(this, "DockerImage", { - directory: path.join(__dirname, "resources"), - }); - - const dockerDestBase = `${Aws.ACCOUNT_ID}.dkr.ecr.${Aws.REGION}.amazonaws.com`; - - new ecrDeployment.ECRDeployment(this, "DeployDockerImage", { - src: new ecrDeployment.DockerImageName(image.imageUri), - dest: new ecrDeployment.DockerImageName( - `${dockerDestBase}/${props.ecrRepo}:${props.dockerImageTag}`, - ), - }); - - const ecrRepository = ecr.Repository.fromRepositoryName( - this, - "EcrRespository", - props.ecrRepo, - ); - this.image = ecs.EcrImage.fromEcrRepository( - ecrRepository, - props.dockerImageTag, - ); - } -} +} \ No newline at end of file diff --git a/lib/nextflow-config-construct.ts b/lib/nextflow-config-construct.ts new file mode 100644 index 0000000..11b383c --- /dev/null +++ b/lib/nextflow-config-construct.ts @@ -0,0 +1,307 @@ +import { join } from "path"; +import { readFileSync } from "fs"; +import * as Handlebars from "handlebars"; +import { Construct } from "constructs"; +import { BucketProps } from "./application-stack"; +import * as appconfig from "aws-cdk-lib/aws-appconfig"; +import { DeletionProtectionCheck } from "aws-cdk-lib/aws-appconfig"; +import { DockerImageAsset, Platform } from "aws-cdk-lib/aws-ecr-assets"; +import { IRole } from "aws-cdk-lib/aws-iam"; +import { IJobQueue } from "aws-cdk-lib/aws-batch"; +import { Duration } from "aws-cdk-lib"; +import { NEXTFLOW_PLUGINS } from "./dependencies"; + +export type NextflowConfigProps = { + bucket: BucketProps; + tasksInstanceRole: IRole; + tasksJobQueue: IJobQueue; + + // if present and true, instructs the construct to make local ECR assets mirroring + // the standard task Docker images + // otherwise, the pipeline will launch Docker images directly from their + // public repository (like quay.io or dockerhub) + readonly copyToLocalEcr?: boolean; +}; + +export class NextflowConfigConstruct extends Construct { + private readonly application: appconfig.Application; + private readonly environment: appconfig.Environment; + private readonly hostedConfiguration: appconfig.HostedConfiguration; + + constructor(scope: Construct, id: string, props: NextflowConfigProps) { + super(scope, id); + + /** + * Makes the insertion into the nextflow config of the Docker image URI + * for each task. + * + * @param substitutions a dictionary mapping name->value + * @param configName + * @param dockerImageUri + */ + const fixConfigSectionForTask = ( + substitutions: Record, + configName: string, + dockerImageUri: string, + ) => { + if (props.copyToLocalEcr) { + // we create a "thin" Docker image that essentially is exactly the same layers as the source + // docker image - but is maintained as an asset within the CDK setup + // this means CDK will handle deploying it to ECR for us + const imageAsset = new DockerImageAsset(this, configName, { + directory: join(__dirname, "task_docker_images"), + platform: Platform.LINUX_AMD64, + // because the image base name is passed into Docker - the actual Docker checksum + // itself won't change even when the image base does... so we need to add the name/tag into the hash + extraHash: dockerImageUri, + buildArgs: { + // pass this through to Docker forming the base of the image we are constructing + BASE_IMAGE: dockerImageUri, + }, + }); + + substitutions[configName] = imageAsset.imageUri; + } else { + // we will just directly reference the Docker image in quay.io etc + substitutions[configName] = dockerImageUri; + } + }; + + // we build a dictionary of substitution values that can be inserted into the config by handlebars + // we first insert here the AWS values like role ARN etc that are needed by the Nextflow + // pipeline engine + const substitutions: Record = { + BATCH_INSTANCE_TASK_ROLE_ARN: props.tasksInstanceRole.roleArn, + BATCH_JOB_QUEUE_NAME: props.tasksJobQueue.jobQueueName, + S3_BUCKET_NAME: props.bucket.bucket, + S3_BUCKET_REFDATA_PREFIX: props.bucket.refDataPrefix, + PLUGINS: NEXTFLOW_PLUGINS, + }; + + // modules/local/neo/annotate_fusions/main.nf: 'biocontainers/hmftools-isofox:1.7.1--hdfd78af_1' + + fixConfigSectionForTask( + substitutions, + "NEO_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-neo:1.2--hdfd78af_1", + ); + fixConfigSectionForTask( + substitutions, + "BAMTOOLS_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-bam-tools:1.3--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "LINXREPORT_DOCKER_IMAGE_URI", + "quay.io/biocontainers/r-linxreport:1.0.0--r43hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "PAVE_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-pave:1.7--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "ESVEE_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-esvee:1.0--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "SAMBAMBA_DOCKER_IMAGE_URI", + "quay.io/biocontainers/sambamba:1.0.1--h6f6fda4_0", + ); + fixConfigSectionForTask( + substitutions, + "SAMTOOLS_DOCKER_IMAGE_URI", + "quay.io/biocontainers/samtools:1.18--h50ea8bc_", + ); + fixConfigSectionForTask( + substitutions, + "STAR_ALIGN_IMAGE_URI", + "quay.io/biocontainers/star:2.7.3a--0", + ); + fixConfigSectionForTask( + substitutions, + "GRIPSS_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-gripss:2.4--hdfd78af_00", + ); + fixConfigSectionForTask( + substitutions, + "COBALT_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-cobalt:2.0--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "LINX_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-linx:2.0--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "ISOFOX_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-isofox:1.7.1--hdfd78af_1", + ); + fixConfigSectionForTask( + substitutions, + "AMBER_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-amber:4.1.1--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "LILAC_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-lilac:1.6--hdfd78af_1", + ); + fixConfigSectionForTask( + substitutions, + "STAR_DOCKER_IMAGE_URI", + "quay.io/biocontainers/star:2.7.3a--0", + ); + fixConfigSectionForTask( + substitutions, + "PURPLE_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-purple:4.1--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "VIRUSBREAKEND_DOCKER_IMAGE_URI", + "quay.io/nf-core/gridss:2.13.2--1", + ); + fixConfigSectionForTask( + substitutions, + "GRIDSS_INDEX_DOCKER_IMAGE_URI", + "quay.io/biocontainers/gridss:2.13.2--h50ea8bc_3", + ); + fixConfigSectionForTask( + substitutions, + "GATK4_MARKDUPLICATES_IMAGE_URI", + "quay.io/biocontainers/gatk4:4.4.0.0--py36hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "CHORD_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-chord:2.1.0--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "LILAC_EXTRACT_INDEX_DOCKER_IMAGE_URI", + "quay.io/biocontainers/mulled-v2-4dde50190ae599f2bb2027cb2c8763ea00fb5084:4163e62e1daead7b7ea0228baece715bec295c22-0", + ); + fixConfigSectionForTask( + substitutions, + "LILAC_REALIGN_READS_DOCKER_IMAGE_URI", + "quay.io/biocontainers/mulled-v2-4dde50190ae599f2bb2027cb2c8763ea00fb5084:4163e62e1daead7b7ea0228baece715bec295c22-0", + ); + fixConfigSectionForTask( + substitutions, + "LILAC_SLICE_DOCKER_IMAGE_URI", + "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_0", + ); + fixConfigSectionForTask( + substitutions, + "BWAMEM2_DOCKER_IMAGE_URI", + "quay.io/biocontainers/mulled-v2-4dde50190ae599f2bb2027cb2c8763ea00fb5084:4163e62e1daead7b7ea0228baece715bec295c22-0", + ); + fixConfigSectionForTask( + substitutions, + "REDUX_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-redux:1.1--hdfd78af_1", + ); + fixConfigSectionForTask( + substitutions, + "VIRUSINTERPRETER_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-virus-interpreter:1.7--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "SAGE_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-sage:4.0--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "CUPPA_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-cuppa:2.3.1--py311r42hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "ORANGE_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-orange:3.7.1--hdfd78af_0", + ); + fixConfigSectionForTask( + substitutions, + "FASTP_DOCKER_IMAGE_URI", + "quay.io/biocontainers/fastp:0.23.4--hadf994f_2", + ); + fixConfigSectionForTask( + substitutions, + "SIGS_DOCKER_IMAGE_URI", + "quay.io/biocontainers/hmftools-sigs:1.2.1--hdfd78af_1", + ); + + const nextflowConfigTemplate = readFileSync( + join(__dirname, "resources/nextflow_aws.template.config"), + { encoding: "utf-8" }, + ); + const nextflowConfigTemplateCompiled = Handlebars.compile( + nextflowConfigTemplate, + ); + const nextflowConfig = nextflowConfigTemplateCompiled(substitutions, {}); + + this.application = new appconfig.Application( + this, + "AppConfigApplication", + {}, + ); + this.environment = new appconfig.Environment(this, "AppConfigEnvironment", { + description: "Default environment for this deployment of Oncoanalyser", + application: this.application, + // the configurations are templated and deployed via CDK - it is not expected that + // users will edit, so we can aggressively delete + deletionProtectionCheck: DeletionProtectionCheck.BYPASS, + }); + + const deploymentStrategy = new appconfig.DeploymentStrategy( + this, + "AppConfigDeploymentStrategy", + { + deploymentStrategyName: "AllAtOnceAsQuickAsWeCan", + rolloutStrategy: { + growthFactor: 100, + deploymentDuration: Duration.minutes(0), + // given our nextflow only runs on demand (and only picks up the config on startup), + // there is no point waiting when we roll out configs + finalBakeTime: Duration.minutes(0), + }, + }, + ); + + this.hostedConfiguration = new appconfig.HostedConfiguration( + this, + "AppConfigHostedConfiguration", + { + description: + "Default configuration for this deployment of Oncoanalyser - this config is autogenerated from a template and should not be edited", + application: this.application, + deployTo: [this.environment], + deploymentStrategy: deploymentStrategy, + content: appconfig.ConfigurationContent.fromInlineText(nextflowConfig), + }, + ); + + // if a substitution of something like REDUX_DOCKER_IMAGE_URI does not happen - then we will be left with an empty string in the nextflow config + // as we don't have any real empty strings - we use this to detect missed subs + //if (nextflowConfig.includes("''")) + // throw new Error( + // "a docker image substitution was missed in the nextflow config presumably because of a simple name mismatch", + // ); + } + + public getEnvironmentVariables(): Record { + return { + ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_APPLICATION: + this.application.applicationId, + ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_ENVIRONMENT: + this.environment.environmentId, + ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_CONFIGURATION_PROFILE: + this.hostedConfiguration.configurationProfileId, + }; + } +} diff --git a/lib/resources/Dockerfile b/lib/resources/Dockerfile index f16ab7c..1129957 100644 --- a/lib/resources/Dockerfile +++ b/lib/resources/Dockerfile @@ -29,6 +29,7 @@ RUN \ git clone -b aws-stack-testing https://github.com/scwatts/oncoanalyser-aws-stack-testing /root/pipeline/software/oncoanalyser/ COPY nextflow_aws.template.config /root/pipeline/other/ + COPY run.sh /root/pipeline/other/ WORKDIR /root/pipeline/ diff --git a/lib/resources/nextflow_aws.template.config b/lib/resources/nextflow_aws.template.config index e5d4eb8..3e7434b 100644 --- a/lib/resources/nextflow_aws.template.config +++ b/lib/resources/nextflow_aws.template.config @@ -10,7 +10,7 @@ aws { volumes = '/scratch' } batch { - cliPath = '/usr/local/bin/aws' + cliPath = '/opt/awscliv2/bin/aws' } } @@ -68,51 +68,61 @@ process { queue = '{{BATCH_JOB_QUEUE_NAME}}' withName: 'FASTP' { + container = '{{FASTP_DOCKER_IMAGE_URI}}' cpus = 16 memory = 30.GB } withName: 'BWAMEM2_ALIGN' { + container = '{{BWAMEM2_DOCKER_IMAGE_URI}}' cpus = 32 memory = 60.GB } withName: 'REDUX' { + container = '{{REDUX_DOCKER_IMAGE_URI}}' cpus = 16 memory = 120.GB } withName: 'STAR_ALIGN' { + container = '{{STAR_ALIGN_IMAGE_URI}}' cpus = 8 memory = 60.GB } withName: 'SAMTOOLS_SORT' { + container = '{{SAMTOOLS_DOCKER_IMAGE_URI}}' cpus = 8 memory = 30.GB } withName: 'SAMBAMBA_MERGE' { + container = '{{SAMBAMBA_DOCKER_IMAGE_URI}}' cpus = 8 memory = 30.GB } withName: 'GATK4_MARKDUPLICATES' { + container = '{{GATK4_MARKDUPLICATES_IMAGE_URI}}' cpus = 8 memory = 30.GB } withName: 'AMBER' { + container = '{{AMBER_DOCKER_IMAGE_URI}}' cpus = 8 memory = 30.GB } withName: 'COBALT' { + container = '{{COBALT_DOCKER_IMAGE_URI}}' cpus = 8 memory = 30.GB } withName: 'ESVEE_PREP' { + container = '{{ESVEE_DOCKER_IMAGE_URI}}' errorStrategy = 'retry' maxRetries = 1 @@ -121,6 +131,7 @@ process { } withName: 'ESVEE_PREP' { + container = '{{ESVEE_DOCKER_IMAGE_URI}}' errorStrategy = 'retry' maxRetries = 1 @@ -131,11 +142,13 @@ process { } withName: 'ESVEE_CALL' { + container = '{{ESVEE_DOCKER_IMAGE_URI}}' cpus = 16 memory = 30.GB } withName: 'ESVEE_DEPTH_ANNOTATOR' { + container = '{{ESVEE_DOCKER_IMAGE_URI}}' errorStrategy = 'retry' maxRetries = 1 @@ -144,26 +157,31 @@ process { } withName: '.*:GRIPSS_FILTERING:(?:GERMLINE|SOMATIC)' { + container = '{{GRIPSS_DOCKER_IMAGE_URI}}' cpus = 4 memory = 30.GB } withName: '.*:SAGE_CALLING:GERMLINE' { + container = '{{SAGE_DOCKER_IMAGE_URI}}' cpus = 4 memory = 30.GB } withName: '.*:SAGE_CALLING:SOMATIC' { + container = '{{SAGE_DOCKER_IMAGE_URI}}' cpus = 16 memory = 30.GB } withName: '.*:SAGE_APPEND:(?:GERMLINE|SOMATIC)' { + container = '{{SAGE_DOCKER_IMAGE_URI}}' cpus = 2 memory = 14.GB } withName: '.*:PAVE_ANNOTATION:GERMLINE' { + container = '{{PAVE_DOCKER_IMAGE_URI}}' cpus = 2 memory = 14.GB } @@ -171,11 +189,14 @@ process { // NOTE(SW): PAVE somatic uses a significant amount of memory, runtime is usually less than 5-10 minutes withName: '.*:PAVE_ANNOTATION:SOMATIC' { + container = '{{PAVE_DOCKER_IMAGE_URI}}' cpus = 4 memory = 30.GB } withName: 'PURPLE' { + container = '{{PURPLE_DOCKER_IMAGE_URI}}' + errorStrategy = 'retry' maxRetries = 1 @@ -184,11 +205,13 @@ process { } withName: '.*:LINX_ANNOTATION:(?:GERMLINE|SOMATIC)' { + container = '{{LINX_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } withName: '.*:LINX_PLOTTING:VISUALISER' { + container = '{{LINX_DOCKER_IMAGE_URI}}' errorStrategy = 'retry' maxRetries = 1 @@ -197,74 +220,87 @@ process { } withName: '.*:LINX_PLOTTING:REPORT' { + container = '{{LINXREPORT_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } withName: 'BAMTOOLS' { + container = '{{BAMTOOLS_DOCKER_IMAGE_URI}}' cpus = 8 memory = 30.GB time = 24.h } withName: 'CHORD' { + container = '{{CHORD_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } withName: 'LILAC' { + container = '{{LILAC_DOCKER_IMAGE_URI}}' cpus = 4 memory = 30.GB } withName: '.*:LILAC_CALLING:EXTRACTCONTIG' { + container = '{{LILAC_EXTRACT_INDEX_DOCKER_IMAGE_URI}}' cpus = 4 memory = 30.GB } withName: '.*:LILAC_CALLING:REALIGNREADS' { + container = '{{LILAC_REALIGN_READS_DOCKER_IMAGE_URI}}' cpus = 4 memory = 30.GB } withName: '.*:LILAC_CALLING:SLICEBAM' { + container = '{{LILAC_SLICE_DOCKER_IMAGE_URI}}' cpus = 4 memory = 30.GB } withName: 'SIGS' { + container = '{{SIGS_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } withName: 'VIRUSBREAKEND' { + container = '{{VIRUSBREAKEND_DOCKER_IMAGE_URI}}' cpus = 8 memory = 60.GB } withName: 'VIRUSINTERPRETER' { + container = '{{VIRUSINTERPRETER_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } withName: 'ISOFOX' { + container = '{{ISOFOX_DOCKER_IMAGE_URI}}' cpus = 8 memory = 30.GB } withName: 'CUPPA' { + container = '{{CUPPA_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } withName: 'ORANGE' { + container = '{{ORANGE_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { + container = '{{DUMPSOFTWAREVERSIONS_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } - } diff --git a/lib/resources/run.sh b/lib/resources/run.sh index b15945a..29c197d 100755 --- a/lib/resources/run.sh +++ b/lib/resources/run.sh @@ -40,8 +40,18 @@ fi aws s3 cp ${params_fp} params.json output_base=$(jq -r .outdir params.json) -# Nextflow config comes from an environment variable prepared by the deploying CDK -echo $ONCOANALYSER_NEXTFLOW_CONFIG_BASE64 | base64 --decode > aws.config +# Nextflow config is generated by the CDK at build time +# however - due to the size of it - we cannot pass in down via Batch Job Definition/Parameter Store +# instead we store it in AppConfig and fetch it +# for the moment appconfig is overkill - but it does open up the possibility of things +# like feature flags etc +appconfig_token=$(aws appconfigdata start-configuration-session \ + --application-identifier $ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_APPLICATION \ + --environment-identifier $ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_ENVIRONMENT \ + --configuration-profile-identifier $ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_CONFIGURATION_PROFILE \ + --query InitialConfigurationToken --output text) + +aws appconfigdata get-latest-configuration --configuration-token $appconfig_token aws.config # Set additional Nextflow arguments nf_arg_stub='' diff --git a/lib/task_docker_images/Dockerfile b/lib/task_docker_images/Dockerfile new file mode 100644 index 0000000..261fb14 --- /dev/null +++ b/lib/task_docker_images/Dockerfile @@ -0,0 +1,4 @@ +ARG BASE_IMAGE + +# use a dynamic base that MUST be specified as part of the CDK build step +FROM $BASE_IMAGE diff --git a/package-lock.json b/package-lock.json index 740b097..b4db762 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@types/node": "22.7.9", "aws-cdk": "2.177.0", "jest": "^29.7.0", + "prettier": "3.5.2", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typescript": "~5.6.3" @@ -3986,6 +3987,22 @@ "node": ">=8" } }, + "node_modules/prettier": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz", + "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-format": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", diff --git a/package.json b/package.json index b4688da..8f91278 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@types/node": "22.7.9", "aws-cdk": "2.177.0", "jest": "^29.7.0", + "prettier": "3.5.2", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typescript": "~5.6.3" From 3eebfedbb04d7e81a9183af73d3edee43888d30a Mon Sep 17 00:00:00 2001 From: Andrew Patterson Date: Mon, 3 Mar 2025 09:57:53 +1100 Subject: [PATCH 09/11] Brought some settings up to CDK top level (#22) Removed all fixed names not externally referenced --- bin/settings.ts | 12 ++++++++---- lib/application-stack.ts | 26 +++++++++++++++++--------- lib/resources/Dockerfile | 4 +++- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/bin/settings.ts b/bin/settings.ts index a497e6a..da34e14 100644 --- a/bin/settings.ts +++ b/bin/settings.ts @@ -12,15 +12,19 @@ export const SETTINGS: OncoanalyserProps = { refDataPrefix: "refdata", }, // NOTE(SW): temporary reduction for testing during dev - //maxPipelineCpus: 64, - //maxTaskCpus: 256, - maxPipelineCpus: 2, - maxTaskCpus: 4, + //pipelineMaxCpus: 64, + //taskMaxCpus: 256, + pipelineMaxCpus: 2, + taskMaxCpus: 4, pipelineInstanceTypes: [ ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), ], + pipelineQueueName: "oncoanalyser-pipeline", + pipelineJobDefinitionName: "oncoanalyser-job-definition", taskInstanceTypes: [ ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.XLARGE), ], vpc: undefined, + gitRepo: "https://github.com/scwatts/oncoanalyser-aws-stack-testing", + gitBranch: "aws-stack-testing" }; diff --git a/lib/application-stack.ts b/lib/application-stack.ts index 744f5ac..a0c065f 100644 --- a/lib/application-stack.ts +++ b/lib/application-stack.ts @@ -23,11 +23,20 @@ export type BucketProps = { export type OncoanalyserProps = { vpc?: ec2.IVpc | string; + + pipelineQueueName: string; + pipelineJobDefinitionName: string; pipelineInstanceTypes: ec2.InstanceType[]; + pipelineMaxCpus: number; + taskInstanceTypes: ec2.InstanceType[]; - maxPipelineCpus: number; - maxTaskCpus: number; + taskMaxCpus: number; + bucket: BucketProps; + + // the Git repo of oncoanalyser to launch from nextflow + gitRepo: string; + gitBranch: string; }; export class Oncoanalyser extends Construct { @@ -56,7 +65,6 @@ export class Oncoanalyser extends Construct { // Create Batch resources and co for Nextflow ***task*** jobs const roleBatchInstanceTask = new iam.Role(this, "BatchInstanceRoleTask", { - roleName: "batch-instance-role-task", assumedBy: new iam.CompositePrincipal( new iam.ServicePrincipal("ec2.amazonaws.com"), new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), @@ -84,7 +92,7 @@ export class Oncoanalyser extends Construct { instanceRole: roleBatchInstanceTask, instanceTypes: props.taskInstanceTypes, launchTemplate: launchTemplateTask, - maxvCpus: props.maxTaskCpus, + maxvCpus: props.taskMaxCpus, securityGroups: [], useOptimalInstanceClasses: false, vpc: vpc, @@ -95,7 +103,6 @@ export class Oncoanalyser extends Construct { ); const jobQueueTask = new batch.JobQueue(this, "JobQueueTask", { - jobQueueName: "oncoanalyser-tasks", computeEnvironments: [ { computeEnvironment: computeEnvironmentTask, order: 1 }, ], @@ -106,7 +113,6 @@ export class Oncoanalyser extends Construct { this, "BatchInstanceRolePipeline", { - roleName: "batch-instance-role-pipeline", assumedBy: new iam.CompositePrincipal( new iam.ServicePrincipal("ec2.amazonaws.com"), new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), @@ -254,7 +260,7 @@ export class Oncoanalyser extends Construct { instanceRole: roleBatchInstancePipeline, instanceTypes: props.pipelineInstanceTypes, launchTemplate: launchTemplatePipeline, - maxvCpus: props.maxPipelineCpus, + maxvCpus: props.pipelineMaxCpus, securityGroups: [], useOptimalInstanceClasses: false, vpc: vpc, @@ -265,7 +271,7 @@ export class Oncoanalyser extends Construct { ); const jobQueuePipeline = new batch.JobQueue(this, "JobQueuePipeline", { - jobQueueName: "oncoanalyser-pipeline", + jobQueueName: props.pipelineQueueName, computeEnvironments: [ { computeEnvironment: computeEnvironmentPipeline, order: 1 }, ], @@ -277,6 +283,8 @@ export class Oncoanalyser extends Construct { platform: Platform.LINUX_AMD64, buildArgs: { NEXTFLOW_PLUGINS: NEXTFLOW_PLUGINS.join(","), + SOFTWARE_GIT_REPO: props.gitRepo, + SOFTWARE_GIT_BRANCH: props.gitBranch }, }); @@ -320,7 +328,7 @@ export class Oncoanalyser extends Construct { // Create job definition for pipeline execution const jobDefinition = new batch.EcsJobDefinition(this, "JobDefinition", { - jobDefinitionName: "oncoanalyser-job-definition", + jobDefinitionName: props.pipelineJobDefinitionName, container: new batch.EcsEc2ContainerDefinition( this, "EcsEc2ContainerDefinition", diff --git a/lib/resources/Dockerfile b/lib/resources/Dockerfile index 1129957..f784610 100644 --- a/lib/resources/Dockerfile +++ b/lib/resources/Dockerfile @@ -1,6 +1,8 @@ FROM docker.io/continuumio/miniconda3:25.1.1-2 ARG NEXTFLOW_PLUGINS +ARG SOFTWARE_GIT_REPO +ARG SOFTWARE_GIT_BRANCH # Configure Conda RUN \ @@ -26,7 +28,7 @@ RUN nextflow plugin install ${NEXTFLOW_PLUGINS} # Install oncoanalyser and config template RUN \ - git clone -b aws-stack-testing https://github.com/scwatts/oncoanalyser-aws-stack-testing /root/pipeline/software/oncoanalyser/ + git clone -b ${SOFTWARE_GIT_BRANCH} ${SOFTWARE_GIT_REPO} /root/pipeline/software/oncoanalyser/ COPY nextflow_aws.template.config /root/pipeline/other/ From 52e4dabc42012c8737462f7e5f52c92d0f315870 Mon Sep 17 00:00:00 2001 From: William Putra Intan <61998484+williamputraintan@users.noreply.github.com> Date: Tue, 4 Mar 2025 07:15:43 +0700 Subject: [PATCH 10/11] Construct Refactor && `jsii` build (#26) --- .github/workflows/release.yml | 30 + .gitignore | 8 + .npmignore | 20 +- bin/oncoanalyser-stack.ts | 3 +- bin/settings.ts | 6 +- lib/application-stack.ts | 396 --- lib/ec2-user-data.txt | 32 + lib/index.ts | 5 + .../Dockerfile | 0 .../index.ts} | 50 +- lib/nextflow-pipeline-environment/index.ts | 243 ++ lib/nextflow-task-environment/index.ts | 129 + .../nextflow_aws.template.config | 0 .../Dockerfile | 4 +- lib/oncoanalyser-job-definition/index.ts | 77 + .../run.sh | 0 lib/oncoanalyser.ts | 188 ++ lib/utils.ts | 31 + package-lock.json | 2675 ++++++++++++++++- package.json | 48 +- tsconfig.json | 31 - 21 files changed, 3361 insertions(+), 615 deletions(-) create mode 100644 .github/workflows/release.yml delete mode 100644 lib/application-stack.ts create mode 100644 lib/ec2-user-data.txt create mode 100644 lib/index.ts rename lib/{task_docker_images => nextflow-config}/Dockerfile (100%) rename lib/{nextflow-config-construct.ts => nextflow-config/index.ts} (90%) create mode 100644 lib/nextflow-pipeline-environment/index.ts create mode 100644 lib/nextflow-task-environment/index.ts rename lib/{resources => }/nextflow_aws.template.config (100%) rename lib/{resources => oncoanalyser-job-definition}/Dockerfile (82%) create mode 100644 lib/oncoanalyser-job-definition/index.ts rename lib/{resources => oncoanalyser-job-definition}/run.sh (100%) create mode 100644 lib/oncoanalyser.ts create mode 100644 lib/utils.ts delete mode 100644 tsconfig.json diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..5db0007 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Release Packages + +on: + release: + types: [released] + +jobs: + publish-to-npm-registry: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + + - uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - run: npm install + + # build and package + + - run: npm run build + + - run: npm run package + + - run: npx publib-npm + env: + NPM_TOKEN: ${{secrets.NPM_PUBLISH_TOKEN}} + NPM_ACCESS_LEVEL: public diff --git a/.gitignore b/.gitignore index dff5ab5..e5f244c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,11 @@ NOTES.md prev/ temp/ /.idea/ + +# Generated by jsii - safe to delete, and ideally should be in .gitignore +tsconfig.json + +dist/ + +.jsii +*.tsbuildinfo diff --git a/.npmignore b/.npmignore index c1d6d45..68f876c 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,20 @@ -*.ts -!*.d.ts - # CDK asset staging directory .cdk.staging cdk.out + +# Exclude typescript source and config +*.ts +!*.d.ts +tsconfig.json +*.tsbuildinfo + +# Include javascript files and typescript declarations +!*.js +!*.d.ts + +# Exclude jsii outdir +dist + +# Include .jsii and .jsii.gz +!.jsii +!.jsii.gz diff --git a/bin/oncoanalyser-stack.ts b/bin/oncoanalyser-stack.ts index 2c25cc7..ef4caab 100644 --- a/bin/oncoanalyser-stack.ts +++ b/bin/oncoanalyser-stack.ts @@ -1,9 +1,8 @@ #!/usr/bin/env node import * as cdk from "aws-cdk-lib"; -import * as ec2 from "aws-cdk-lib/aws-ec2"; import { Construct } from "constructs"; -import { Oncoanalyser, OncoanalyserProps } from "../lib/application-stack"; +import { Oncoanalyser, OncoanalyserProps } from "../lib/oncoanalyser"; import { SETTINGS } from "./settings"; export class OncoanalyserStack extends cdk.Stack { diff --git a/bin/settings.ts b/bin/settings.ts index da34e14..543690d 100644 --- a/bin/settings.ts +++ b/bin/settings.ts @@ -1,4 +1,4 @@ -import { OncoanalyserProps } from "../lib/application-stack"; +import { OncoanalyserProps } from "../lib/oncoanalyser"; import * as ec2 from "aws-cdk-lib/aws-ec2"; /** @@ -19,12 +19,12 @@ export const SETTINGS: OncoanalyserProps = { pipelineInstanceTypes: [ ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), ], - pipelineQueueName: "oncoanalyser-pipeline", + pipelineQueueName: "oncoanalyser-pipeline", pipelineJobDefinitionName: "oncoanalyser-job-definition", taskInstanceTypes: [ ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.XLARGE), ], vpc: undefined, gitRepo: "https://github.com/scwatts/oncoanalyser-aws-stack-testing", - gitBranch: "aws-stack-testing" + gitBranch: "aws-stack-testing", }; diff --git a/lib/application-stack.ts b/lib/application-stack.ts deleted file mode 100644 index a0c065f..0000000 --- a/lib/application-stack.ts +++ /dev/null @@ -1,396 +0,0 @@ -import { Construct } from "constructs"; - -import * as path from "path"; - -import * as batch from "aws-cdk-lib/aws-batch"; -import * as cdk from "aws-cdk-lib"; -import { Aws } from "aws-cdk-lib"; -import * as ec2 from "aws-cdk-lib/aws-ec2"; -import * as ecrAssets from "aws-cdk-lib/aws-ecr-assets"; -import { Platform } from "aws-cdk-lib/aws-ecr-assets"; -import { ContainerImage } from "aws-cdk-lib/aws-ecs"; -import * as iam from "aws-cdk-lib/aws-iam"; -import * as s3 from "aws-cdk-lib/aws-s3"; -import { NextflowConfigConstruct } from "./nextflow-config-construct"; -import { NEXTFLOW_PLUGINS } from "./dependencies"; - -export type BucketProps = { - bucket: string; - inputPrefix: string; - outputPrefix: string; - refDataPrefix: string; -}; - -export type OncoanalyserProps = { - vpc?: ec2.IVpc | string; - - pipelineQueueName: string; - pipelineJobDefinitionName: string; - pipelineInstanceTypes: ec2.InstanceType[]; - pipelineMaxCpus: number; - - taskInstanceTypes: ec2.InstanceType[]; - taskMaxCpus: number; - - bucket: BucketProps; - - // the Git repo of oncoanalyser to launch from nextflow - gitRepo: string; - gitBranch: string; -}; - -export class Oncoanalyser extends Construct { - constructor(scope: Construct, id: string, props: OncoanalyserProps) { - super(scope, id); - - let vpc; - if (props.vpc === undefined) { - vpc = ec2.Vpc.fromLookup(this, "VPC", { - isDefault: true, - }); - } else if (typeof props.vpc == "string") { - vpc = ec2.Vpc.fromLookup(this, "VPC", { - vpcName: props.vpc, - }); - } else { - vpc = props.vpc; - } - - /// Allows all outbound connections. - const securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", { - allowAllOutbound: true, - description: "oncoanalyser security group", - vpc, - }); - - // Create Batch resources and co for Nextflow ***task*** jobs - const roleBatchInstanceTask = new iam.Role(this, "BatchInstanceRoleTask", { - assumedBy: new iam.CompositePrincipal( - new iam.ServicePrincipal("ec2.amazonaws.com"), - new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), - ), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName( - "AmazonSSMManagedInstanceCore", - ), - iam.ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AmazonEC2ContainerServiceforEC2Role", - ), - ], - }); - - const launchTemplateTask = this.getLaunchTemplate({ - securityGroup: securityGroup, - launchTemplateName: "oncoanalyser-task", - }); - - const computeEnvironmentTask = new batch.ManagedEc2EcsComputeEnvironment( - this, - "ComputeEnvironmentTask", - { - allocationStrategy: batch.AllocationStrategy.BEST_FIT_PROGRESSIVE, - instanceRole: roleBatchInstanceTask, - instanceTypes: props.taskInstanceTypes, - launchTemplate: launchTemplateTask, - maxvCpus: props.taskMaxCpus, - securityGroups: [], - useOptimalInstanceClasses: false, - vpc: vpc, - vpcSubnets: { - subnetType: ec2.SubnetType.PUBLIC, - }, - }, - ); - - const jobQueueTask = new batch.JobQueue(this, "JobQueueTask", { - computeEnvironments: [ - { computeEnvironment: computeEnvironmentTask, order: 1 }, - ], - }); - - // Create Batch resources and co for Nextflow ***pipeline*** jobs - const roleBatchInstancePipeline = new iam.Role( - this, - "BatchInstanceRolePipeline", - { - assumedBy: new iam.CompositePrincipal( - new iam.ServicePrincipal("ec2.amazonaws.com"), - new iam.ServicePrincipal("ecs-tasks.amazonaws.com"), - ), - managedPolicies: [ - iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonS3ReadOnlyAccess"), - iam.ManagedPolicy.fromAwsManagedPolicyName( - "AmazonSSMManagedInstanceCore", - ), - iam.ManagedPolicy.fromAwsManagedPolicyName( - "service-role/AmazonEC2ContainerServiceforEC2Role", - ), - ], - }, - ); - - // NOTE(SW): the below policies are mostly those described by the Nextflow documents, some minor changes have been - // made so that the access is less permissive - - new iam.Policy(this, "PipelinePolicyBatchJobs", { - roles: [roleBatchInstancePipeline], - statements: [ - new iam.PolicyStatement({ - actions: [ - "batch:CancelJob", - "batch:SubmitJob", - "batch:TagResource", - "batch:TerminateJob", - ], - - resources: [ - jobQueueTask.jobQueueArn, - // this is the naming format of the job definitions made by the pipeline node - `arn:aws:batch:${Aws.REGION}:${Aws.ACCOUNT_ID}:job-definition/nf-*`, - ], - }), - ], - }); - - new iam.Policy(this, "PipelinePolicyBatchGeneral", { - roles: [roleBatchInstancePipeline], - statements: [ - new iam.PolicyStatement({ - actions: [ - "batch:ListJobs", - "batch:DescribeJobs", - "batch:DescribeJobQueues", - "batch:DescribeComputeEnvironments", - "batch:RegisterJobDefinition", - "batch:DescribeJobDefinitions", - ], - resources: ["*"], - }), - ], - }); - - new iam.Policy(this, "PipelinePolicyInstances", { - roles: [roleBatchInstancePipeline], - statements: [ - new iam.PolicyStatement({ - actions: [ - "ecs:DescribeTasks", - "ec2:DescribeInstances", - "ec2:DescribeInstanceTypes", - "ec2:DescribeInstanceAttribute", - "ecs:DescribeContainerInstances", - "ec2:DescribeInstanceStatus", - ], - resources: ["*"], - }), - ], - }); - - new iam.Policy(this, "PipelinePolicyECR", { - roles: [roleBatchInstancePipeline], - statements: [ - new iam.PolicyStatement({ - actions: [ - "ecr:GetAuthorizationToken", - "ecr:BatchCheckLayerAvailability", - "ecr:GetDownloadUrlForLayer", - "ecr:GetRepositoryPolicy", - "ecr:DescribeRepositories", - "ecr:ListImages", - "ecr:DescribeImages", - "ecr:BatchGetImage", - "ecr:GetLifecyclePolicy", - "ecr:GetLifecyclePolicyPreview", - "ecr:ListTagsForResource", - "ecr:DescribeImageScanFindings", - ], - resources: ["*"], - }), - ], - }); - - new iam.Policy(this, "PipelinePolicyCloudWatchLogEvents", { - roles: [roleBatchInstancePipeline], - statements: [ - new iam.PolicyStatement({ - actions: ["logs:GetLogEvents"], - resources: [ - `arn:aws:logs:${Aws.REGION}:${Aws.ACCOUNT_ID}:log-group:/aws/batch/job/:nf-*`, - ], - }), - ], - }); - - new iam.Policy(this, "PipelinePolicyAppConfig", { - roles: [roleBatchInstancePipeline], - statements: [ - new iam.PolicyStatement({ - actions: [ - "appconfig:GetLatestConfiguration", - "appconfig:StartConfigurationSession", - ], - // should be tightened - resources: [`*`], - }), - ], - }); - - roleBatchInstancePipeline.attachInlinePolicy( - new iam.Policy(this, "PipelinePolicyPassRole", { - statements: [ - new iam.PolicyStatement({ - actions: ["iam:PassRole"], - resources: [roleBatchInstanceTask.roleArn], - }), - ], - }), - ); - - const launchTemplatePipeline = this.getLaunchTemplate({ - securityGroup: securityGroup, - launchTemplateName: "oncoanalyser-pipeline", - }); - - const computeEnvironmentPipeline = - new batch.ManagedEc2EcsComputeEnvironment( - this, - "ComputeEnvironmentPipeline", - { - allocationStrategy: batch.AllocationStrategy.BEST_FIT_PROGRESSIVE, - instanceRole: roleBatchInstancePipeline, - instanceTypes: props.pipelineInstanceTypes, - launchTemplate: launchTemplatePipeline, - maxvCpus: props.pipelineMaxCpus, - securityGroups: [], - useOptimalInstanceClasses: false, - vpc: vpc, - vpcSubnets: { - subnetType: ec2.SubnetType.PUBLIC, - }, - }, - ); - - const jobQueuePipeline = new batch.JobQueue(this, "JobQueuePipeline", { - jobQueueName: props.pipelineQueueName, - computeEnvironments: [ - { computeEnvironment: computeEnvironmentPipeline, order: 1 }, - ], - }); - - // create Docker image for pipeline - const image = new ecrAssets.DockerImageAsset(this, "DockerImage", { - directory: path.join(__dirname, "resources"), - platform: Platform.LINUX_AMD64, - buildArgs: { - NEXTFLOW_PLUGINS: NEXTFLOW_PLUGINS.join(","), - SOFTWARE_GIT_REPO: props.gitRepo, - SOFTWARE_GIT_BRANCH: props.gitBranch - }, - }); - - // Bucket permissions - const nfBucket = s3.Bucket.fromBucketName( - this, - "S3Bucket", - props.bucket.bucket, - ); - - nfBucket.grantRead( - roleBatchInstancePipeline, - `${props.bucket.inputPrefix}/*`, - ); - nfBucket.grantRead(roleBatchInstanceTask, `${props.bucket.inputPrefix}/*`); - - nfBucket.grantRead( - roleBatchInstancePipeline, - `${props.bucket.refDataPrefix}/*`, - ); - nfBucket.grantRead( - roleBatchInstanceTask, - `${props.bucket.refDataPrefix}/*`, - ); - - nfBucket.grantReadWrite( - roleBatchInstancePipeline, - `${props.bucket.outputPrefix}/*`, - ); - nfBucket.grantReadWrite( - roleBatchInstanceTask, - `${props.bucket.outputPrefix}/*`, - ); - - const config = new NextflowConfigConstruct(this, "NextflowConfig", { - bucket: props.bucket, - tasksInstanceRole: roleBatchInstanceTask, - tasksJobQueue: jobQueueTask, - copyToLocalEcr: false, - }); - - // Create job definition for pipeline execution - const jobDefinition = new batch.EcsJobDefinition(this, "JobDefinition", { - jobDefinitionName: props.pipelineJobDefinitionName, - container: new batch.EcsEc2ContainerDefinition( - this, - "EcsEc2ContainerDefinition", - { - cpu: 1, - image: ContainerImage.fromDockerImageAsset(image), - command: ["true"], - memory: cdk.Size.gibibytes(1), - jobRole: roleBatchInstancePipeline, - environment: config.getEnvironmentVariables(), - }, - ), - }); - } - - getLaunchTemplate(args: { - securityGroup: ec2.ISecurityGroup; - launchTemplateName?: string; - }) { - const userData = ec2.UserData.custom( - `MIME-Version: 1.0 -Content-Type: multipart/mixed; boundary="==BOUNDARY==" - ---==BOUNDARY== -Content-Type: text/cloud-config; charset="us-ascii" - -packages: - - btrfs-progs - - git - - jq - - lvm2 - - sed - - unzip - - wget - ---==BOUNDARY== -Content-Type: text/x-shellscript; charset="us-ascii" - -#!/bin/bash -curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip -unzip -q /tmp/awscliv2.zip -d /tmp/ - -/tmp/aws/install --install-dir /opt/awscliv2/aws-cli/ --bin-dir /opt/awscliv2/bin/ -ln -s /opt/awscliv2/bin/aws /usr/local/bin/ - -git clone https://github.com/awslabs/amazon-ebs-autoscale /tmp/amazon-ebs-autoscale/ -(cd /tmp/amazon-ebs-autoscale/ && git checkout 6db0c70) - -bash /tmp/amazon-ebs-autoscale/install.sh - -rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ ---==BOUNDARY==--`, - ); - const ltName = args.launchTemplateName ?? "oncoanalyser"; - const constructId = `LaunchTemplate-${ltName}`; - const launchTemplate = new ec2.LaunchTemplate(this, constructId, { - associatePublicIpAddress: true, - userData: userData, - securityGroup: args.securityGroup, - }); - - cdk.Tags.of(launchTemplate).add("Name", ltName); - return launchTemplate; - } -} \ No newline at end of file diff --git a/lib/ec2-user-data.txt b/lib/ec2-user-data.txt new file mode 100644 index 0000000..144a0c5 --- /dev/null +++ b/lib/ec2-user-data.txt @@ -0,0 +1,32 @@ +MIME-Version: 1.0 +Content-Type: multipart/mixed; boundary="==BOUNDARY==" + +--==BOUNDARY== +Content-Type: text/cloud-config; charset="us-ascii" + +packages: + - btrfs-progs + - git + - jq + - lvm2 + - sed + - unzip + - wget + +--==BOUNDARY== +Content-Type: text/x-shellscript; charset="us-ascii" + +#!/bin/bash +curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip +unzip -q /tmp/awscliv2.zip -d /tmp/ + +/tmp/aws/install --install-dir /opt/awscliv2/aws-cli/ --bin-dir /opt/awscliv2/bin/ +ln -s /opt/awscliv2/bin/aws /usr/local/bin/ + +git clone https://github.com/awslabs/amazon-ebs-autoscale /tmp/amazon-ebs-autoscale/ +(cd /tmp/amazon-ebs-autoscale/ && git checkout 6db0c70) + +bash /tmp/amazon-ebs-autoscale/install.sh + +rm -rf /tmp/awscliv2.zip /tmp/aws/ /tmp/amazon-ebs-autoscale/ +--==BOUNDARY==-- diff --git a/lib/index.ts b/lib/index.ts new file mode 100644 index 0000000..8f96be7 --- /dev/null +++ b/lib/index.ts @@ -0,0 +1,5 @@ +export * from "./oncoanalyser"; +export * from "./nextflow-config"; +export * from "./nextflow-task-environment"; +export * from "./nextflow-pipeline-environment"; +export * from "./oncoanalyser-job-definition"; diff --git a/lib/task_docker_images/Dockerfile b/lib/nextflow-config/Dockerfile similarity index 100% rename from lib/task_docker_images/Dockerfile rename to lib/nextflow-config/Dockerfile diff --git a/lib/nextflow-config-construct.ts b/lib/nextflow-config/index.ts similarity index 90% rename from lib/nextflow-config-construct.ts rename to lib/nextflow-config/index.ts index 11b383c..506fff1 100644 --- a/lib/nextflow-config-construct.ts +++ b/lib/nextflow-config/index.ts @@ -2,30 +2,50 @@ import { join } from "path"; import { readFileSync } from "fs"; import * as Handlebars from "handlebars"; import { Construct } from "constructs"; -import { BucketProps } from "./application-stack"; +import { BucketProps } from "../oncoanalyser"; import * as appconfig from "aws-cdk-lib/aws-appconfig"; import { DeletionProtectionCheck } from "aws-cdk-lib/aws-appconfig"; import { DockerImageAsset, Platform } from "aws-cdk-lib/aws-ecr-assets"; import { IRole } from "aws-cdk-lib/aws-iam"; import { IJobQueue } from "aws-cdk-lib/aws-batch"; import { Duration } from "aws-cdk-lib"; -import { NEXTFLOW_PLUGINS } from "./dependencies"; +import { NEXTFLOW_PLUGINS } from "../dependencies"; -export type NextflowConfigProps = { - bucket: BucketProps; - tasksInstanceRole: IRole; - tasksJobQueue: IJobQueue; - - // if present and true, instructs the construct to make local ECR assets mirroring - // the standard task Docker images - // otherwise, the pipeline will launch Docker images directly from their - // public repository (like quay.io or dockerhub) +export interface NextflowConfigProps { + /** + * The S3 bucket to use for the Nextflow environment. + */ + readonly bucket: BucketProps; + /** + * The role to use for the tasks instance. + */ + readonly tasksInstanceRole: IRole; + /** + * The job queue to use for the tasks. + */ + readonly tasksJobQueue: IJobQueue; + /** + * If true, instructs the construct to make local ECR assets mirroring the standard task Docker images. + * otherwise, the pipeline will launch Docker images directly from their public repository (like quay.io or dockerhub) + */ readonly copyToLocalEcr?: boolean; -}; +} +/** + * Construct that creates an AppConfig configuration for the Nextflow pipeline environment. + */ export class NextflowConfigConstruct extends Construct { + /** + * The AppConfig application that is created. + */ private readonly application: appconfig.Application; + /** + * The AppConfig environment that is created. + */ private readonly environment: appconfig.Environment; + /** + * The AppConfig hosted configuration that is created. + */ private readonly hostedConfiguration: appconfig.HostedConfiguration; constructor(scope: Construct, id: string, props: NextflowConfigProps) { @@ -49,7 +69,7 @@ export class NextflowConfigConstruct extends Construct { // docker image - but is maintained as an asset within the CDK setup // this means CDK will handle deploying it to ECR for us const imageAsset = new DockerImageAsset(this, configName, { - directory: join(__dirname, "task_docker_images"), + directory: join(__dirname), platform: Platform.LINUX_AMD64, // because the image base name is passed into Docker - the actual Docker checksum // itself won't change even when the image base does... so we need to add the name/tag into the hash @@ -237,7 +257,7 @@ export class NextflowConfigConstruct extends Construct { ); const nextflowConfigTemplate = readFileSync( - join(__dirname, "resources/nextflow_aws.template.config"), + join(__dirname, "..", "nextflow_aws.template.config"), { encoding: "utf-8" }, ); const nextflowConfigTemplateCompiled = Handlebars.compile( @@ -294,7 +314,7 @@ export class NextflowConfigConstruct extends Construct { // ); } - public getEnvironmentVariables(): Record { + public retrieveEnvironmentVariables(): Record { return { ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_APPLICATION: this.application.applicationId, diff --git a/lib/nextflow-pipeline-environment/index.ts b/lib/nextflow-pipeline-environment/index.ts new file mode 100644 index 0000000..7625251 --- /dev/null +++ b/lib/nextflow-pipeline-environment/index.ts @@ -0,0 +1,243 @@ +import { Construct } from "constructs"; +import { Aws } from "aws-cdk-lib"; + +import { + IVpc, + SecurityGroup, + SubnetType, + InstanceType, +} from "aws-cdk-lib/aws-ec2"; +import { + AllocationStrategy, + JobQueue, + ManagedEc2EcsComputeEnvironment, +} from "aws-cdk-lib/aws-batch"; +import { + CompositePrincipal, + ManagedPolicy, + Policy, + PolicyStatement, + Role, + ServicePrincipal, +} from "aws-cdk-lib/aws-iam"; +import { createLaunchTemplate } from "../utils"; +import { IBucket } from "aws-cdk-lib/aws-s3"; + +export interface NextflowPipelineEnvironmentProps { + /** + * VPC to run the Nextflow batch environment in. + */ + readonly vpc: IVpc; + /** + * The security group to use for the task jobs. + */ + readonly securityGroup: SecurityGroup; + /** + * The name of the pipeline job queue. + */ + readonly pipelineQueueName: string; + /** + * The ec2 instance types to use for the task jobs. + */ + readonly instanceTypes: InstanceType[]; + /** + * The maximum number of vCPUs that can be used by the compute environment. + */ + readonly taskMaxCpus: number; + /** + * The S3 bucket to use for the Nextflow environment. + */ + readonly nfBucket: IBucket; + /** + * The patterns to grant read access to the bucket. + */ + readonly nfBucketGrantRead?: string[]; + /** + * The patterns to grant read-write access to the bucket. + */ + readonly nfBucketGrantReadWrite?: string[]; + /** + * Additional policies to attach to the instance role. + */ + readonly additionalInstanceRolePolicies?: Policy[]; +} + +/** + * Create a Nextflow batch compute environment for **Pipeline** jobs. + */ +export class NextflowPipelineEnvironment extends Construct { + /** + * The compute environment task that is created. + */ + computeEnvironmentPipeline: ManagedEc2EcsComputeEnvironment; + /** + * The instance role that is created. + */ + instanceRole: Role; + /** + * The job queue that is created for the compute environment. + */ + jobQueue: JobQueue; + + constructor( + scope: Construct, + id: string, + props: NextflowPipelineEnvironmentProps, + ) { + super(scope, id); + + this.instanceRole = this.createInitInstanceRole(); + + if (props.additionalInstanceRolePolicies) { + this.addAdditionalPolicies(props.additionalInstanceRolePolicies); + } + + this.computeEnvironmentPipeline = new ManagedEc2EcsComputeEnvironment( + this, + "ComputeEnvironmentPipeline", + { + allocationStrategy: AllocationStrategy.BEST_FIT_PROGRESSIVE, + instanceRole: this.instanceRole, + instanceTypes: props.instanceTypes, + launchTemplate: createLaunchTemplate(this, { + securityGroup: props.securityGroup, + launchTemplateName: "oncoanalyser-pipeline", + }), + maxvCpus: props.taskMaxCpus, + securityGroups: [], + useOptimalInstanceClasses: false, + vpc: props.vpc, + vpcSubnets: { + subnetType: SubnetType.PUBLIC, + }, + }, + ); + + this.jobQueue = new JobQueue(this, "JobQueuePipeline", { + jobQueueName: props.pipelineQueueName, + computeEnvironments: [ + { computeEnvironment: this.computeEnvironmentPipeline, order: 1 }, + ], + }); + if (props.nfBucketGrantRead) { + for (const pattern of props.nfBucketGrantRead) { + props.nfBucket.grantRead(this.instanceRole, pattern); + } + } + + if (props.nfBucketGrantReadWrite) { + for (const pattern of props.nfBucketGrantReadWrite) { + props.nfBucket.grantReadWrite(this.instanceRole, pattern); + } + } + } + + private addAdditionalPolicies(policies: Policy[]) { + for (const policy of policies) { + policy.attachToRole(this.instanceRole); + } + } + + private createInitInstanceRole(): Role { + const instanceRole = new Role(this, "BatchInstanceRolePipeline", { + assumedBy: new CompositePrincipal( + new ServicePrincipal("ec2.amazonaws.com"), + new ServicePrincipal("ecs-tasks.amazonaws.com"), + ), + managedPolicies: [ + ManagedPolicy.fromAwsManagedPolicyName("AmazonS3ReadOnlyAccess"), + ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"), + ManagedPolicy.fromAwsManagedPolicyName( + "service-role/AmazonEC2ContainerServiceforEC2Role", + ), + ], + }); + + // NOTE(SW): the below policies are mostly those described by the Nextflow documents, some minor changes have been + // made so that the access is less permissive + new Policy(this, "PipelinePolicyBatchGeneral", { + roles: [instanceRole], + statements: [ + new PolicyStatement({ + actions: [ + "batch:ListJobs", + "batch:DescribeJobs", + "batch:DescribeJobQueues", + "batch:DescribeComputeEnvironments", + "batch:RegisterJobDefinition", + "batch:DescribeJobDefinitions", + ], + resources: ["*"], + }), + ], + }); + + new Policy(this, "PipelinePolicyInstances", { + roles: [instanceRole], + statements: [ + new PolicyStatement({ + actions: [ + "ecs:DescribeTasks", + "ec2:DescribeInstances", + "ec2:DescribeInstanceTypes", + "ec2:DescribeInstanceAttribute", + "ecs:DescribeContainerInstances", + "ec2:DescribeInstanceStatus", + ], + resources: ["*"], + }), + ], + }); + + new Policy(this, "PipelinePolicyECR", { + roles: [instanceRole], + statements: [ + new PolicyStatement({ + actions: [ + "ecr:GetAuthorizationToken", + "ecr:BatchCheckLayerAvailability", + "ecr:GetDownloadUrlForLayer", + "ecr:GetRepositoryPolicy", + "ecr:DescribeRepositories", + "ecr:ListImages", + "ecr:DescribeImages", + "ecr:BatchGetImage", + "ecr:GetLifecyclePolicy", + "ecr:GetLifecyclePolicyPreview", + "ecr:ListTagsForResource", + "ecr:DescribeImageScanFindings", + ], + resources: ["*"], + }), + ], + }); + + new Policy(this, "PipelinePolicyCloudWatchLogEvents", { + roles: [instanceRole], + statements: [ + new PolicyStatement({ + actions: ["logs:GetLogEvents"], + resources: [ + `arn:aws:logs:${Aws.REGION}:${Aws.ACCOUNT_ID}:log-group:/aws/batch/job/:nf-*`, + ], + }), + ], + }); + + new Policy(this, "PipelinePolicyAppConfig", { + roles: [instanceRole], + statements: [ + new PolicyStatement({ + actions: [ + "appconfig:GetLatestConfiguration", + "appconfig:StartConfigurationSession", + ], + // should be tightened + resources: [`*`], + }), + ], + }); + + return instanceRole; + } +} diff --git a/lib/nextflow-task-environment/index.ts b/lib/nextflow-task-environment/index.ts new file mode 100644 index 0000000..10b1d8b --- /dev/null +++ b/lib/nextflow-task-environment/index.ts @@ -0,0 +1,129 @@ +import { Construct } from "constructs"; +import { + IVpc, + SecurityGroup, + SubnetType, + InstanceType, +} from "aws-cdk-lib/aws-ec2"; +import { + AllocationStrategy, + JobQueue, + ManagedEc2EcsComputeEnvironment, +} from "aws-cdk-lib/aws-batch"; +import { + CompositePrincipal, + ManagedPolicy, + Role, + ServicePrincipal, +} from "aws-cdk-lib/aws-iam"; +import { createLaunchTemplate } from "../utils"; +import { IBucket } from "aws-cdk-lib/aws-s3"; + +export interface NextflowTaskEnvironmentProps { + /** + * VPC to run the Nextflow batch environment in. + */ + readonly vpc: IVpc; + /** + * The security group to use for the task jobs. + */ + readonly securityGroup: SecurityGroup; + /** + * The ec2 instance types to use for the task jobs. + */ + readonly instanceTypes: InstanceType[]; + /** + * The maximum number of vCPUs that can be used by the compute environment. + */ + readonly taskMaxCpus: number; + /** + * The S3 bucket to use for the Nextflow environment. + */ + readonly nfBucket: IBucket; + /** + * The patterns to grant read access to the bucket. + */ + readonly nfBucketGrantRead?: string[]; + /** + * The patterns to grant read-write access to the bucket. + */ + readonly nfBucketGrantReadWrite?: string[]; +} + +/** + * Create a Nextflow batch compute environment for **tasks** jobs. + */ +export class NextflowTaskEnvironment extends Construct { + /** + * The compute environment task that is created. + */ + computeEnvironmentTask: ManagedEc2EcsComputeEnvironment; + /** + * The instance role that is created. + */ + instanceRole: Role; + /** + * The job queue that is created for the compute environment. + */ + jobQueue: JobQueue; + + constructor( + scope: Construct, + id: string, + props: NextflowTaskEnvironmentProps, + ) { + super(scope, id); + + this.instanceRole = new Role(this, "BatchInstanceRoleTask", { + assumedBy: new CompositePrincipal( + new ServicePrincipal("ec2.amazonaws.com"), + new ServicePrincipal("ecs-tasks.amazonaws.com"), + ), + managedPolicies: [ + ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore"), + ManagedPolicy.fromAwsManagedPolicyName( + "service-role/AmazonEC2ContainerServiceforEC2Role", + ), + ], + }); + + this.computeEnvironmentTask = new ManagedEc2EcsComputeEnvironment( + this, + "ComputeEnvironmentTask", + { + allocationStrategy: AllocationStrategy.BEST_FIT_PROGRESSIVE, + instanceRole: this.instanceRole, + instanceTypes: props.instanceTypes, + launchTemplate: createLaunchTemplate(this, { + securityGroup: props.securityGroup, + launchTemplateName: "oncoanalyser-task", + }), + maxvCpus: props.taskMaxCpus, + securityGroups: [], + useOptimalInstanceClasses: false, + vpc: props.vpc, + vpcSubnets: { + subnetType: SubnetType.PUBLIC, + }, + }, + ); + + this.jobQueue = new JobQueue(this, "JobQueueTask", { + computeEnvironments: [ + { computeEnvironment: this.computeEnvironmentTask, order: 1 }, + ], + }); + + if (props.nfBucketGrantRead) { + for (const pattern of props.nfBucketGrantRead) { + props.nfBucket.grantRead(this.instanceRole, pattern); + } + } + + if (props.nfBucketGrantReadWrite) { + for (const pattern of props.nfBucketGrantReadWrite) { + props.nfBucket.grantReadWrite(this.instanceRole, pattern); + } + } + } +} diff --git a/lib/resources/nextflow_aws.template.config b/lib/nextflow_aws.template.config similarity index 100% rename from lib/resources/nextflow_aws.template.config rename to lib/nextflow_aws.template.config diff --git a/lib/resources/Dockerfile b/lib/oncoanalyser-job-definition/Dockerfile similarity index 82% rename from lib/resources/Dockerfile rename to lib/oncoanalyser-job-definition/Dockerfile index f784610..df732af 100644 --- a/lib/resources/Dockerfile +++ b/lib/oncoanalyser-job-definition/Dockerfile @@ -30,8 +30,8 @@ RUN nextflow plugin install ${NEXTFLOW_PLUGINS} RUN \ git clone -b ${SOFTWARE_GIT_BRANCH} ${SOFTWARE_GIT_REPO} /root/pipeline/software/oncoanalyser/ +# The dockerfile should be executed one level above the oncoanalyser-job-definition directory COPY nextflow_aws.template.config /root/pipeline/other/ - -COPY run.sh /root/pipeline/other/ +COPY oncoanalyser-job-definition/run.sh /root/pipeline/other/ WORKDIR /root/pipeline/ diff --git a/lib/oncoanalyser-job-definition/index.ts b/lib/oncoanalyser-job-definition/index.ts new file mode 100644 index 0000000..048bc04 --- /dev/null +++ b/lib/oncoanalyser-job-definition/index.ts @@ -0,0 +1,77 @@ +import * as path from "path"; + +import { Construct } from "constructs"; +import { NEXTFLOW_PLUGINS } from "../dependencies"; +import { DockerImageAsset, Platform } from "aws-cdk-lib/aws-ecr-assets"; +import { + EcsEc2ContainerDefinition, + EcsJobDefinition, +} from "aws-cdk-lib/aws-batch"; +import { ContainerImage } from "aws-cdk-lib/aws-ecs"; +import { Size } from "aws-cdk-lib"; +import { IRole } from "aws-cdk-lib/aws-iam"; + +export interface OncoanalyserJobDefinitionProps { + /** + * The IAM role to use for the pipeline job definition. + */ + readonly jobRole: IRole; + /** + * The name of the pipeline job definition. + */ + readonly pipelineJobDefinitionName: string; + /** + * The environment variables to set in the container. + */ + readonly environment: Record; + /** + * The git repository of oncoanalyser to launch from nextflow. + */ + readonly gitRepo: string; + /** + * The git branch of oncoanalyser to launch from nextflow. + */ + readonly gitBranch: string; +} + +/** + * Create a job definition for running Oncoanalyser in AWS Batch. + */ +export class OncoanalyserJobDefinition extends Construct { + constructor( + scope: Construct, + id: string, + props: OncoanalyserJobDefinitionProps, + ) { + super(scope, id); + + // create Docker image for pipeline + const image = new DockerImageAsset(this, "DockerImage", { + directory: path.join(__dirname, ".."), + file: "oncoanalyser-job-definition/Dockerfile", + platform: Platform.LINUX_AMD64, + buildArgs: { + NEXTFLOW_PLUGINS: NEXTFLOW_PLUGINS.join(","), + SOFTWARE_GIT_REPO: props.gitRepo, + SOFTWARE_GIT_BRANCH: props.gitBranch, + }, + }); + + // Create job definition for pipeline execution + new EcsJobDefinition(this, "JobDefinition", { + jobDefinitionName: props.pipelineJobDefinitionName, + container: new EcsEc2ContainerDefinition( + this, + "EcsEc2ContainerDefinition", + { + cpu: 1, + image: ContainerImage.fromDockerImageAsset(image), + command: ["true"], + memory: Size.gibibytes(1), + jobRole: props.jobRole, + environment: props.environment, + }, + ), + }); + } +} diff --git a/lib/resources/run.sh b/lib/oncoanalyser-job-definition/run.sh similarity index 100% rename from lib/resources/run.sh rename to lib/oncoanalyser-job-definition/run.sh diff --git a/lib/oncoanalyser.ts b/lib/oncoanalyser.ts new file mode 100644 index 0000000..cc36fb8 --- /dev/null +++ b/lib/oncoanalyser.ts @@ -0,0 +1,188 @@ +import { Construct } from "constructs"; + +import * as ec2 from "aws-cdk-lib/aws-ec2"; +import * as iam from "aws-cdk-lib/aws-iam"; +import * as s3 from "aws-cdk-lib/aws-s3"; +import { Aws } from "aws-cdk-lib"; +import { NextflowConfigConstruct } from "./nextflow-config"; +import { OncoanalyserJobDefinition } from "./oncoanalyser-job-definition"; +import { IVpc, Vpc } from "aws-cdk-lib/aws-ec2"; +import { NextflowTaskEnvironment } from "./nextflow-task-environment"; +import { NextflowPipelineEnvironment } from "./nextflow-pipeline-environment"; +export interface BucketProps { + readonly bucket: string; + readonly inputPrefix: string; + readonly outputPrefix: string; + readonly refDataPrefix: string; +} + +export interface OncoanalyserProps { + /** + * The VPC to run the Oncoanalyser environment in. + */ + readonly vpc?: ec2.IVpc | string; + /** + * The name of the Nextflow pipeline job queue. + */ + readonly pipelineQueueName: string; + /** + * The name of the the job definition for Oncoanalyser to run. + */ + readonly pipelineJobDefinitionName: string; + /** + * The instance types to use for the pipeline jobs. + */ + readonly pipelineInstanceTypes: ec2.InstanceType[]; + /** + * The maximum number of vCPUs that can be used for the batch pipeline. + */ + readonly pipelineMaxCpus: number; + /** + * The instance types to use for the Nextflow task jobs. + */ + readonly taskInstanceTypes: ec2.InstanceType[]; + /** + * The maximum number of vCPUs that can be used for the batch tasks. + */ + readonly taskMaxCpus: number; + /* + * The S3 bucket to use for the Nextflow environment. + */ + readonly bucket: BucketProps; + /** + * The git repository of oncoanalyser to launch from nextflow. + */ + readonly gitRepo: string; + /** + * The git branch of oncoanalyser to launch from nextflow. + */ + readonly gitBranch: string; +} + +/** + * In general you would only need this construct to create the Oncoanalyser environment. + */ +export class Oncoanalyser extends Construct { + /** + * The VPC that the Oncoanalyser batch environment is running in. + */ + readonly vpc: ec2.IVpc; + /** + * The security group that the Oncoanalyser batch environment is running in. + */ + readonly securityGroup: ec2.SecurityGroup; + + constructor(scope: Construct, id: string, props: OncoanalyserProps) { + super(scope, id); + + this.vpc = this.lookupVpc(props.vpc); + + // Allows all outbound connections. + this.securityGroup = new ec2.SecurityGroup(this, "SecurityGroup", { + allowAllOutbound: true, + description: "oncoanalyser security group", + vpc: this.vpc, + }); + + const nfBucket = s3.Bucket.fromBucketName( + this, + "NextflowBucket", + props.bucket.bucket, + ); + + const nfTaskComputeEnv = new NextflowTaskEnvironment( + this, + "NextflowTaskComputeEnvironment", + { + vpc: this.vpc, + securityGroup: this.securityGroup, + instanceTypes: props.taskInstanceTypes, + taskMaxCpus: props.taskMaxCpus, + nfBucket: nfBucket, + nfBucketGrantRead: [ + `${props.bucket.inputPrefix}/*`, + `${props.bucket.refDataPrefix}/*`, + ], + nfBucketGrantReadWrite: [`${props.bucket.outputPrefix}/*`], + }, + ); + + const nfPipelineComputeEnv = new NextflowPipelineEnvironment( + this, + "NextflowPipelineEnvironment", + { + vpc: this.vpc, + securityGroup: this.securityGroup, + pipelineQueueName: props.pipelineQueueName, + instanceTypes: props.pipelineInstanceTypes, + taskMaxCpus: props.pipelineMaxCpus, + nfBucket: nfBucket, + nfBucketGrantRead: [ + `${props.bucket.inputPrefix}/*`, + `${props.bucket.refDataPrefix}/*`, + ], + nfBucketGrantReadWrite: [`${props.bucket.outputPrefix}/*`], + additionalInstanceRolePolicies: [ + new iam.Policy(this, "PipelinePolicyBatchJobs", { + statements: [ + new iam.PolicyStatement({ + actions: [ + "batch:CancelJob", + "batch:SubmitJob", + "batch:TagResource", + "batch:TerminateJob", + ], + + resources: [ + nfTaskComputeEnv.jobQueue.jobQueueArn, + // this is the naming format of the job definitions made by the pipeline node + `arn:aws:batch:${Aws.REGION}:${Aws.ACCOUNT_ID}:job-definition/nf-*`, + ], + }), + ], + }), + new iam.Policy(this, "PipelinePolicyPassRole", { + statements: [ + new iam.PolicyStatement({ + actions: ["iam:PassRole"], + resources: [nfTaskComputeEnv.instanceRole.roleArn], + }), + ], + }), + ], + }, + ); + + const config = new NextflowConfigConstruct(this, "NextflowConfig", { + bucket: props.bucket, + tasksInstanceRole: nfTaskComputeEnv.instanceRole, + tasksJobQueue: nfTaskComputeEnv.jobQueue, + copyToLocalEcr: false, + }); + + new OncoanalyserJobDefinition(this, "OncoanalyserJobDefinition", { + jobRole: nfPipelineComputeEnv.instanceRole, + pipelineJobDefinitionName: props.pipelineJobDefinitionName, + environment: config.retrieveEnvironmentVariables(), + gitRepo: props.gitRepo, + gitBranch: props.gitBranch, + }); + } + + /** + * Lookup the VPC to use for the Oncoanalyser environment. + */ + private lookupVpc(vpc?: IVpc | string): IVpc { + if (vpc === undefined) { + return Vpc.fromLookup(this, "VPC", { + isDefault: true, + }); + } else if (typeof vpc == "string") { + return Vpc.fromLookup(this, "VPC", { + vpcName: vpc, + }); + } else { + return vpc; + } + } +} diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 0000000..7caab2e --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,31 @@ +import { Construct } from "constructs"; +import { Tags } from "aws-cdk-lib"; +import { ISecurityGroup, LaunchTemplate, UserData } from "aws-cdk-lib/aws-ec2"; +import { readFileSync } from "fs"; +import * as path from "path"; + +export function createLaunchTemplate( + construct: Construct, + { + securityGroup, + launchTemplateName, + }: { + securityGroup: ISecurityGroup; + launchTemplateName?: string; + }, +) { + const userDataFilePath = path.resolve(__dirname, "ec2-user-data.txt"); + const userDataContent = readFileSync(path.resolve(userDataFilePath), "utf-8"); + const userData = UserData.custom(userDataContent); + + const ltName = launchTemplateName ?? "oncoanalyser"; + const constructId = `LaunchTemplate-${ltName}`; + const launchTemplate = new LaunchTemplate(construct, constructId, { + associatePublicIpAddress: true, + userData: userData, + securityGroup: securityGroup, + }); + + Tags.of(launchTemplate).add("Name", ltName); + return launchTemplate; +} diff --git a/package-lock.json b/package-lock.json index b4db762..ac8ef37 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,18 @@ { - "name": "oncoanalyser-stack", + "name": "@umccr/oncoanalyser-aws", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "oncoanalyser-stack", + "name": "@umccr/oncoanalyser-aws", "version": "0.1.0", + "bundleDependencies": [ + "handlebars" + ], + "license": "MIT", "dependencies": { - "aws-cdk-lib": "2.177.0", "cdk-ecr-deployment": "^3.0.33", - "constructs": "^10.0.0", "handlebars": "^4.7.8" }, "bin": { @@ -20,11 +22,20 @@ "@types/jest": "^29.5.14", "@types/node": "22.7.9", "aws-cdk": "2.177.0", + "aws-cdk-lib": "2.177.0", + "constructs": "10.1.312", "jest": "^29.7.0", + "jsii": "^5.7.6", + "jsii-pacmak": "^1.108.0", "prettier": "3.5.2", + "publib": "^0.2.955", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typescript": "~5.6.3" + }, + "peerDependencies": { + "aws-cdk-lib": "2.177.0", + "constructs": "^10.1.312" } }, "node_modules/@ampproject/remapping": { @@ -91,6 +102,705 @@ "node": ">=10" } }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-codeartifact": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-codeartifact/-/client-codeartifact-3.758.0.tgz", + "integrity": "sha512-SiLokm9+I+M/h1XnCrbXW+BblnOG5SfGT5LekOafivSSEDZwNaM/CEFM1BXaJUOSEipf7c62WT9HgPQa2hj94w==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.758.0", + "@aws-sdk/credential-provider-node": "3.758.0", + "@aws-sdk/middleware-host-header": "3.734.0", + "@aws-sdk/middleware-logger": "3.734.0", + "@aws-sdk/middleware-recursion-detection": "3.734.0", + "@aws-sdk/middleware-user-agent": "3.758.0", + "@aws-sdk/region-config-resolver": "3.734.0", + "@aws-sdk/types": "3.734.0", + "@aws-sdk/util-endpoints": "3.743.0", + "@aws-sdk/util-user-agent-browser": "3.734.0", + "@aws-sdk/util-user-agent-node": "3.758.0", + "@smithy/config-resolver": "^4.0.1", + "@smithy/core": "^3.1.5", + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/hash-node": "^4.0.1", + "@smithy/invalid-dependency": "^4.0.1", + "@smithy/middleware-content-length": "^4.0.1", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-retry": "^4.0.7", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/protocol-http": "^5.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-body-length-node": "^4.0.0", + "@smithy/util-defaults-mode-browser": "^4.0.7", + "@smithy/util-defaults-mode-node": "^4.0.7", + "@smithy/util-endpoints": "^3.0.1", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", + "@smithy/util-stream": "^4.1.2", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.758.0.tgz", + "integrity": "sha512-8bOXVYtf/0OUN0jXTIHLv3V0TAS6kvvCRAy7nmiL/fDde0O+ChW1WZU7CVPAOtFEpFCdKskDcxFspM7m1k6qyg==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.758.0", + "@aws-sdk/credential-provider-node": "3.758.0", + "@aws-sdk/middleware-host-header": "3.734.0", + "@aws-sdk/middleware-logger": "3.734.0", + "@aws-sdk/middleware-recursion-detection": "3.734.0", + "@aws-sdk/middleware-user-agent": "3.758.0", + "@aws-sdk/region-config-resolver": "3.734.0", + "@aws-sdk/types": "3.734.0", + "@aws-sdk/util-endpoints": "3.743.0", + "@aws-sdk/util-user-agent-browser": "3.734.0", + "@aws-sdk/util-user-agent-node": "3.758.0", + "@smithy/config-resolver": "^4.0.1", + "@smithy/core": "^3.1.5", + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/hash-node": "^4.0.1", + "@smithy/invalid-dependency": "^4.0.1", + "@smithy/middleware-content-length": "^4.0.1", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-retry": "^4.0.7", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/protocol-http": "^5.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-body-length-node": "^4.0.0", + "@smithy/util-defaults-mode-browser": "^4.0.7", + "@smithy/util-defaults-mode-node": "^4.0.7", + "@smithy/util-endpoints": "^3.0.1", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.758.0.tgz", + "integrity": "sha512-BoGO6IIWrLyLxQG6txJw6RT2urmbtlwfggapNCrNPyYjlXpzTSJhBYjndg7TpDATFd0SXL0zm8y/tXsUXNkdYQ==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.758.0", + "@aws-sdk/middleware-host-header": "3.734.0", + "@aws-sdk/middleware-logger": "3.734.0", + "@aws-sdk/middleware-recursion-detection": "3.734.0", + "@aws-sdk/middleware-user-agent": "3.758.0", + "@aws-sdk/region-config-resolver": "3.734.0", + "@aws-sdk/types": "3.734.0", + "@aws-sdk/util-endpoints": "3.743.0", + "@aws-sdk/util-user-agent-browser": "3.734.0", + "@aws-sdk/util-user-agent-node": "3.758.0", + "@smithy/config-resolver": "^4.0.1", + "@smithy/core": "^3.1.5", + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/hash-node": "^4.0.1", + "@smithy/invalid-dependency": "^4.0.1", + "@smithy/middleware-content-length": "^4.0.1", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-retry": "^4.0.7", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/protocol-http": "^5.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-body-length-node": "^4.0.0", + "@smithy/util-defaults-mode-browser": "^4.0.7", + "@smithy/util-defaults-mode-node": "^4.0.7", + "@smithy/util-endpoints": "^3.0.1", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.758.0.tgz", + "integrity": "sha512-0RswbdR9jt/XKemaLNuxi2gGr4xGlHyGxkTdhSQzCyUe9A9OPCoLl3rIESRguQEech+oJnbHk/wuiwHqTuP9sg==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "3.734.0", + "@smithy/core": "^3.1.5", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/signature-v4": "^5.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/util-middleware": "^4.0.1", + "fast-xml-parser": "4.4.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-cognito-identity": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.758.0.tgz", + "integrity": "sha512-y/rHZqyChlEkNRr59gn4hv0gjhJwGmdCdW0JI1K9p3P9p7EurWGjr2M6+goTn3ilOlcAwrl5oFKR5jLt27TkOA==", + "dev": true, + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.758.0.tgz", + "integrity": "sha512-N27eFoRrO6MeUNumtNHDW9WOiwfd59LPXPqDrIa3kWL/s+fOKFHb9xIcF++bAwtcZnAxKkgpDCUP+INNZskE+w==", + "dev": true, + "dependencies": { + "@aws-sdk/core": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.758.0.tgz", + "integrity": "sha512-Xt9/U8qUCiw1hihztWkNeIR+arg6P+yda10OuCHX6kFVx3auTlU7+hCqs3UxqniGU4dguHuftf3mRpi5/GJ33Q==", + "dev": true, + "dependencies": { + "@aws-sdk/core": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/property-provider": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/util-stream": "^4.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.758.0.tgz", + "integrity": "sha512-cymSKMcP5d+OsgetoIZ5QCe1wnp2Q/tq+uIxVdh9MbfdBBEnl9Ecq6dH6VlYS89sp4QKuxHxkWXVnbXU3Q19Aw==", + "dev": true, + "dependencies": { + "@aws-sdk/core": "3.758.0", + "@aws-sdk/credential-provider-env": "3.758.0", + "@aws-sdk/credential-provider-http": "3.758.0", + "@aws-sdk/credential-provider-process": "3.758.0", + "@aws-sdk/credential-provider-sso": "3.758.0", + "@aws-sdk/credential-provider-web-identity": "3.758.0", + "@aws-sdk/nested-clients": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/credential-provider-imds": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.758.0.tgz", + "integrity": "sha512-+DaMv63wiq7pJrhIQzZYMn4hSarKiizDoJRvyR7WGhnn0oQ/getX9Z0VNCV3i7lIFoLNTb7WMmQ9k7+z/uD5EQ==", + "dev": true, + "dependencies": { + "@aws-sdk/credential-provider-env": "3.758.0", + "@aws-sdk/credential-provider-http": "3.758.0", + "@aws-sdk/credential-provider-ini": "3.758.0", + "@aws-sdk/credential-provider-process": "3.758.0", + "@aws-sdk/credential-provider-sso": "3.758.0", + "@aws-sdk/credential-provider-web-identity": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/credential-provider-imds": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.758.0.tgz", + "integrity": "sha512-AzcY74QTPqcbXWVgjpPZ3HOmxQZYPROIBz2YINF0OQk0MhezDWV/O7Xec+K1+MPGQO3qS6EDrUUlnPLjsqieHA==", + "dev": true, + "dependencies": { + "@aws-sdk/core": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.758.0.tgz", + "integrity": "sha512-x0FYJqcOLUCv8GLLFDYMXRAQKGjoM+L0BG4BiHYZRDf24yQWFCAZsCQAYKo6XZYh2qznbsW6f//qpyJ5b0QVKQ==", + "dev": true, + "dependencies": { + "@aws-sdk/client-sso": "3.758.0", + "@aws-sdk/core": "3.758.0", + "@aws-sdk/token-providers": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.758.0.tgz", + "integrity": "sha512-XGguXhBqiCXMXRxcfCAVPlMbm3VyJTou79r/3mxWddHWF0XbhaQiBIbUz6vobVTD25YQRbWSmSch7VA8kI5Lrw==", + "dev": true, + "dependencies": { + "@aws-sdk/core": "3.758.0", + "@aws-sdk/nested-clients": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-providers": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.758.0.tgz", + "integrity": "sha512-BaGVBdm9ynsErIc/mLuUwJ1OQcL/pkhCuAm24jpsif3evZ5wgyZnEAZB2yRin+mQnQaQT3L+KvTbdKGfjL8+fQ==", + "dev": true, + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.758.0", + "@aws-sdk/core": "3.758.0", + "@aws-sdk/credential-provider-cognito-identity": "3.758.0", + "@aws-sdk/credential-provider-env": "3.758.0", + "@aws-sdk/credential-provider-http": "3.758.0", + "@aws-sdk/credential-provider-ini": "3.758.0", + "@aws-sdk/credential-provider-node": "3.758.0", + "@aws-sdk/credential-provider-process": "3.758.0", + "@aws-sdk/credential-provider-sso": "3.758.0", + "@aws-sdk/credential-provider-web-identity": "3.758.0", + "@aws-sdk/nested-clients": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/core": "^3.1.5", + "@smithy/credential-provider-imds": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.734.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.734.0.tgz", + "integrity": "sha512-LW7RRgSOHHBzWZnigNsDIzu3AiwtjeI2X66v+Wn1P1u+eXssy1+up4ZY/h+t2sU4LU36UvEf+jrZti9c6vRnFw==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "3.734.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.734.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.734.0.tgz", + "integrity": "sha512-mUMFITpJUW3LcKvFok176eI5zXAUomVtahb9IQBwLzkqFYOrMJvWAvoV4yuxrJ8TlQBG8gyEnkb9SnhZvjg67w==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "3.734.0", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.734.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.734.0.tgz", + "integrity": "sha512-CUat2d9ITsFc2XsmeiRQO96iWpxSKYFjxvj27Hc7vo87YUHRnfMfnc8jw1EpxEwMcvBD7LsRa6vDNky6AjcrFA==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "3.734.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.758.0.tgz", + "integrity": "sha512-iNyehQXtQlj69JCgfaOssgZD4HeYGOwxcaKeG6F+40cwBjTAi0+Ph1yfDwqk2qiBPIRWJ/9l2LodZbxiBqgrwg==", + "dev": true, + "dependencies": { + "@aws-sdk/core": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@aws-sdk/util-endpoints": "3.743.0", + "@smithy/core": "^3.1.5", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.758.0.tgz", + "integrity": "sha512-YZ5s7PSvyF3Mt2h1EQulCG93uybprNGbBkPmVuy/HMMfbFTt4iL3SbKjxqvOZelm86epFfj7pvK7FliI2WOEcg==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.758.0", + "@aws-sdk/middleware-host-header": "3.734.0", + "@aws-sdk/middleware-logger": "3.734.0", + "@aws-sdk/middleware-recursion-detection": "3.734.0", + "@aws-sdk/middleware-user-agent": "3.758.0", + "@aws-sdk/region-config-resolver": "3.734.0", + "@aws-sdk/types": "3.734.0", + "@aws-sdk/util-endpoints": "3.743.0", + "@aws-sdk/util-user-agent-browser": "3.734.0", + "@aws-sdk/util-user-agent-node": "3.758.0", + "@smithy/config-resolver": "^4.0.1", + "@smithy/core": "^3.1.5", + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/hash-node": "^4.0.1", + "@smithy/invalid-dependency": "^4.0.1", + "@smithy/middleware-content-length": "^4.0.1", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-retry": "^4.0.7", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/protocol-http": "^5.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-body-length-node": "^4.0.0", + "@smithy/util-defaults-mode-browser": "^4.0.7", + "@smithy/util-defaults-mode-node": "^4.0.7", + "@smithy/util-endpoints": "^3.0.1", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.734.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.734.0.tgz", + "integrity": "sha512-Lvj1kPRC5IuJBr9DyJ9T9/plkh+EfKLy+12s/mykOy1JaKHDpvj+XGy2YO6YgYVOb8JFtaqloid+5COtje4JTQ==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "3.734.0", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-config-provider": "^4.0.0", + "@smithy/util-middleware": "^4.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.758.0.tgz", + "integrity": "sha512-ckptN1tNrIfQUaGWm/ayW1ddG+imbKN7HHhjFdS4VfItsP0QQOB0+Ov+tpgb4MoNR4JaUghMIVStjIeHN2ks1w==", + "dev": true, + "dependencies": { + "@aws-sdk/nested-clients": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.734.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.734.0.tgz", + "integrity": "sha512-o11tSPTT70nAkGV1fN9wm/hAIiLPyWX6SuGf+9JyTp7S/rC2cFWhR26MvA69nplcjNaXVzB0f+QFrLXXjOqCrg==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.743.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.743.0.tgz", + "integrity": "sha512-sN1l559zrixeh5x+pttrnd0A3+r34r0tmPkJ/eaaMaAzXqsmKU/xYre9K3FNnsSS1J1k4PEfk/nHDTVUgFYjnw==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "3.734.0", + "@smithy/types": "^4.1.0", + "@smithy/util-endpoints": "^3.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.723.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.723.0.tgz", + "integrity": "sha512-Yf2CS10BqK688DRsrKI/EO6B8ff5J86NXe4C+VCysK7UOgN0l1zOTeTukZ3H8Q9tYYX3oaF1961o8vRkFm7Nmw==", + "dev": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.734.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.734.0.tgz", + "integrity": "sha512-xQTCus6Q9LwUuALW+S76OL0jcWtMOVu14q+GoLnWPUM7QeUw963oQcLhF7oq0CtaLLKyl4GOUfcwc773Zmwwng==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "3.734.0", + "@smithy/types": "^4.1.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.758.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.758.0.tgz", + "integrity": "sha512-A5EZw85V6WhoKMV2hbuFRvb9NPlxEErb4HPO6/SPXYY4QrjprIzScHxikqcWv1w4J3apB1wto9LPU3IMsYtfrw==", + "dev": true, + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.758.0", + "@aws-sdk/types": "3.734.0", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, "node_modules/@babel/code-frame": { "version": "7.26.2", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", @@ -742,228 +1452,868 @@ "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" + "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/reporters/node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "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.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@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.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "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.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@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.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "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.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsii/check-node": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.108.0.tgz", + "integrity": "sha512-wa8AGH31Cl0x1jU/KtM6JB32IurBmK1YiX5ZnCndifRCehLnS8DmJCPYrzJbKD4xqmHigaq6696fAnM/L7qIsw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.2", + "semver": "^7.6.3" + }, + "engines": { + "node": ">= 14.17.0" + } + }, + "node_modules/@jsii/check-node/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jsii/spec": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/@jsii/spec/-/spec-1.108.0.tgz", + "integrity": "sha512-YtebmBRy19UT1pKmxqlTqfW1OcFFjuU2zxxi+QFfM8KG1ahBlpcuz+3DE9gG1qTASIJJJI0fd8PaAiZ5gE40sQ==", + "dev": true, + "dependencies": { + "ajv": "^8.17.1" + }, + "engines": { + "node": ">= 14.17.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.1.tgz", + "integrity": "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.0.1.tgz", + "integrity": "sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ==", + "dev": true, + "dependencies": { + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-config-provider": "^4.0.0", + "@smithy/util-middleware": "^4.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.5.tgz", + "integrity": "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA==", + "dev": true, + "dependencies": { + "@smithy/middleware-serde": "^4.0.2", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-stream": "^4.1.2", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.1.tgz", + "integrity": "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg==", + "dev": true, + "dependencies": { + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.1.tgz", + "integrity": "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA==", + "dev": true, + "dependencies": { + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-base64": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.1.tgz", + "integrity": "sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.1.tgz", + "integrity": "sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", + "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", + "dev": true, + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.1.tgz", + "integrity": "sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ==", + "dev": true, + "dependencies": { + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.6.tgz", + "integrity": "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg==", + "dev": true, + "dependencies": { + "@smithy/core": "^3.1.5", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-middleware": "^4.0.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.7.tgz", + "integrity": "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ==", + "dev": true, + "dependencies": { + "@smithy/node-config-provider": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/service-error-classification": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.2.tgz", + "integrity": "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.1.tgz", + "integrity": "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.1.tgz", + "integrity": "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ==", + "dev": true, + "dependencies": { + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.3.tgz", + "integrity": "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA==", + "dev": true, + "dependencies": { + "@smithy/abort-controller": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.1.tgz", + "integrity": "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.0.1.tgz", + "integrity": "sha512-TE4cpj49jJNB/oHyh/cRVEgNZaoPaxd4vteJNB0yGidOCVR0jCw/hjPVsT8Q8FRmj8Bd3bFZt8Dh7xGCT+xMBQ==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.1.tgz", + "integrity": "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "@smithy/util-uri-escape": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.1.tgz", + "integrity": "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.1.tgz", + "integrity": "sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.1.tgz", + "integrity": "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.1.tgz", + "integrity": "sha512-nCe6fQ+ppm1bQuw5iKoeJ0MJfz2os7Ic3GBjOkLOPtavbD1ONoyE3ygjBfz2ythFWm4YnRm6OxW+8p/m9uCoIA==", + "dev": true, + "dependencies": { + "@smithy/is-array-buffer": "^4.0.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-hex-encoding": "^4.0.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-uri-escape": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.6.tgz", + "integrity": "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw==", + "dev": true, + "dependencies": { + "@smithy/core": "^3.1.5", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-stream": "^4.1.2", + "tslib": "^2.6.2" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "node_modules/@smithy/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.1.0.tgz", + "integrity": "sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" + "tslib": "^2.6.2" }, "engines": { - "node": ">=10" + "node": ">=18.0.0" } }, - "node_modules/@jest/reporters/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "node_modules/@smithy/url-parser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.1.tgz", + "integrity": "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "@smithy/querystring-parser": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=10" + "node": ">=18.0.0" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@smithy/util-base64": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", + "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "dev": true, - "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "node_modules/@smithy/util-body-length-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", + "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "node_modules/@smithy/util-body-length-node": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", + "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "node_modules/@smithy/util-buffer-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", + "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" + "@smithy/is-array-buffer": "^4.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "node_modules/@smithy/util-config-provider": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", + "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "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.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.7.tgz", + "integrity": "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.7.tgz", + "integrity": "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" + "@smithy/config-resolver": "^4.0.1", + "@smithy/credential-provider-imds": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=18.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==", + "node_modules/@smithy/util-endpoints": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.1.tgz", + "integrity": "sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA==", "dev": true, + "dependencies": { + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=6.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@smithy/util-hex-encoding": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", + "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", "dev": true, - "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, "engines": { - "node": ">=6.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "node_modules/@smithy/util-middleware": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.1.tgz", + "integrity": "sha512-HiLAvlcqhbzhuiOa0Lyct5IIlyIz0PQO5dnMlmQ/ubYM46dPInB+3yQGkfxsk6Q24Y0n3/JmcA1v5iEhmOF5mA==", + "dev": true, + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "node_modules/@smithy/util-retry": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.1.tgz", + "integrity": "sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@smithy/service-error-classification": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "node_modules/@smithy/util-stream": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.2.tgz", + "integrity": "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw==", "dev": true, - "license": "MIT" + "dependencies": { + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/types": "^4.1.0", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-hex-encoding": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "node_modules/@smithy/util-uri-escape": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", + "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "type-detect": "4.0.8" + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "node_modules/@smithy/util-utf8": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", + "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@smithy/util-buffer-from": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@tsconfig/node10": { @@ -1039,6 +2389,15 @@ "@babel/types": "^7.20.7" } }, + "node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/graceful-fs": { "version": "4.1.9", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", @@ -1115,6 +2474,16 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@xmldom/xmldom": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", + "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=14.6" + } + }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", @@ -1141,6 +2510,22 @@ "node": ">=0.4.0" } }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1676,6 +3061,12 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", + "dev": true + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1799,6 +3190,15 @@ ], "license": "CC-BY-4.0" }, + "node_modules/case": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", + "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/cdk-ecr-deployment": { "version": "3.0.33", "resolved": "https://registry.npmjs.org/cdk-ecr-deployment/-/cdk-ecr-deployment-3.0.33.tgz", @@ -2198,6 +3598,15 @@ "node": ">=12" } }, + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -2209,6 +3618,32 @@ "node": ">= 0.12.0" } }, + "node_modules/codemaker": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.108.0.tgz", + "integrity": "sha512-EwMvLf3tkBXllS4hZbr3WYm4kZiAH5Spd01MaRd+yJ636RfwIvpGgCGVqYbjW0RJ7yyfnakZ0HvCc8PxqyYWbA==", + "dev": true, + "dependencies": { + "camelcase": "^6.3.0", + "decamelize": "^5.0.1", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 14.17.0" + } + }, + "node_modules/codemaker/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/collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", @@ -2225,15 +3660,32 @@ "color-name": "~1.1.4" }, "engines": { - "node": ">=7.0.0" + "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/commonmark": { + "version": "0.31.2", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.31.2.tgz", + "integrity": "sha512-2fRLTyb9r/2835k5cwcAwOj0DEc44FARnMp5veGsJ+mEAZdi52sNopLu07ZyElQUz058H43whzlERDIaaSw4rg==", + "dev": true, + "dependencies": { + "entities": "~3.0.1", + "mdurl": "~1.0.1", + "minimist": "~1.2.8" + }, + "bin": { + "commonmark": "bin/commonmark" + }, + "engines": { + "node": "*" } }, - "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", @@ -2298,6 +3750,15 @@ "node": ">= 8" } }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2315,6 +3776,18 @@ } } }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", @@ -2340,6 +3813,15 @@ "node": ">=0.10.0" } }, + "node_modules/detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2413,6 +3895,18 @@ "dev": true, "license": "MIT" }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -2455,6 +3949,12 @@ "node": ">=4" } }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -2505,12 +4005,83 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.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/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] + }, + "node_modules/fast-xml-parser": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "peer": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -2579,6 +4150,26 @@ "node": ">=8" } }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2669,6 +4260,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "peer": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -2689,6 +4293,7 @@ "version": "4.7.8", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "inBundle": true, "license": "MIT", "dependencies": { "minimist": "^1.2.5", @@ -2812,6 +4417,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "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", @@ -2832,6 +4447,19 @@ "node": ">=6" } }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "peer": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -3589,6 +5217,261 @@ "node": ">=6" } }, + "node_modules/jsii": { + "version": "5.7.7", + "resolved": "https://registry.npmjs.org/jsii/-/jsii-5.7.7.tgz", + "integrity": "sha512-3FYMEhFs0w4EJuP65uCCeN9aJ7fQbTh5Uc5aWreTYkgVdF9JgWCoxR4ZUhIjQYQtpJCVA49I8qAEUmPg1Eu1QQ==", + "dev": true, + "dependencies": { + "@jsii/check-node": "1.108.0", + "@jsii/spec": "^1.108.0", + "case": "^1.6.3", + "chalk": "^4", + "fast-deep-equal": "^3.1.3", + "log4js": "^6.9.1", + "semver": "^7.7.1", + "semver-intersect": "^1.5.0", + "sort-json": "^2.0.1", + "spdx-license-list": "^6.9.0", + "typescript": "~5.7", + "yargs": "^17.7.2" + }, + "bin": { + "jsii": "bin/jsii" + }, + "engines": { + "node": ">= 18.12.0" + } + }, + "node_modules/jsii-pacmak": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.108.0.tgz", + "integrity": "sha512-qj/dGQkALH/YTMGUIyg+EgFD9+WXyrJPug8cwQureNyRK90gHLrTMo7oFQhhTlW2OVH6WAGlQO5FPLtkbujgmQ==", + "dev": true, + "dependencies": { + "@jsii/check-node": "1.108.0", + "@jsii/spec": "^1.108.0", + "clone": "^2.1.2", + "codemaker": "^1.108.0", + "commonmark": "^0.31.2", + "escape-string-regexp": "^4.0.0", + "fs-extra": "^10.1.0", + "jsii-reflect": "^1.108.0", + "semver": "^7.6.3", + "spdx-license-list": "^6.9.0", + "xmlbuilder": "^15.1.1", + "yargs": "^16.2.0" + }, + "bin": { + "jsii-pacmak": "bin/jsii-pacmak" + }, + "engines": { + "node": ">= 14.17.0" + }, + "peerDependencies": { + "jsii-rosetta": ">=5.4.0" + } + }, + "node_modules/jsii-pacmak/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/jsii-pacmak/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jsii-pacmak/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsii-pacmak/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsii-pacmak/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsii-reflect": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.108.0.tgz", + "integrity": "sha512-szlgEA2zFJhtSId2/GYHqosofkXgmkdo+baMMbv0HWt1UuwUK+pI+nYP9WX7mkNoNgIS1tVLre6AZZAZ7RmOfg==", + "dev": true, + "dependencies": { + "@jsii/check-node": "1.108.0", + "@jsii/spec": "^1.108.0", + "chalk": "^4", + "fs-extra": "^10.1.0", + "oo-ascii-tree": "^1.108.0", + "yargs": "^16.2.0" + }, + "bin": { + "jsii-tree": "bin/jsii-tree" + }, + "engines": { + "node": ">= 14.17.0" + } + }, + "node_modules/jsii-reflect/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/jsii-reflect/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsii-reflect/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsii-rosetta": { + "version": "5.7.7", + "resolved": "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-5.7.7.tgz", + "integrity": "sha512-+xNqFD+cBI7JWcigD3ui/bgJWLC1Mkof/nc5kzBBCovCQqcM7u/2B3mNDxYMVPpnjvJX3P7eITVFWzIC/Z/U2A==", + "dev": true, + "peer": true, + "dependencies": { + "@jsii/check-node": "1.108.0", + "@jsii/spec": "^1.108.0", + "@xmldom/xmldom": "^0.9.8", + "chalk": "^4", + "commonmark": "^0.31.2", + "fast-glob": "^3.3.3", + "jsii": "~5.7.0", + "semver": "^7.7.1", + "semver-intersect": "^1.5.0", + "stream-json": "^1.9.1", + "typescript": "~5.7", + "workerpool": "^6.5.1", + "yargs": "^17.7.2" + }, + "bin": { + "jsii-rosetta": "bin/jsii-rosetta" + }, + "engines": { + "node": ">= 18.12.0" + } + }, + "node_modules/jsii-rosetta/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "peer": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsii-rosetta/node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/jsii/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsii/node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "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", @@ -3596,6 +5479,12 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -3608,6 +5497,18 @@ "node": ">=6" } }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -3653,6 +5554,22 @@ "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3708,6 +5625,12 @@ "tmpl": "1.0.5" } }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3715,6 +5638,16 @@ "dev": true, "license": "MIT" }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -3754,11 +5687,21 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "inBundle": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3776,6 +5719,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "inBundle": true, "license": "MIT" }, "node_modules/node-int64": { @@ -3840,6 +5784,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/oo-ascii-tree": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.108.0.tgz", + "integrity": "sha512-aR++8J29Te6L+1pVi9phOvsMVdEj7245vpcJqmrzDOGHpJdZ3zm1hdh44pYfzV1PiDgG3S3fwtlLZilulwVAgg==", + "dev": true, + "engines": { + "node": ">= 14.17.0" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3883,6 +5845,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -3946,6 +5936,28 @@ "dev": true, "license": "MIT" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -4044,6 +6056,114 @@ "node": ">= 6" } }, + "node_modules/publib": { + "version": "0.2.955", + "resolved": "https://registry.npmjs.org/publib/-/publib-0.2.955.tgz", + "integrity": "sha512-dqOlYcD0SLHNDgfbieyy4c+RyKR3sP/sYQjvXKa3WrGbopmOwDqPouqNbb49ehpp5hqSzbeuKPyZ6+gW+11GGA==", + "dev": true, + "dependencies": { + "@aws-sdk/client-codeartifact": "^3.758.0", + "@aws-sdk/credential-providers": "^3.758.0", + "@aws-sdk/types": "^3.734.0", + "@types/fs-extra": "^8.0.0", + "fs-extra": "^8.0.0", + "glob": "10.0.0", + "p-queue": "6", + "shlex": "^2.1.2", + "yargs": "^17" + }, + "bin": { + "jsii-release": "bin/jsii-release-shim", + "jsii-release-ca": "bin/jsii-release-shim", + "jsii-release-golang": "bin/jsii-release-shim", + "jsii-release-maven": "bin/jsii-release-shim", + "jsii-release-npm": "bin/jsii-release-shim", + "jsii-release-nuget": "bin/jsii-release-shim", + "jsii-release-pypi": "bin/jsii-release-shim", + "jsii-release-shim": "bin/jsii-release-shim", + "publib": "bin/publib", + "publib-ca": "bin/publib-ca", + "publib-golang": "bin/publib-golang", + "publib-maven": "bin/publib-maven", + "publib-npm": "bin/publib-npm", + "publib-nuget": "bin/publib-nuget", + "publib-pypi": "bin/publib-pypi" + } + }, + "node_modules/publib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/publib/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/publib/node_modules/glob": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.0.0.tgz", + "integrity": "sha512-zmp9ZDC6NpDNLujV2W2n+3lH+BafIVZ4/ct+Yj3BMZTH/+bgm/eVjHzeFLwxJrrIGgjjS2eiQLlpurHsNlEAtQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^9.0.0", + "minipass": "^5.0.0", + "path-scurry": "^1.6.4" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/publib/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/publib/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/publib/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/pure-rand": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", @@ -4061,6 +6181,27 @@ ], "license": "MIT" }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true + }, "node_modules/react-is": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", @@ -4077,6 +6218,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -4130,6 +6280,47 @@ "node": ">=10" } }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "peer": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peer": true, + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -4139,6 +6330,15 @@ "semver": "bin/semver.js" } }, + "node_modules/semver-intersect": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.5.0.tgz", + "integrity": "sha512-BDjWX7yCC0haX4W/zrnV2JaMpVirwaEkGOBmgRQtH++F1N3xl9v7k9H44xfTqwl+yLNNSbMKosoVSTIiJVQ2Pw==", + "dev": true, + "dependencies": { + "semver": "^6.3.0" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4162,6 +6362,12 @@ "node": ">=8" } }, + "node_modules/shlex": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/shlex/-/shlex-2.1.2.tgz", + "integrity": "sha512-Nz6gtibMVgYeMEhUjp2KuwAgqaJA1K155dU/HuDaEJUGgnmYfVtVZah+uerVWdH8UGnyahhDCgABbYTbs254+w==", + "dev": true + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -4184,14 +6390,50 @@ "node": ">=8" } }, + "node_modules/sort-json": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sort-json/-/sort-json-2.0.1.tgz", + "integrity": "sha512-s8cs2bcsQCzo/P2T/uoU6Js4dS/jnX8+4xunziNoq9qmSpZNCrRIAIvp4avsz0ST18HycV4z/7myJ7jsHWB2XQ==", + "dev": true, + "dependencies": { + "detect-indent": "^5.0.0", + "detect-newline": "^2.1.0", + "minimist": "^1.2.0" + }, + "bin": { + "sort-json": "app/cmd.js" + } + }, + "node_modules/sort-json/node_modules/detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "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==", + "inBundle": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/spdx-license-list": { + "version": "6.9.0", + "resolved": "https://registry.npmjs.org/spdx-license-list/-/spdx-license-list-6.9.0.tgz", + "integrity": "sha512-L2jl5vc2j6jxWcNCvcVj/BW9A8yGIG02Dw+IUw0ZxDM70f7Ylf5Hq39appV1BI9yxyWQRpq2TQ1qaXvf+yjkqA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -4210,6 +6452,69 @@ "node": ">=10" } }, + "node_modules/stream-chain": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", + "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", + "dev": true, + "peer": true + }, + "node_modules/stream-json": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz", + "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==", + "dev": true, + "peer": true, + "dependencies": { + "stream-chain": "^2.2.5" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/streamroller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/streamroller/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -4285,6 +6590,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ] + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -4449,6 +6766,12 @@ } } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -4490,6 +6813,7 @@ "version": "3.19.3", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "inBundle": true, "license": "BSD-2-Clause", "optional": true, "bin": { @@ -4506,6 +6830,15 @@ "dev": true, "license": "MIT" }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", @@ -4537,6 +6870,19 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "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", @@ -4589,8 +6935,16 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "inBundle": true, "license": "MIT" }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true, + "peer": true + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -4628,6 +6982,15 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "engines": { + "node": ">=8.0" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 8f91278..147fdde 100644 --- a/package.json +++ b/package.json @@ -1,30 +1,64 @@ { - "name": "oncoanalyser-stack", + "name": "@umccr/oncoanalyser-aws", "version": "0.1.0", "author": "Stephen Watts", "bin": { "oncoanalyser-stack": "bin/oncoanalyser-stack.js" }, + "repository": { + "type": "git", + "url": "git+https://github.com/umccr/oncoanalyser-aws.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/umccr/oncoanalyser-aws/issues" + }, + "homepage": "https://github.com/umccr/oncoanalyser-aws#readme", + "keywords": [ + "aws", + "cdk", + "oncoanalyser" + ], + "stability": "stable", "scripts": { - "build": "tsc", - "watch": "tsc -w", "test": "jest", - "cdk": "cdk" + "cdk": "cdk", + "clean": "git clean -fXd", + "build": "jsii", + "build:watch": "jsii --watch", + "package": "jsii-pacmak -v" }, "devDependencies": { "@types/jest": "^29.5.14", "@types/node": "22.7.9", "aws-cdk": "2.177.0", + "aws-cdk-lib": "2.177.0", + "constructs": "10.1.312", "jest": "^29.7.0", + "jsii": "^5.7.6", + "jsii-pacmak": "^1.108.0", "prettier": "3.5.2", + "publib": "^0.2.955", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", "typescript": "~5.6.3" }, + "bundledDependencies": [ + "handlebars" + ], "dependencies": { - "aws-cdk-lib": "2.177.0", "cdk-ecr-deployment": "^3.0.33", - "constructs": "^10.0.0", "handlebars": "^4.7.8" - } + }, + "peerDependencies": { + "aws-cdk-lib": "2.177.0", + "constructs": "^10.1.312" + }, + "jsii": { + "outdir": "dist", + "versionFormat": "short", + "targets": {} + }, + "main": "lib/index.js", + "types": "lib/index.d.ts" } diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index aaa7dc5..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "module": "commonjs", - "lib": [ - "es2020", - "dom" - ], - "declaration": true, - "strict": true, - "noImplicitAny": true, - "strictNullChecks": true, - "noImplicitThis": true, - "alwaysStrict": true, - "noUnusedLocals": false, - "noUnusedParameters": false, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": false, - "inlineSourceMap": true, - "inlineSources": true, - "experimentalDecorators": true, - "strictPropertyInitialization": false, - "typeRoots": [ - "./node_modules/@types" - ] - }, - "exclude": [ - "node_modules", - "cdk.out" - ] -} From 4420cd6df7b64cb96c1d015e110d7aa88dca1722 Mon Sep 17 00:00:00 2001 From: andrewpatto Date: Tue, 4 Mar 2025 14:34:59 +1100 Subject: [PATCH 11/11] Fixed LD_LIBRARY_PATH for aws cli General tidy up --- README.md | 15 +- bin/settings.ts | 13 +- jest.config.js | 8 - lib/dependencies.ts | 12 + ...er-data.txt => ec2-user-data.template.txt} | 3 +- lib/nextflow-config/index.ts | 220 +- .../nextflow-aws.template.config} | 12 +- .../{ => thin-docker}/Dockerfile | 0 lib/nextflow-pipeline-environment/index.ts | 5 + lib/nextflow-task-environment/index.ts | 5 + lib/oncoanalyser-job-definition/Dockerfile | 1 - lib/oncoanalyser-job-definition/run.sh | 8 +- lib/oncoanalyser.ts | 33 +- lib/utils.ts | 8 +- package-lock.json | 5794 ++++------------- package.json | 31 +- test/oncoanalyser-stack.test.ts | 17 - 17 files changed, 1307 insertions(+), 4878 deletions(-) delete mode 100644 jest.config.js rename lib/{ec2-user-data.txt => ec2-user-data.template.txt} (84%) rename lib/{nextflow_aws.template.config => nextflow-config/nextflow-aws.template.config} (95%) rename lib/nextflow-config/{ => thin-docker}/Dockerfile (100%) delete mode 100644 test/oncoanalyser-stack.test.ts diff --git a/README.md b/README.md index 9315fe5..6a01147 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,3 @@ -# Welcome to your CDK TypeScript project +# Oncoanalyser AWS -This is a blank project for CDK development with TypeScript. - -The `cdk.json` file tells the CDK Toolkit how to execute your app. - -## Useful commands - -* `npm run build` compile typescript to js -* `npm run watch` watch for changes and compile -* `npm run test` perform the jest unit tests -* `npx cdk deploy` deploy this stack to your default AWS account/region -* `npx cdk diff` compare deployed stack with current state -* `npx cdk synth` emits the synthesized CloudFormation template +A CDK package that deploys Oncoanalyser. diff --git a/bin/settings.ts b/bin/settings.ts index 543690d..74f73d3 100644 --- a/bin/settings.ts +++ b/bin/settings.ts @@ -1,10 +1,12 @@ -import { OncoanalyserProps } from "../lib/oncoanalyser"; -import * as ec2 from "aws-cdk-lib/aws-ec2"; +import { OncoanalyserProps } from "../lib"; +import { InstanceClass, InstanceSize, InstanceType } from "aws-cdk-lib/aws-ec2"; /** * Configurable settings for the oncoanalyser construct. */ export const SETTINGS: OncoanalyserProps = { + // use the default VPC of the account + vpc: undefined, bucket: { bucket: "umccr-temp-dev", inputPrefix: "inputs", @@ -17,14 +19,11 @@ export const SETTINGS: OncoanalyserProps = { pipelineMaxCpus: 2, taskMaxCpus: 4, pipelineInstanceTypes: [ - ec2.InstanceType.of(ec2.InstanceClass.R6A, ec2.InstanceSize.LARGE), + InstanceType.of(InstanceClass.R6A, InstanceSize.LARGE), ], pipelineQueueName: "oncoanalyser-pipeline", pipelineJobDefinitionName: "oncoanalyser-job-definition", - taskInstanceTypes: [ - ec2.InstanceType.of(ec2.InstanceClass.R6I, ec2.InstanceSize.XLARGE), - ], - vpc: undefined, + taskInstanceTypes: [InstanceType.of(InstanceClass.R6I, InstanceSize.XLARGE)], gitRepo: "https://github.com/scwatts/oncoanalyser-aws-stack-testing", gitBranch: "aws-stack-testing", }; diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 08263b8..0000000 --- a/jest.config.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = { - testEnvironment: 'node', - roots: ['/test'], - testMatch: ['**/*.test.ts'], - transform: { - '^.+\\.tsx?$': 'ts-jest' - } -}; diff --git a/lib/dependencies.ts b/lib/dependencies.ts index ba3faab..b5d688d 100644 --- a/lib/dependencies.ts +++ b/lib/dependencies.ts @@ -6,3 +6,15 @@ export const NEXTFLOW_PLUGINS: string[] = [ "nf-schema@2.3.0", "nf-wave@1.7.4", ]; + +/** + * Define the master location of the AWS CLI for Nextflow + */ +export const AWS_CLI_BASE_PATH = "/mounted-aws-cli/awscliv2"; + +/** + * Define the location (inside tasks) of the scratch area. The underlying + * batch instances and container setup will need to set this up. For instance + * they might mount in a NVME etc. + */ +export const SCRATCH_BASE_PATH = "/scratch"; diff --git a/lib/ec2-user-data.txt b/lib/ec2-user-data.template.txt similarity index 84% rename from lib/ec2-user-data.txt rename to lib/ec2-user-data.template.txt index 144a0c5..da85846 100644 --- a/lib/ec2-user-data.txt +++ b/lib/ec2-user-data.template.txt @@ -20,8 +20,7 @@ Content-Type: text/x-shellscript; charset="us-ascii" curl https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip -o /tmp/awscliv2.zip unzip -q /tmp/awscliv2.zip -d /tmp/ -/tmp/aws/install --install-dir /opt/awscliv2/aws-cli/ --bin-dir /opt/awscliv2/bin/ -ln -s /opt/awscliv2/bin/aws /usr/local/bin/ +/tmp/aws/install --install-dir {{AWS_CLI_BASE_PATH}}/aws-cli/ --bin-dir {{AWS_CLI_BASE_PATH}}/bin/ git clone https://github.com/awslabs/amazon-ebs-autoscale /tmp/amazon-ebs-autoscale/ (cd /tmp/amazon-ebs-autoscale/ && git checkout 6db0c70) diff --git a/lib/nextflow-config/index.ts b/lib/nextflow-config/index.ts index 506fff1..0de517f 100644 --- a/lib/nextflow-config/index.ts +++ b/lib/nextflow-config/index.ts @@ -9,7 +9,11 @@ import { DockerImageAsset, Platform } from "aws-cdk-lib/aws-ecr-assets"; import { IRole } from "aws-cdk-lib/aws-iam"; import { IJobQueue } from "aws-cdk-lib/aws-batch"; import { Duration } from "aws-cdk-lib"; -import { NEXTFLOW_PLUGINS } from "../dependencies"; +import { + AWS_CLI_BASE_PATH, + NEXTFLOW_PLUGINS, + SCRATCH_BASE_PATH, +} from "../dependencies"; export interface NextflowConfigProps { /** @@ -47,20 +51,90 @@ export class NextflowConfigConstruct extends Construct { * The AppConfig hosted configuration that is created. */ private readonly hostedConfiguration: appconfig.HostedConfiguration; + /** + * The substitutions dictionary that is used for various templating. + */ + private readonly substitutions: Record; constructor(scope: Construct, id: string, props: NextflowConfigProps) { super(scope, id); - /** - * Makes the insertion into the nextflow config of the Docker image URI - * for each task. - * - * @param substitutions a dictionary mapping name->value - * @param configName - * @param dockerImageUri - */ + this.substitutions = this.createSubstitutions(props); + + const nextflowConfig = this.processTemplate( + join(__dirname, "nextflow-aws.template.config"), + ); + + this.application = new appconfig.Application( + this, + "AppConfigApplication", + {}, + ); + this.environment = new appconfig.Environment(this, "AppConfigEnvironment", { + description: "Default environment for this deployment of Oncoanalyser", + application: this.application, + // the configurations are templated and deployed via CDK - it is not expected that + // users will edit, so we can aggressively delete + deletionProtectionCheck: DeletionProtectionCheck.BYPASS, + }); + + const deploymentStrategy = new appconfig.DeploymentStrategy( + this, + "AppConfigDeploymentStrategy", + { + deploymentStrategyName: "AllAtOnceAsQuickAsWeCan", + rolloutStrategy: { + growthFactor: 100, + deploymentDuration: Duration.minutes(0), + // given our nextflow only runs on demand (and only picks up the config on startup), + // there is no point waiting when we roll out configs + finalBakeTime: Duration.minutes(0), + }, + }, + ); + + this.hostedConfiguration = new appconfig.HostedConfiguration( + this, + "AppConfigHostedConfiguration", + { + description: + "Default configuration for this deployment of Oncoanalyser - this config is autogenerated from a template and should not be edited", + application: this.application, + deployTo: [this.environment], + deploymentStrategy: deploymentStrategy, + content: appconfig.ConfigurationContent.fromInlineText(nextflowConfig), + }, + ); + } + + public retrieveEnvironmentVariables(): Record { + return { + ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_APPLICATION: + this.application.applicationId, + ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_ENVIRONMENT: + this.environment.environmentId, + ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_CONFIGURATION_PROFILE: + this.hostedConfiguration.configurationProfileId, + }; + } + + private createSubstitutions(props: NextflowConfigProps): Record { + // we build a dictionary of substitution values that can be inserted into the config by handlebars + // we first insert here the AWS values like role ARN etc that are needed by the Nextflow + // pipeline engine + const subs: Record = { + BATCH_INSTANCE_TASK_ROLE_ARN: props.tasksInstanceRole.roleArn, + BATCH_JOB_QUEUE_NAME: props.tasksJobQueue.jobQueueName, + S3_BUCKET_NAME: props.bucket.bucket, + S3_BUCKET_REFDATA_PREFIX: props.bucket.refDataPrefix, + PLUGINS: NEXTFLOW_PLUGINS, + AWS_CLI_BASE_PATH: AWS_CLI_BASE_PATH, + SCRATCH_BASE_PATH: SCRATCH_BASE_PATH, + }; + + // Makes the insertion into the nextflow config of the Docker image URI + // for each task. const fixConfigSectionForTask = ( - substitutions: Record, configName: string, dockerImageUri: string, ) => { @@ -69,7 +143,7 @@ export class NextflowConfigConstruct extends Construct { // docker image - but is maintained as an asset within the CDK setup // this means CDK will handle deploying it to ECR for us const imageAsset = new DockerImageAsset(this, configName, { - directory: join(__dirname), + directory: join(__dirname, "thin-docker"), platform: Platform.LINUX_AMD64, // because the image base name is passed into Docker - the actual Docker checksum // itself won't change even when the image base does... so we need to add the name/tag into the hash @@ -80,248 +154,150 @@ export class NextflowConfigConstruct extends Construct { }, }); - substitutions[configName] = imageAsset.imageUri; + subs[configName] = imageAsset.imageUri; } else { // we will just directly reference the Docker image in quay.io etc - substitutions[configName] = dockerImageUri; + subs[configName] = dockerImageUri; } }; - // we build a dictionary of substitution values that can be inserted into the config by handlebars - // we first insert here the AWS values like role ARN etc that are needed by the Nextflow - // pipeline engine - const substitutions: Record = { - BATCH_INSTANCE_TASK_ROLE_ARN: props.tasksInstanceRole.roleArn, - BATCH_JOB_QUEUE_NAME: props.tasksJobQueue.jobQueueName, - S3_BUCKET_NAME: props.bucket.bucket, - S3_BUCKET_REFDATA_PREFIX: props.bucket.refDataPrefix, - PLUGINS: NEXTFLOW_PLUGINS, - }; - - // modules/local/neo/annotate_fusions/main.nf: 'biocontainers/hmftools-isofox:1.7.1--hdfd78af_1' - fixConfigSectionForTask( - substitutions, "NEO_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-neo:1.2--hdfd78af_1", ); fixConfigSectionForTask( - substitutions, "BAMTOOLS_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-bam-tools:1.3--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "LINXREPORT_DOCKER_IMAGE_URI", "quay.io/biocontainers/r-linxreport:1.0.0--r43hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "PAVE_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-pave:1.7--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "ESVEE_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-esvee:1.0--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "SAMBAMBA_DOCKER_IMAGE_URI", "quay.io/biocontainers/sambamba:1.0.1--h6f6fda4_0", ); fixConfigSectionForTask( - substitutions, "SAMTOOLS_DOCKER_IMAGE_URI", "quay.io/biocontainers/samtools:1.18--h50ea8bc_", ); fixConfigSectionForTask( - substitutions, "STAR_ALIGN_IMAGE_URI", "quay.io/biocontainers/star:2.7.3a--0", ); fixConfigSectionForTask( - substitutions, "GRIPSS_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-gripss:2.4--hdfd78af_00", ); fixConfigSectionForTask( - substitutions, "COBALT_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-cobalt:2.0--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "LINX_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-linx:2.0--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "ISOFOX_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-isofox:1.7.1--hdfd78af_1", ); fixConfigSectionForTask( - substitutions, "AMBER_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-amber:4.1.1--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "LILAC_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-lilac:1.6--hdfd78af_1", ); fixConfigSectionForTask( - substitutions, "STAR_DOCKER_IMAGE_URI", "quay.io/biocontainers/star:2.7.3a--0", ); fixConfigSectionForTask( - substitutions, "PURPLE_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-purple:4.1--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "VIRUSBREAKEND_DOCKER_IMAGE_URI", "quay.io/nf-core/gridss:2.13.2--1", ); fixConfigSectionForTask( - substitutions, "GRIDSS_INDEX_DOCKER_IMAGE_URI", "quay.io/biocontainers/gridss:2.13.2--h50ea8bc_3", ); fixConfigSectionForTask( - substitutions, "GATK4_MARKDUPLICATES_IMAGE_URI", "quay.io/biocontainers/gatk4:4.4.0.0--py36hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "CHORD_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-chord:2.1.0--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "LILAC_EXTRACT_INDEX_DOCKER_IMAGE_URI", "quay.io/biocontainers/mulled-v2-4dde50190ae599f2bb2027cb2c8763ea00fb5084:4163e62e1daead7b7ea0228baece715bec295c22-0", ); fixConfigSectionForTask( - substitutions, "LILAC_REALIGN_READS_DOCKER_IMAGE_URI", "quay.io/biocontainers/mulled-v2-4dde50190ae599f2bb2027cb2c8763ea00fb5084:4163e62e1daead7b7ea0228baece715bec295c22-0", ); fixConfigSectionForTask( - substitutions, "LILAC_SLICE_DOCKER_IMAGE_URI", "quay.io/biocontainers/samtools:1.19.2--h50ea8bc_0", ); fixConfigSectionForTask( - substitutions, "BWAMEM2_DOCKER_IMAGE_URI", "quay.io/biocontainers/mulled-v2-4dde50190ae599f2bb2027cb2c8763ea00fb5084:4163e62e1daead7b7ea0228baece715bec295c22-0", ); fixConfigSectionForTask( - substitutions, "REDUX_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-redux:1.1--hdfd78af_1", ); fixConfigSectionForTask( - substitutions, "VIRUSINTERPRETER_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-virus-interpreter:1.7--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "SAGE_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-sage:4.0--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "CUPPA_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-cuppa:2.3.1--py311r42hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "ORANGE_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-orange:3.7.1--hdfd78af_0", ); fixConfigSectionForTask( - substitutions, "FASTP_DOCKER_IMAGE_URI", "quay.io/biocontainers/fastp:0.23.4--hadf994f_2", ); fixConfigSectionForTask( - substitutions, "SIGS_DOCKER_IMAGE_URI", "quay.io/biocontainers/hmftools-sigs:1.2.1--hdfd78af_1", ); - const nextflowConfigTemplate = readFileSync( - join(__dirname, "..", "nextflow_aws.template.config"), - { encoding: "utf-8" }, - ); - const nextflowConfigTemplateCompiled = Handlebars.compile( - nextflowConfigTemplate, - ); - const nextflowConfig = nextflowConfigTemplateCompiled(substitutions, {}); - - this.application = new appconfig.Application( - this, - "AppConfigApplication", - {}, - ); - this.environment = new appconfig.Environment(this, "AppConfigEnvironment", { - description: "Default environment for this deployment of Oncoanalyser", - application: this.application, - // the configurations are templated and deployed via CDK - it is not expected that - // users will edit, so we can aggressively delete - deletionProtectionCheck: DeletionProtectionCheck.BYPASS, - }); - - const deploymentStrategy = new appconfig.DeploymentStrategy( - this, - "AppConfigDeploymentStrategy", - { - deploymentStrategyName: "AllAtOnceAsQuickAsWeCan", - rolloutStrategy: { - growthFactor: 100, - deploymentDuration: Duration.minutes(0), - // given our nextflow only runs on demand (and only picks up the config on startup), - // there is no point waiting when we roll out configs - finalBakeTime: Duration.minutes(0), - }, - }, - ); - - this.hostedConfiguration = new appconfig.HostedConfiguration( - this, - "AppConfigHostedConfiguration", - { - description: - "Default configuration for this deployment of Oncoanalyser - this config is autogenerated from a template and should not be edited", - application: this.application, - deployTo: [this.environment], - deploymentStrategy: deploymentStrategy, - content: appconfig.ConfigurationContent.fromInlineText(nextflowConfig), - }, - ); - - // if a substitution of something like REDUX_DOCKER_IMAGE_URI does not happen - then we will be left with an empty string in the nextflow config - // as we don't have any real empty strings - we use this to detect missed subs - //if (nextflowConfig.includes("''")) - // throw new Error( - // "a docker image substitution was missed in the nextflow config presumably because of a simple name mismatch", - // ); + return subs; } - public retrieveEnvironmentVariables(): Record { - return { - ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_APPLICATION: - this.application.applicationId, - ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_ENVIRONMENT: - this.environment.environmentId, - ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_CONFIGURATION_PROFILE: - this.hostedConfiguration.configurationProfileId, - }; + /** + * Takes a path to a template/text file in Handlebars format and returns the + * content of the file with substitutions made. + * + * @param templatePath + */ + private processTemplate(templatePath: string): string { + const templateContent = readFileSync(templatePath, { encoding: "utf-8" }); + const templateCompiled = Handlebars.compile(templateContent, { strict: true }); + return templateCompiled(this.substitutions, {}); } } diff --git a/lib/nextflow_aws.template.config b/lib/nextflow-config/nextflow-aws.template.config similarity index 95% rename from lib/nextflow_aws.template.config rename to lib/nextflow-config/nextflow-aws.template.config index 3e7434b..25148e3 100644 --- a/lib/nextflow_aws.template.config +++ b/lib/nextflow-config/nextflow-aws.template.config @@ -7,11 +7,11 @@ plugins { aws { batch { jobRole = '{{BATCH_INSTANCE_TASK_ROLE_ARN}}' - volumes = '/scratch' + volumes = '{{SCRATCH_BASE_PATH}}' } batch { - cliPath = '/opt/awscliv2/bin/aws' - } + cliPath = '{{AWS_CLI_BASE_PATH}}/bin/aws' + } } params { @@ -46,10 +46,11 @@ params { process { executor = 'awsbatch' - scratch = '/scratch/' + scratch = '{{SCRATCH_BASE_PATH}}' // NOTE(SW): using docker.runOptions in 23.10.01 causes `--network host` to be included twice, triggering an error in Docker - containerOptions = '--network host' + // NOTE(AP): in order to make the nextflow invoke of aws CLI find the correct libz.so - we need to set LD_LIBRARY_PATH + containerOptions = '--network host --env LD_LIBRARY_PATH={{AWS_CLI_BASE_PATH}}/aws-cli/v2/current/dist' resourceLabels = { return [ @@ -299,7 +300,6 @@ process { } withName: 'CUSTOM_DUMPSOFTWAREVERSIONS' { - container = '{{DUMPSOFTWAREVERSIONS_DOCKER_IMAGE_URI}}' cpus = 1 memory = 12.GB } diff --git a/lib/nextflow-config/Dockerfile b/lib/nextflow-config/thin-docker/Dockerfile similarity index 100% rename from lib/nextflow-config/Dockerfile rename to lib/nextflow-config/thin-docker/Dockerfile diff --git a/lib/nextflow-pipeline-environment/index.ts b/lib/nextflow-pipeline-environment/index.ts index 7625251..35fc539 100644 --- a/lib/nextflow-pipeline-environment/index.ts +++ b/lib/nextflow-pipeline-environment/index.ts @@ -60,6 +60,10 @@ export interface NextflowPipelineEnvironmentProps { * Additional policies to attach to the instance role. */ readonly additionalInstanceRolePolicies?: Policy[]; + /** + * The launch template content for the underlying batch instances + */ + readonly launchTemplateContent: string; } /** @@ -100,6 +104,7 @@ export class NextflowPipelineEnvironment extends Construct { instanceRole: this.instanceRole, instanceTypes: props.instanceTypes, launchTemplate: createLaunchTemplate(this, { + content: props.launchTemplateContent, securityGroup: props.securityGroup, launchTemplateName: "oncoanalyser-pipeline", }), diff --git a/lib/nextflow-task-environment/index.ts b/lib/nextflow-task-environment/index.ts index 10b1d8b..984c274 100644 --- a/lib/nextflow-task-environment/index.ts +++ b/lib/nextflow-task-environment/index.ts @@ -48,6 +48,10 @@ export interface NextflowTaskEnvironmentProps { * The patterns to grant read-write access to the bucket. */ readonly nfBucketGrantReadWrite?: string[]; + /** + * The launch template content for the underlying batch instances + */ + readonly launchTemplateContent: string; } /** @@ -95,6 +99,7 @@ export class NextflowTaskEnvironment extends Construct { instanceRole: this.instanceRole, instanceTypes: props.instanceTypes, launchTemplate: createLaunchTemplate(this, { + content: props.launchTemplateContent, securityGroup: props.securityGroup, launchTemplateName: "oncoanalyser-task", }), diff --git a/lib/oncoanalyser-job-definition/Dockerfile b/lib/oncoanalyser-job-definition/Dockerfile index df732af..fdbb6b0 100644 --- a/lib/oncoanalyser-job-definition/Dockerfile +++ b/lib/oncoanalyser-job-definition/Dockerfile @@ -31,7 +31,6 @@ RUN \ git clone -b ${SOFTWARE_GIT_BRANCH} ${SOFTWARE_GIT_REPO} /root/pipeline/software/oncoanalyser/ # The dockerfile should be executed one level above the oncoanalyser-job-definition directory -COPY nextflow_aws.template.config /root/pipeline/other/ COPY oncoanalyser-job-definition/run.sh /root/pipeline/other/ WORKDIR /root/pipeline/ diff --git a/lib/oncoanalyser-job-definition/run.sh b/lib/oncoanalyser-job-definition/run.sh index 29c197d..5dfc8e5 100755 --- a/lib/oncoanalyser-job-definition/run.sh +++ b/lib/oncoanalyser-job-definition/run.sh @@ -46,12 +46,12 @@ output_base=$(jq -r .outdir params.json) # for the moment appconfig is overkill - but it does open up the possibility of things # like feature flags etc appconfig_token=$(aws appconfigdata start-configuration-session \ - --application-identifier $ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_APPLICATION \ - --environment-identifier $ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_ENVIRONMENT \ - --configuration-profile-identifier $ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_CONFIGURATION_PROFILE \ + --application-identifier "$ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_APPLICATION" \ + --environment-identifier "$ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_ENVIRONMENT" \ + --configuration-profile-identifier "$ONCOANALYSER_NEXTFLOW_CONFIG_APPCONFIG_CONFIGURATION_PROFILE" \ --query InitialConfigurationToken --output text) -aws appconfigdata get-latest-configuration --configuration-token $appconfig_token aws.config +aws appconfigdata get-latest-configuration --configuration-token "$appconfig_token" aws.config # Set additional Nextflow arguments nf_arg_stub='' diff --git a/lib/oncoanalyser.ts b/lib/oncoanalyser.ts index cc36fb8..d1db70c 100644 --- a/lib/oncoanalyser.ts +++ b/lib/oncoanalyser.ts @@ -9,6 +9,11 @@ import { OncoanalyserJobDefinition } from "./oncoanalyser-job-definition"; import { IVpc, Vpc } from "aws-cdk-lib/aws-ec2"; import { NextflowTaskEnvironment } from "./nextflow-task-environment"; import { NextflowPipelineEnvironment } from "./nextflow-pipeline-environment"; +import { readFileSync } from "fs"; +import * as Handlebars from "handlebars"; +import { join } from "path"; +import { AWS_CLI_BASE_PATH, SCRATCH_BASE_PATH } from "./dependencies"; + export interface BucketProps { readonly bucket: string; readonly inputPrefix: string; @@ -57,6 +62,15 @@ export interface OncoanalyserProps { * The git branch of oncoanalyser to launch from nextflow. */ readonly gitBranch: string; + /** + * If true, instructs the construct to re-deploy all Task images from + * their normal source (quay.io etc) to ECR. This will make + * the initial build much slower, but will then use the Docker cache + * and will make all executions of the tasks entirely local to AWS. + * If absent or false, then the default docker task URIs will be used + * and pulled from the remote sources at runtime. + */ + readonly copyToLocalEcr?: boolean; } /** @@ -90,6 +104,21 @@ export class Oncoanalyser extends Construct { props.bucket.bucket, ); + const launchTemplateTemplate = readFileSync( + join(__dirname, "ec2-user-data.template.txt"), + { encoding: "utf-8" }, + ); + const launchTemplateCompiled = Handlebars.compile(launchTemplateTemplate, { + strict: true, + }); + const launchTemplateContent = launchTemplateCompiled( + { + AWS_CLI_BASE_PATH: AWS_CLI_BASE_PATH, + SCRATCH_BASE_PATH: SCRATCH_BASE_PATH, + }, + {}, + ); + const nfTaskComputeEnv = new NextflowTaskEnvironment( this, "NextflowTaskComputeEnvironment", @@ -104,6 +133,7 @@ export class Oncoanalyser extends Construct { `${props.bucket.refDataPrefix}/*`, ], nfBucketGrantReadWrite: [`${props.bucket.outputPrefix}/*`], + launchTemplateContent: launchTemplateContent, }, ); @@ -150,6 +180,7 @@ export class Oncoanalyser extends Construct { ], }), ], + launchTemplateContent: launchTemplateContent, }, ); @@ -157,7 +188,7 @@ export class Oncoanalyser extends Construct { bucket: props.bucket, tasksInstanceRole: nfTaskComputeEnv.instanceRole, tasksJobQueue: nfTaskComputeEnv.jobQueue, - copyToLocalEcr: false, + copyToLocalEcr: props.copyToLocalEcr, }); new OncoanalyserJobDefinition(this, "OncoanalyserJobDefinition", { diff --git a/lib/utils.ts b/lib/utils.ts index 7caab2e..5605c4c 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,22 +1,20 @@ import { Construct } from "constructs"; import { Tags } from "aws-cdk-lib"; import { ISecurityGroup, LaunchTemplate, UserData } from "aws-cdk-lib/aws-ec2"; -import { readFileSync } from "fs"; -import * as path from "path"; export function createLaunchTemplate( construct: Construct, { + content, securityGroup, launchTemplateName, }: { + content: string; securityGroup: ISecurityGroup; launchTemplateName?: string; }, ) { - const userDataFilePath = path.resolve(__dirname, "ec2-user-data.txt"); - const userDataContent = readFileSync(path.resolve(userDataFilePath), "utf-8"); - const userData = UserData.custom(userDataContent); + const userData = UserData.custom(content); const ltName = launchTemplateName ?? "oncoanalyser"; const constructId = `LaunchTemplate-${ltName}`; diff --git a/package-lock.json b/package-lock.json index ac8ef37..f67f9c0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,61 +12,40 @@ ], "license": "MIT", "dependencies": { - "cdk-ecr-deployment": "^3.0.33", - "handlebars": "^4.7.8" + "handlebars": "4.7.8" }, "bin": { "oncoanalyser-stack": "bin/oncoanalyser-stack.js" }, "devDependencies": { - "@types/jest": "^29.5.14", "@types/node": "22.7.9", - "aws-cdk": "2.177.0", - "aws-cdk-lib": "2.177.0", - "constructs": "10.1.312", - "jest": "^29.7.0", - "jsii": "^5.7.6", - "jsii-pacmak": "^1.108.0", - "prettier": "3.5.2", - "publib": "^0.2.955", - "ts-jest": "^29.2.5", - "ts-node": "^10.9.2", - "typescript": "~5.6.3" + "aws-cdk": "2.1002.0", + "aws-cdk-lib": "2.181.1", + "constructs": "10.4.2", + "jsii": "5.7.7", + "jsii-pacmak": "1.108.0", + "prettier": "3.5.3", + "publib": "0.2.956", + "ts-node": "10.9.2", + "typescript": "5.8.2" }, "peerDependencies": { - "aws-cdk-lib": "2.177.0", - "constructs": "^10.1.312" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "aws-cdk-lib": "2.181.1", + "constructs": "10.4.2" } }, "node_modules/@aws-cdk/asset-awscli-v1": { "version": "2.2.225", "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.225.tgz", "integrity": "sha512-fMPfR7PwiwQZwAux9tQ5LRrFJJfl5Vp3kR8GMc+H/PA/wql9+w8mk5gs6SDpwBFpT7n3XkZ5H98Ns5+g7/WMIg==", - "license": "Apache-2.0" - }, - "node_modules/@aws-cdk/asset-kubectl-v20": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.4.tgz", - "integrity": "sha512-Ps2MkmjYgMyflagqQ4dgTElc7Vwpqj8spw8dQVFiSeaaMPsuDSNsPax3/HjuDuwqsmLdaCZc6umlxYLpL0kYDA==", + "dev": true, "license": "Apache-2.0" }, "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz", "integrity": "sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A==", + "dev": true, "license": "Apache-2.0" }, "node_modules/@aws-cdk/cloud-assembly-schema": { @@ -77,6 +56,7 @@ "jsonschema", "semver" ], + "dev": true, "license": "Apache-2.0", "dependencies": { "jsonschema": "~1.4.1", @@ -85,6 +65,7 @@ }, "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { "version": "1.4.1", + "dev": true, "inBundle": true, "license": "MIT", "engines": { @@ -93,6 +74,7 @@ }, "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { "version": "7.7.1", + "dev": true, "inBundle": true, "license": "ISC", "bin": { @@ -801,4420 +783,1683 @@ } } }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "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, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.26.8", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", - "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" + "node": ">=12" } }, - "node_modules/@babel/core": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", - "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", + "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, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/helper-compilation-targets": "^7.26.5", - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/traverse": "^7.26.9", - "@babel/types": "^7.26.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@babel/generator": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz", - "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==", + "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, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jsii/check-node": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.108.0.tgz", + "integrity": "sha512-wa8AGH31Cl0x1jU/KtM6JB32IurBmK1YiX5ZnCndifRCehLnS8DmJCPYrzJbKD4xqmHigaq6696fAnM/L7qIsw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.5", - "@babel/helper-validator-option": "^7.25.9", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" + "chalk": "^4.1.2", + "semver": "^7.6.3" }, "engines": { - "node": ">=6.9.0" + "node": ">= 14.17.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", - "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "node_modules/@jsii/check-node/node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=6.9.0" + "node": ">=10" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", - "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "node_modules/@jsii/spec": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/@jsii/spec/-/spec-1.108.0.tgz", + "integrity": "sha512-YtebmBRy19UT1pKmxqlTqfW1OcFFjuU2zxxi+QFfM8KG1ahBlpcuz+3DE9gG1qTASIJJJI0fd8PaAiZ5gE40sQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "ajv": "^8.17.1" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">= 14.17.0" } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz", - "integrity": "sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, "engines": { - "node": ">=6.9.0" + "node": ">= 8" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", - "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", + "peer": true, "engines": { - "node": ">=6.9.0" + "node": ">= 8" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", + "peer": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">= 8" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", - "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "node_modules/@smithy/abort-controller": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.1.tgz", + "integrity": "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g==", "dev": true, - "license": "MIT", + "dependencies": { + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@babel/helpers": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz", - "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==", + "node_modules/@smithy/config-resolver": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.0.1.tgz", + "integrity": "sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9" + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-config-provider": "^4.0.0", + "@smithy/util-middleware": "^4.0.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@babel/parser": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz", - "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==", + "node_modules/@smithy/core": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.5.tgz", + "integrity": "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/types": "^7.26.9" - }, - "bin": { - "parser": "bin/babel-parser.js" + "@smithy/middleware-serde": "^4.0.2", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-body-length-browser": "^4.0.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-stream": "^4.1.2", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=18.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==", + "node_modules/@smithy/credential-provider-imds": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.1.tgz", + "integrity": "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/fetch-http-handler": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.1.tgz", + "integrity": "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-base64": "^4.0.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/hash-node": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.1.tgz", + "integrity": "sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" + "@smithy/types": "^4.1.0", + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/invalid-dependency": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.1.tgz", + "integrity": "sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/is-array-buffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", + "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.0.0" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", - "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "node_modules/@smithy/middleware-content-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.1.tgz", + "integrity": "sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18.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==", + "node_modules/@smithy/middleware-endpoint": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.6.tgz", + "integrity": "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@smithy/core": "^3.1.5", + "@smithy/middleware-serde": "^4.0.2", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "@smithy/url-parser": "^4.0.1", + "@smithy/util-middleware": "^4.0.1", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/middleware-retry": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.7.tgz", + "integrity": "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@smithy/node-config-provider": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/service-error-classification": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-retry": "^4.0.1", + "tslib": "^2.6.2", + "uuid": "^9.0.1" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/middleware-serde": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.2.tgz", + "integrity": "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/middleware-stack": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.1.tgz", + "integrity": "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/node-config-provider": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.1.tgz", + "integrity": "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@smithy/property-provider": "^4.0.1", + "@smithy/shared-ini-file-loader": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/node-http-handler": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.3.tgz", + "integrity": "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@smithy/abort-controller": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/querystring-builder": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18.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==", + "node_modules/@smithy/property-provider": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.1.tgz", + "integrity": "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18.0.0" } }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", - "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "node_modules/@smithy/protocol-http": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.0.1.tgz", + "integrity": "sha512-TE4cpj49jJNB/oHyh/cRVEgNZaoPaxd4vteJNB0yGidOCVR0jCw/hjPVsT8Q8FRmj8Bd3bFZt8Dh7xGCT+xMBQ==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": ">=18.0.0" } }, - "node_modules/@babel/template": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.26.9.tgz", - "integrity": "sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==", + "node_modules/@smithy/querystring-builder": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.1.tgz", + "integrity": "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/parser": "^7.26.9", - "@babel/types": "^7.26.9" + "@smithy/types": "^4.1.0", + "@smithy/util-uri-escape": "^4.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@babel/traverse": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz", - "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==", + "node_modules/@smithy/querystring-parser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.1.tgz", + "integrity": "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.9", - "@babel/parser": "^7.26.9", - "@babel/template": "^7.26.9", - "@babel/types": "^7.26.9", - "debug": "^4.3.1", - "globals": "^11.1.0" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.0" } }, - "node_modules/@babel/types": { - "version": "7.26.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz", - "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==", + "node_modules/@smithy/service-error-classification": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.1.tgz", + "integrity": "sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9" + "@smithy/types": "^4.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=18.0.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, - "license": "MIT" - }, - "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==", + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.1.tgz", + "integrity": "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=12" + "node": ">=18.0.0" } }, - "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==", + "node_modules/@smithy/signature-v4": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.1.tgz", + "integrity": "sha512-nCe6fQ+ppm1bQuw5iKoeJ0MJfz2os7Ic3GBjOkLOPtavbD1ONoyE3ygjBfz2ythFWm4YnRm6OxW+8p/m9uCoIA==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@smithy/is-array-buffer": "^4.0.0", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-hex-encoding": "^4.0.0", + "@smithy/util-middleware": "^4.0.1", + "@smithy/util-uri-escape": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" } }, - "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==", + "node_modules/@smithy/smithy-client": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.6.tgz", + "integrity": "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw==", "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" + "@smithy/core": "^3.1.5", + "@smithy/middleware-endpoint": "^4.0.6", + "@smithy/middleware-stack": "^4.0.1", + "@smithy/protocol-http": "^5.0.1", + "@smithy/types": "^4.1.0", + "@smithy/util-stream": "^4.1.2", + "tslib": "^2.6.2" }, "engines": { - "node": ">=8" + "node": ">=18.0.0" } }, - "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==", + "node_modules/@smithy/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.1.0.tgz", + "integrity": "sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw==", "dev": true, + "dependencies": { + "tslib": "^2.6.2" + }, "engines": { - "node": ">=8" + "node": ">=18.0.0" } }, - "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "node_modules/@smithy/url-parser": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.1.tgz", + "integrity": "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "slash": "^3.0.0" + "@smithy/querystring-parser": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "node_modules/@smithy/util-base64": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", + "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@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.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" }, "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": ">=18.0.0" } }, - "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "node_modules/@smithy/util-body-length-browser": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", + "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0" + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "node_modules/@smithy/util-body-length-node": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", + "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", "dev": true, - "license": "MIT", "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "node_modules/@smithy/util-buffer-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", + "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", "dev": true, - "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3" + "@smithy/is-array-buffer": "^4.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "node_modules/@smithy/util-config-provider": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", + "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.7.tgz", + "integrity": "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.7.tgz", + "integrity": "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ==", "dev": true, - "license": "MIT", "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "@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": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" + "@smithy/config-resolver": "^4.0.1", + "@smithy/credential-provider-imds": "^4.0.1", + "@smithy/node-config-provider": "^4.0.1", + "@smithy/property-provider": "^4.0.1", + "@smithy/smithy-client": "^4.1.6", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "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": ">=18.0.0" } }, - "node_modules/@jest/reporters/node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "node_modules/@smithy/util-endpoints": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.1.tgz", + "integrity": "sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA==", "dev": true, - "license": "BSD-3-Clause", "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" + "@smithy/node-config-provider": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": ">=10" + "node": ">=18.0.0" } }, - "node_modules/@jest/reporters/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "node_modules/@smithy/util-hex-encoding": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", + "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "tslib": "^2.6.2" }, "engines": { - "node": ">=10" + "node": ">=18.0.0" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@smithy/util-middleware": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.1.tgz", + "integrity": "sha512-HiLAvlcqhbzhuiOa0Lyct5IIlyIz0PQO5dnMlmQ/ubYM46dPInB+3yQGkfxsk6Q24Y0n3/JmcA1v5iEhmOF5mA==", "dev": true, - "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "node_modules/@smithy/util-retry": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.1.tgz", + "integrity": "sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw==", "dev": true, - "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "@smithy/service-error-classification": "^4.0.1", + "@smithy/types": "^4.1.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", - "dev": true, - "license": "MIT", + "node_modules/@smithy/util-stream": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.2.tgz", + "integrity": "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw==", + "dev": true, "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@smithy/fetch-http-handler": "^5.0.1", + "@smithy/node-http-handler": "^4.0.3", + "@smithy/types": "^4.1.0", + "@smithy/util-base64": "^4.0.0", + "@smithy/util-buffer-from": "^4.0.0", + "@smithy/util-hex-encoding": "^4.0.0", + "@smithy/util-utf8": "^4.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "node_modules/@smithy/util-uri-escape": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", + "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "slash": "^3.0.0" + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "node_modules/@smithy/util-utf8": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", + "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "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.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "@smithy/util-buffer-from": "^4.0.0", + "tslib": "^2.6.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18.0.0" } }, - "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "@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" - } + "license": "MIT" }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", - "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "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, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } + "license": "MIT" }, - "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==", + "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, - "engines": { - "node": ">=6.0.0" - } + "license": "MIT" }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } + "license": "MIT" }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "node_modules/@types/fs-extra": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "node_modules/@types/node": { + "version": "22.7.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.9.tgz", + "integrity": "sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "undici-types": "~6.19.2" } }, - "node_modules/@jsii/check-node": { - "version": "1.108.0", - "resolved": "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.108.0.tgz", - "integrity": "sha512-wa8AGH31Cl0x1jU/KtM6JB32IurBmK1YiX5ZnCndifRCehLnS8DmJCPYrzJbKD4xqmHigaq6696fAnM/L7qIsw==", + "node_modules/@xmldom/xmldom": { + "version": "0.9.8", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", + "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "semver": "^7.6.3" - }, + "peer": true, "engines": { - "node": ">= 14.17.0" + "node": ">=14.6" } }, - "node_modules/@jsii/check-node/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "node_modules/acorn": { + "version": "8.14.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", "dev": true, + "license": "MIT", "bin": { - "semver": "bin/semver.js" + "acorn": "bin/acorn" }, "engines": { - "node": ">=10" + "node": ">=0.4.0" } }, - "node_modules/@jsii/spec": { - "version": "1.108.0", - "resolved": "https://registry.npmjs.org/@jsii/spec/-/spec-1.108.0.tgz", - "integrity": "sha512-YtebmBRy19UT1pKmxqlTqfW1OcFFjuU2zxxi+QFfM8KG1ahBlpcuz+3DE9gG1qTASIJJJI0fd8PaAiZ5gE40sQ==", + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", "dependencies": { - "ajv": "^8.17.1" + "acorn": "^8.11.0" }, "engines": { - "node": ">= 14.17.0" + "node": ">=0.4.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "peer": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">= 8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "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, - "peer": true, + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "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, - "peer": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">= 8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true, "license": "MIT" }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.0" - } - }, - "node_modules/@smithy/abort-controller": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.1.tgz", - "integrity": "sha512-fiUIYgIgRjMWznk6iLJz35K2YxSLHzLBA/RC6lBrKfQ8fHbPfvk7Pk9UvpKoHgJjI18MnbPuEju53zcVy6KF1g==", + "node_modules/aws-cdk": { + "version": "2.1002.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1002.0.tgz", + "integrity": "sha512-2lq1ho1Rq/sDMTieA6zna9aogk3qHM3Oq/mF7QCx2Jj0+e8/ZJOJW+5xU9oUBclRpUIxfUevC93H3eCSr1VW6g==", "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" + "license": "Apache-2.0", + "bin": { + "cdk": "bin/cdk" }, "engines": { - "node": ">=18.0.0" + "node": ">= 14.15.0" + }, + "optionalDependencies": { + "fsevents": "2.3.2" } }, - "node_modules/@smithy/config-resolver": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.0.1.tgz", - "integrity": "sha512-Igfg8lKu3dRVkTSEm98QpZUvKEOa71jDX4vKRcvJVyRc3UgN3j7vFMf0s7xLQhYmKa8kyJGQgUJDOV5V3neVlQ==", + "node_modules/aws-cdk-lib": { + "version": "2.181.1", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.181.1.tgz", + "integrity": "sha512-PDxYiqzet17tigJ8icjzoZIzmcdusQfKNnwpRzcGu5//n3YqlKf/vGEkQuU0xcgt4lBMX4Yjuqfsl8wYidCESw==", + "bundleDependencies": [ + "@balena/dockerignore", + "case", + "fs-extra", + "ignore", + "jsonschema", + "minimatch", + "punycode", + "semver", + "table", + "yaml", + "mime-types" + ], "dev": true, + "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.0.1", - "@smithy/types": "^4.1.0", - "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.1", - "tslib": "^2.6.2" + "@aws-cdk/asset-awscli-v1": "^2.2.208", + "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0", + "@aws-cdk/cloud-assembly-schema": "^39.2.0", + "@balena/dockerignore": "^1.0.2", + "case": "1.6.3", + "fs-extra": "^11.2.0", + "ignore": "^5.3.2", + "jsonschema": "^1.4.1", + "mime-types": "^2.1.35", + "minimatch": "^3.1.2", + "punycode": "^2.3.1", + "semver": "^7.6.3", + "table": "^6.8.2", + "yaml": "1.10.2" }, "engines": { - "node": ">=18.0.0" + "node": ">= 14.15.0" + }, + "peerDependencies": { + "constructs": "^10.0.0" } }, - "node_modules/@smithy/core": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.1.5.tgz", - "integrity": "sha512-HLclGWPkCsekQgsyzxLhCQLa8THWXtB5PxyYN+2O6nkyLt550KQKTlbV2D1/j5dNIQapAZM1+qFnpBFxZQkgCA==", - "dev": true, - "dependencies": { - "@smithy/middleware-serde": "^4.0.2", - "@smithy/protocol-http": "^5.0.1", - "@smithy/types": "^4.1.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.1", - "@smithy/util-stream": "^4.1.2", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/credential-provider-imds": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.1.tgz", - "integrity": "sha512-l/qdInaDq1Zpznpmev/+52QomsJNZ3JkTl5yrTl02V6NBgJOQ4LY0SFw/8zsMwj3tLe8vqiIuwF6nxaEwgf6mg==", - "dev": true, - "dependencies": { - "@smithy/node-config-provider": "^4.0.1", - "@smithy/property-provider": "^4.0.1", - "@smithy/types": "^4.1.0", - "@smithy/url-parser": "^4.0.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/fetch-http-handler": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.1.tgz", - "integrity": "sha512-3aS+fP28urrMW2KTjb6z9iFow6jO8n3MFfineGbndvzGZit3taZhKWtTorf+Gp5RpFDDafeHlhfsGlDCXvUnJA==", - "dev": true, - "dependencies": { - "@smithy/protocol-http": "^5.0.1", - "@smithy/querystring-builder": "^4.0.1", - "@smithy/types": "^4.1.0", - "@smithy/util-base64": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/hash-node": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.1.tgz", - "integrity": "sha512-TJ6oZS+3r2Xu4emVse1YPB3Dq3d8RkZDKcPr71Nj/lJsdAP1c7oFzYqEn1IBc915TsgLl2xIJNuxCz+gLbLE0w==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/invalid-dependency": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.1.tgz", - "integrity": "sha512-gdudFPf4QRQ5pzj7HEnu6FhKRi61BfH/Gk5Yf6O0KiSbr1LlVhgjThcvjdu658VE6Nve8vaIWB8/fodmS1rBPQ==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", - "dev": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-content-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.1.tgz", - "integrity": "sha512-OGXo7w5EkB5pPiac7KNzVtfCW2vKBTZNuCctn++TTSOMpe6RZO/n6WEC1AxJINn3+vWLKW49uad3lo/u0WJ9oQ==", - "dev": true, - "dependencies": { - "@smithy/protocol-http": "^5.0.1", - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.0.6.tgz", - "integrity": "sha512-ftpmkTHIFqgaFugcjzLZv3kzPEFsBFSnq1JsIkr2mwFzCraZVhQk2gqN51OOeRxqhbPTkRFj39Qd2V91E/mQxg==", - "dev": true, - "dependencies": { - "@smithy/core": "^3.1.5", - "@smithy/middleware-serde": "^4.0.2", - "@smithy/node-config-provider": "^4.0.1", - "@smithy/shared-ini-file-loader": "^4.0.1", - "@smithy/types": "^4.1.0", - "@smithy/url-parser": "^4.0.1", - "@smithy/util-middleware": "^4.0.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-retry": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.0.7.tgz", - "integrity": "sha512-58j9XbUPLkqAcV1kHzVX/kAR16GT+j7DUZJqwzsxh1jtz7G82caZiGyyFgUvogVfNTg3TeAOIJepGc8TXF4AVQ==", - "dev": true, - "dependencies": { - "@smithy/node-config-provider": "^4.0.1", - "@smithy/protocol-http": "^5.0.1", - "@smithy/service-error-classification": "^4.0.1", - "@smithy/smithy-client": "^4.1.6", - "@smithy/types": "^4.1.0", - "@smithy/util-middleware": "^4.0.1", - "@smithy/util-retry": "^4.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-serde": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.2.tgz", - "integrity": "sha512-Sdr5lOagCn5tt+zKsaW+U2/iwr6bI9p08wOkCp6/eL6iMbgdtc2R5Ety66rf87PeohR0ExI84Txz9GYv5ou3iQ==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-stack": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.1.tgz", - "integrity": "sha512-dHwDmrtR/ln8UTHpaIavRSzeIk5+YZTBtLnKwDW3G2t6nAupCiQUvNzNoHBpik63fwUaJPtlnMzXbQrNFWssIA==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/node-config-provider": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.0.1.tgz", - "integrity": "sha512-8mRTjvCtVET8+rxvmzRNRR0hH2JjV0DFOmwXPrISmTIJEfnCBugpYYGAsCj8t41qd+RB5gbheSQ/6aKZCQvFLQ==", - "dev": true, - "dependencies": { - "@smithy/property-provider": "^4.0.1", - "@smithy/shared-ini-file-loader": "^4.0.1", - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/node-http-handler": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.3.tgz", - "integrity": "sha512-dYCLeINNbYdvmMLtW0VdhW1biXt+PPCGazzT5ZjKw46mOtdgToQEwjqZSS9/EN8+tNs/RO0cEWG044+YZs97aA==", - "dev": true, - "dependencies": { - "@smithy/abort-controller": "^4.0.1", - "@smithy/protocol-http": "^5.0.1", - "@smithy/querystring-builder": "^4.0.1", - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/property-provider": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.1.tgz", - "integrity": "sha512-o+VRiwC2cgmk/WFV0jaETGOtX16VNPp2bSQEzu0whbReqE1BMqsP2ami2Vi3cbGVdKu1kq9gQkDAGKbt0WOHAQ==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.0.1.tgz", - "integrity": "sha512-TE4cpj49jJNB/oHyh/cRVEgNZaoPaxd4vteJNB0yGidOCVR0jCw/hjPVsT8Q8FRmj8Bd3bFZt8Dh7xGCT+xMBQ==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/querystring-builder": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.1.tgz", - "integrity": "sha512-wU87iWZoCbcqrwszsOewEIuq+SU2mSoBE2CcsLwE0I19m0B2gOJr1MVjxWcDQYOzHbR1xCk7AcOBbGFUYOKvdg==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "@smithy/util-uri-escape": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/querystring-parser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.1.tgz", - "integrity": "sha512-Ma2XC7VS9aV77+clSFylVUnPZRindhB7BbmYiNOdr+CHt/kZNJoPP0cd3QxCnCFyPXC4eybmyE98phEHkqZ5Jw==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/service-error-classification": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.1.tgz", - "integrity": "sha512-3JNjBfOWpj/mYfjXJHB4Txc/7E4LVq32bwzE7m28GN79+M1f76XHflUaSUkhOriprPDzev9cX/M+dEB80DNDKA==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.1.tgz", - "integrity": "sha512-hC8F6qTBbuHRI/uqDgqqi6J0R4GtEZcgrZPhFQnMhfJs3MnUTGSnR1NSJCJs5VWlMydu0kJz15M640fJlRsIOw==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/signature-v4": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.0.1.tgz", - "integrity": "sha512-nCe6fQ+ppm1bQuw5iKoeJ0MJfz2os7Ic3GBjOkLOPtavbD1ONoyE3ygjBfz2ythFWm4YnRm6OxW+8p/m9uCoIA==", - "dev": true, - "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", - "@smithy/protocol-http": "^5.0.1", - "@smithy/types": "^4.1.0", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-middleware": "^4.0.1", - "@smithy/util-uri-escape": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.1.6.tgz", - "integrity": "sha512-UYDolNg6h2O0L+cJjtgSyKKvEKCOa/8FHYJnBobyeoeWDmNpXjwOAtw16ezyeu1ETuuLEOZbrynK0ZY1Lx9Jbw==", - "dev": true, - "dependencies": { - "@smithy/core": "^3.1.5", - "@smithy/middleware-endpoint": "^4.0.6", - "@smithy/middleware-stack": "^4.0.1", - "@smithy/protocol-http": "^5.0.1", - "@smithy/types": "^4.1.0", - "@smithy/util-stream": "^4.1.2", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.1.0.tgz", - "integrity": "sha512-enhjdwp4D7CXmwLtD6zbcDMbo6/T6WtuuKCY49Xxc6OMOmUWlBEBDREsxxgV2LIdeQPW756+f97GzcgAwp3iLw==", - "dev": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/url-parser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.1.tgz", - "integrity": "sha512-gPXcIEUtw7VlK8f/QcruNXm7q+T5hhvGu9tl63LsJPZ27exB6dtNwvh2HIi0v7JcXJ5emBxB+CJxwaLEdJfA+g==", - "dev": true, - "dependencies": { - "@smithy/querystring-parser": "^4.0.1", - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-base64": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", - "dev": true, - "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-body-length-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", - "dev": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", - "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", - "dev": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-buffer-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", - "dev": true, - "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-config-provider": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", - "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", - "dev": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.7.tgz", - "integrity": "sha512-CZgDDrYHLv0RUElOsmZtAnp1pIjwDVCSuZWOPhIOBvG36RDfX1Q9+6lS61xBf+qqvHoqRjHxgINeQz47cYFC2Q==", - "dev": true, - "dependencies": { - "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.6", - "@smithy/types": "^4.1.0", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.7.tgz", - "integrity": "sha512-79fQW3hnfCdrfIi1soPbK3zmooRFnLpSx3Vxi6nUlqaaQeC5dm8plt4OTNDNqEEEDkvKghZSaoti684dQFVrGQ==", - "dev": true, - "dependencies": { - "@smithy/config-resolver": "^4.0.1", - "@smithy/credential-provider-imds": "^4.0.1", - "@smithy/node-config-provider": "^4.0.1", - "@smithy/property-provider": "^4.0.1", - "@smithy/smithy-client": "^4.1.6", - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-endpoints": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.1.tgz", - "integrity": "sha512-zVdUENQpdtn9jbpD9SCFK4+aSiavRb9BxEtw9ZGUR1TYo6bBHbIoi7VkrFQ0/RwZlzx0wRBaRmPclj8iAoJCLA==", - "dev": true, - "dependencies": { - "@smithy/node-config-provider": "^4.0.1", - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-hex-encoding": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", - "dev": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-middleware": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.1.tgz", - "integrity": "sha512-HiLAvlcqhbzhuiOa0Lyct5IIlyIz0PQO5dnMlmQ/ubYM46dPInB+3yQGkfxsk6Q24Y0n3/JmcA1v5iEhmOF5mA==", - "dev": true, - "dependencies": { - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-retry": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.1.tgz", - "integrity": "sha512-WmRHqNVwn3kI3rKk1LsKcVgPBG6iLTBGC1iYOV3GQegwJ3E8yjzHytPt26VNzOWr1qu0xE03nK0Ug8S7T7oufw==", - "dev": true, - "dependencies": { - "@smithy/service-error-classification": "^4.0.1", - "@smithy/types": "^4.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-stream": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.1.2.tgz", - "integrity": "sha512-44PKEqQ303d3rlQuiDpcCcu//hV8sn+u2JBo84dWCE0rvgeiVl0IlLMagbU++o0jCWhYCsHaAt9wZuZqNe05Hw==", - "dev": true, - "dependencies": { - "@smithy/fetch-http-handler": "^5.0.1", - "@smithy/node-http-handler": "^4.0.3", - "@smithy/types": "^4.1.0", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-uri-escape": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", - "dev": true, - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-utf8": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", - "dev": true, - "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "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, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/fs-extra": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", - "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "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": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", - "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" - } - }, - "node_modules/@types/node": { - "version": "22.7.9", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.9.tgz", - "integrity": "sha512-jrTfRC7FM6nChvU7X2KqcrgquofrWLFDeYC1hKfwNWomVvrn7JIksqf344WN2X/y8xrgqBd2dJATZV4GbatBfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "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.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "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/@xmldom/xmldom": { - "version": "0.9.8", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.8.tgz", - "integrity": "sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==", - "dev": true, - "peer": true, - "engines": { - "node": ">=14.6" - } - }, - "node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "ISC", - "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, - "license": "MIT" - }, - "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/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/aws-cdk": { - "version": "2.177.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.177.0.tgz", - "integrity": "sha512-TiBoyE5wMB5q4jX1bELwkklgbs5eLY1Phjfnb4Mof0K9tOSRJ9UEq6xEamF0esMS+TuYU7a/ESTpmKX3iYqA3w==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "cdk": "bin/cdk" - }, - "engines": { - "node": ">= 14.15.0" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/aws-cdk-lib": { - "version": "2.177.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.177.0.tgz", - "integrity": "sha512-nTnHAwjZaPJ5gfJjtzE/MyK6q0a66nWthoJl7l8srucRb+I30dczhbbXor6QCdVpJaTRAEliMOMq23aglsAQbg==", - "bundleDependencies": [ - "@balena/dockerignore", - "case", - "fs-extra", - "ignore", - "jsonschema", - "minimatch", - "punycode", - "semver", - "table", - "yaml", - "mime-types" - ], - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.208", - "@aws-cdk/asset-kubectl-v20": "^2.1.3", - "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0", - "@aws-cdk/cloud-assembly-schema": "^39.2.0", - "@balena/dockerignore": "^1.0.2", - "case": "1.6.3", - "fs-extra": "^11.2.0", - "ignore": "^5.3.2", - "jsonschema": "^1.4.1", - "mime-types": "^2.1.35", - "minimatch": "^3.1.2", - "punycode": "^2.3.1", - "semver": "^7.6.3", - "table": "^6.8.2", - "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", - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.17.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-styles": { - "version": "4.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/astral-regex": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/balanced-match": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/brace-expansion": { - "version": "1.1.11", - "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", - "inBundle": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/color-convert": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/color-name": { - "version": "1.1.4", - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/concat-map": { - "version": "0.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/emoji-regex": { - "version": "8.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { - "version": "3.1.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/fast-uri": { - "version": "3.0.3", - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/aws-cdk-lib/node_modules/fs-extra": { - "version": "11.2.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/aws-cdk-lib/node_modules/graceful-fs": { - "version": "4.2.11", - "inBundle": true, - "license": "ISC" - }, - "node_modules/aws-cdk-lib/node_modules/ignore": { - "version": "5.3.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/jsonfile": { - "version": "6.1.0", - "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", - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { - "version": "4.4.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/mime-db": { - "version": "1.52.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/mime-types": { - "version": "2.1.35", - "inBundle": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/minimatch": { - "version": "3.1.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.3.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/aws-cdk-lib/node_modules/require-from-string": { - "version": "2.0.2", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.6.3", - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/aws-cdk-lib/node_modules/slice-ansi": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/string-width": { - "version": "4.2.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/strip-ansi": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.8.2", - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/universalify": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/yaml": { - "version": "1.10.2", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "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.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", - "dev": true, - "license": "MIT", - "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.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "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/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", - "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.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", - "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001688", - "electron-to-chromium": "^1.5.73", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.1" - }, - "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, - "license": "Apache-2.0", - "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, - "license": "MIT", - "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.30001700", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz", - "integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/cdk-ecr-deployment": { - "version": "3.0.33", - "resolved": "https://registry.npmjs.org/cdk-ecr-deployment/-/cdk-ecr-deployment-3.0.33.tgz", - "integrity": "sha512-G/QzjDQ1SoiBtO6KmrukgdBrjtqz3VAxa/T8K46/h9uf0eIAlGGGX96ODeI3Yv8udJDOgjNhu61bI2//81Wjbw==", - "bundleDependencies": [ - "got", - "hpagent" - ], - "dependencies": { - "aws-cdk-lib": "^2.0.0", - "constructs": "^10.0.5", - "got": "^11.8.6", - "hpagent": "^0.1.2" - }, - "peerDependencies": { - "aws-cdk-lib": "^2.0.0", - "constructs": "^10.0.5" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@sindresorhus/is": { - "version": "4.6.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "inBundle": true, - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@types/cacheable-request": { - "version": "6.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@types/cacheable-request/node_modules/@types/node": { - "version": "20.11.25", - "inBundle": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "inBundle": true, - "license": "MIT" - }, - "node_modules/cdk-ecr-deployment/node_modules/@types/keyv": { - "version": "3.1.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@types/keyv/node_modules/@types/node": { - "version": "20.11.25", - "inBundle": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@types/responselike": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/@types/responselike/node_modules/@types/node": { - "version": "20.11.25", - "inBundle": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/cacheable-lookup": { - "version": "5.0.4", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/cacheable-request": { - "version": "7.0.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/clone-response": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/clone-response/node_modules/mimic-response": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/decompress-response": { - "version": "6.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/defer-to-connect": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/end-of-stream": { - "version": "1.4.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/get-stream": { - "version": "5.2.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/got": { - "version": "11.8.6", - "inBundle": true, - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/hpagent": { - "version": "0.1.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/cdk-ecr-deployment/node_modules/http-cache-semantics": { - "version": "4.1.1", - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/cdk-ecr-deployment/node_modules/http2-wrapper": { - "version": "1.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/json-buffer": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/cdk-ecr-deployment/node_modules/keyv": { - "version": "4.5.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/lowercase-keys": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/mimic-response": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/normalize-url": { - "version": "6.1.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/once": { - "version": "1.4.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/p-cancelable": { - "version": "2.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/pump": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/quick-lru": { - "version": "5.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/resolve-alpn": { - "version": "1.2.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/cdk-ecr-deployment/node_modules/responselike": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cdk-ecr-deployment/node_modules/undici-types": { - "version": "5.26.5", - "inBundle": true, - "license": "MIT" - }, - "node_modules/cdk-ecr-deployment/node_modules/wrappy": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC" - }, - "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, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "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, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/codemaker": { - "version": "1.108.0", - "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.108.0.tgz", - "integrity": "sha512-EwMvLf3tkBXllS4hZbr3WYm4kZiAH5Spd01MaRd+yJ636RfwIvpGgCGVqYbjW0RJ7yyfnakZ0HvCc8PxqyYWbA==", - "dev": true, - "dependencies": { - "camelcase": "^6.3.0", - "decamelize": "^5.0.1", - "fs-extra": "^10.1.0" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/codemaker/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/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, - "license": "MIT" - }, - "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/commonmark": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.31.2.tgz", - "integrity": "sha512-2fRLTyb9r/2835k5cwcAwOj0DEc44FARnMp5veGsJ+mEAZdi52sNopLu07ZyElQUz058H43whzlERDIaaSw4rg==", - "dev": true, - "dependencies": { - "entities": "~3.0.1", - "mdurl": "~1.0.1", - "minimist": "~1.2.8" - }, - "bin": { - "commonmark": "bin/commonmark" - }, - "engines": { - "node": "*" - } - }, - "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.312", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.1.312.tgz", - "integrity": "sha512-eC6tBCDIz/arXAvJwqlv+fPZb6tly4Z58kcTFygSLDp+XuqOxuLTaEyBcLcJQy20+zeUopgWw7K2Go0EWmJ8NQ==", - "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-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "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/decamelize": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", - "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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, - "license": "MIT", - "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, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.104", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.104.tgz", - "integrity": "sha512-Us9M2L4cO/zMBqVkJtnj353nQhMju9slHm62NprKTmdF3HH8wYOtNvDFq/JB2+ZRoGLzdvYDiATlMHs98XBM1g==", - "dev": true, - "license": "ISC" - }, - "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, - "license": "MIT", - "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, - "license": "MIT" - }, - "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "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, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "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/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "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.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "peer": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.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/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ] - }, - "node_modules/fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "peer": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "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, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { + "version": "1.0.2", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } + "inBundle": true, + "license": "Apache-2.0" }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "node_modules/aws-cdk-lib/node_modules/ajv": { + "version": "8.17.1", "dev": true, + "inBundle": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "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/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">=12" - } - }, - "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.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, + "inBundle": true, "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "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": { - "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" - }, + "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": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 0.8.0" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/aws-cdk-lib/node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "peer": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 6" + "node": ">=7.0.0" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "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/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-uri": { + "version": "3.0.6", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/aws-cdk-lib/node_modules/fs-extra": { + "version": "11.3.0", "dev": true, + "inBundle": true, "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": ">=4" + "node": ">=14.14" } }, - "node_modules/graceful-fs": { + "node_modules/aws-cdk-lib/node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true + "dev": true, + "inBundle": true, + "license": "ISC" }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "node_modules/aws-cdk-lib/node_modules/ignore": { + "version": "5.3.2", + "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "node": ">= 4" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/jsonfile": { + "version": "6.1.0", "dev": true, + "inBundle": true, + "license": "MIT", "dependencies": { - "function-bind": "^1.1.2" + "universalify": "^2.0.0" }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/aws-cdk-lib/node_modules/jsonschema": { + "version": "1.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": "*" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { + "version": "4.4.2", "dev": true, + "inBundle": true, "license": "MIT" }, - "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==", + "node_modules/aws-cdk-lib/node_modules/mime-db": { + "version": "1.52.0", "dev": true, - "license": "Apache-2.0", + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=10.17.0" + "node": ">= 0.6" } }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "node_modules/aws-cdk-lib/node_modules/mime-types": { + "version": "2.1.35", "dev": true, + "inBundle": true, "license": "MIT", "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "mime-db": "1.52.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.6" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "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": ">=0.8.19" + "node": "*" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/punycode": { + "version": "2.3.1", "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" } }, - "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/aws-cdk-lib/node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/semver": { + "version": "7.6.3", "dev": true, - "license": "MIT" + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "node_modules/aws-cdk-lib/node_modules/slice-ansi": { + "version": "4.0.0", "dev": true, + "inBundle": true, "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "peer": true, - "engines": { - "node": ">=0.10.0" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/string-width": { + "version": "4.2.3", "dev": true, + "inBundle": true, "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "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==", + "node_modules/aws-cdk-lib/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, + "inBundle": true, "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/aws-cdk-lib/node_modules/table": { + "version": "6.9.0", "dev": true, - "peer": true, + "inBundle": true, + "license": "BSD-3-Clause", "dependencies": { - "is-extglob": "^2.1.1" + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10.0.0" } }, - "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==", + "node_modules/aws-cdk-lib/node_modules/universalify": { + "version": "2.0.1", "dev": true, + "inBundle": true, + "license": "MIT", "engines": { - "node": ">=0.12.0" + "node": ">= 10.0.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==", + "node_modules/aws-cdk-lib/node_modules/yaml": { + "version": "1.10.2", "dev": true, - "license": "MIT", + "inBundle": true, + "license": "ISC", "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 6" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" + "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/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==", + "node_modules/bowser": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", + "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", + "dev": true + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "peer": true, + "dependencies": { + "fill-range": "^7.1.1" + }, "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==", + "node_modules/case": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", + "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", "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": ">= 0.8.0" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "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, - "license": "BSD-3-Clause", "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", + "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "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==", + "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, - "license": "BSD-3-Clause", + "license": "ISC", "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=0.8" } }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "node_modules/codemaker": { + "version": "1.108.0", + "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.108.0.tgz", + "integrity": "sha512-EwMvLf3tkBXllS4hZbr3WYm4kZiAH5Spd01MaRd+yJ636RfwIvpGgCGVqYbjW0RJ7yyfnakZ0HvCc8PxqyYWbA==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" + "camelcase": "^6.3.0", + "decamelize": "^5.0.1", + "fs-extra": "^10.1.0" }, "engines": { - "node": ">=10" + "node": ">= 14.17.0" } }, - "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "node_modules/codemaker/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" - }, - "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" + "node": ">=10" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "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, - "license": "MIT", "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0" + "color-name": "~1.1.4" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=7.0.0" } }, - "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "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/commonmark": { + "version": "0.31.2", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.31.2.tgz", + "integrity": "sha512-2fRLTyb9r/2835k5cwcAwOj0DEc44FARnMp5veGsJ+mEAZdi52sNopLu07ZyElQUz058H43whzlERDIaaSw4rg==", "dev": true, - "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" + "entities": "~3.0.1", + "mdurl": "~1.0.1", + "minimist": "~1.2.8" }, "bin": { - "jest": "bin/jest.js" + "commonmark": "bin/commonmark" }, "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": "*" } }, - "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "node_modules/constructs": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz", + "integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==", "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "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.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", - "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 - } - } + "license": "Apache-2.0" }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "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, + "license": "MIT" + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=4.0" } }, - "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "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, - "license": "MIT", "dependencies": { - "detect-newline": "^3.0.0" + "ms": "2.1.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "node_modules/detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=4" } }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "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, - "license": "MIT", + "license": "BSD-3-Clause", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.3.1" } }, - "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "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, + "license": "MIT" + }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@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.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.12" }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, "license": "MIT", - "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, - "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8.6.0" } }, - "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "jest-util": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ] }, - "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==", + "node_modules/fast-xml-parser": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", + "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + }, + { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" } + ], + "dependencies": { + "strnum": "^1.0.5" + }, + "bin": { + "fxparser": "src/cli/cli.js" } }, - "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "peer": true, + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, - "license": "MIT", "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=12" } }, - "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", - "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-runner/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==", + "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, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@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.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "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.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "license": "MIT", - "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/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "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, "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, "engines": { - "node": ">=10" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "MIT", + "peer": true, "dependencies": { - "@jest/types": "^29.6.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "is-glob": "^4.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 6" } }, - "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", - "dev": true, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "inBundle": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "leven": "^3.1.0", - "pretty-format": "^29.7.0" + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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, - "license": "MIT", - "engines": { - "node": ">=10" + "node": ">=0.4.7" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "uglify-js": "^3.1.4" } }, - "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "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, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-util": "^29.7.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, + "peer": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.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==", + "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, "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">=8" } }, - "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, - "license": "MIT" - }, - "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==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "peer": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "is-extglob": "^2.1.1" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "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, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, + "peer": true, "engines": { - "node": ">=6" + "node": ">=0.12.0" } }, "node_modules/jsii": { @@ -5472,31 +2717,12 @@ "node": ">=14.17" } }, - "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, - "license": "MIT" - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "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/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -5509,51 +2735,6 @@ "graceful-fs": "^4.1.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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT" - }, - "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/log4js": { "version": "6.9.1", "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", @@ -5570,74 +2751,18 @@ "node": ">=8.0" } }, - "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, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "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, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", "dev": true }, - "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, - "license": "MIT" - }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -5653,6 +2778,7 @@ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "peer": true, "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -5661,28 +2787,6 @@ "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, - "license": "MIT", - "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/minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", @@ -5708,13 +2812,6 @@ "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, - "license": "MIT" - }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -5722,68 +2819,6 @@ "inBundle": true, "license": "MIT" }, - "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, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", - "dev": true, - "license": "MIT" - }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/oo-ascii-tree": { "version": "1.108.0", "resolved": "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.108.0.tgz", @@ -5802,49 +2837,6 @@ "node": ">=4" } }, - "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, - "license": "MIT", - "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-queue": { "version": "6.6.2", "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", @@ -5873,69 +2865,6 @@ "node": ">=8" } }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT" - }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -5958,18 +2887,12 @@ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, + "peer": true, "engines": { "node": ">=8.6" }, @@ -5977,32 +2900,10 @@ "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, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/prettier": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz", - "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", "bin": { @@ -6015,52 +2916,12 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.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, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/publib": { - "version": "0.2.955", - "resolved": "https://registry.npmjs.org/publib/-/publib-0.2.955.tgz", - "integrity": "sha512-dqOlYcD0SLHNDgfbieyy4c+RyKR3sP/sYQjvXKa3WrGbopmOwDqPouqNbb49ehpp5hqSzbeuKPyZ6+gW+11GGA==", + "version": "0.2.956", + "resolved": "https://registry.npmjs.org/publib/-/publib-0.2.956.tgz", + "integrity": "sha512-N7QtK5BCgq1ilaM0FLcsYQ8/dXSuVBJUYCbnxSygPk59z+hy4/C1l7KiROd07CEQldryvtCRlMgbVtXxFbcv4w==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@aws-sdk/client-codeartifact": "^3.758.0", "@aws-sdk/credential-providers": "^3.758.0", @@ -6164,23 +3025,6 @@ "node": ">= 4.0.0" } }, - "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -6202,12 +3046,6 @@ ], "peer": true }, - "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/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -6227,59 +3065,6 @@ "node": ">=0.10.0" } }, - "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "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, - "license": "MIT", - "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": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -6339,57 +3124,12 @@ "semver": "^6.3.0" } }, - "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, - "license": "MIT", - "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, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/shlex": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/shlex/-/shlex-2.1.2.tgz", "integrity": "sha512-Nz6gtibMVgYeMEhUjp2KuwAgqaJA1K155dU/HuDaEJUGgnmYfVtVZah+uerVWdH8UGnyahhDCgABbYTbs254+w==", "dev": true }, - "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, - "license": "MIT" - }, - "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/sort-json": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/sort-json/-/sort-json-2.0.1.tgz", @@ -6434,24 +3174,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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/stream-chain": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", @@ -6515,20 +3237,6 @@ "node": ">= 4.0.0" } }, - "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, - "license": "MIT", - "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", @@ -6557,39 +3265,6 @@ "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, - "license": "MIT", - "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, - "license": "MIT", - "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, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/strnum": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", @@ -6614,45 +3289,12 @@ "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, - "license": "MIT", - "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, - "license": "BSD-3-Clause" - }, "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, + "peer": true, "dependencies": { "is-number": "^7.0.0" }, @@ -6660,68 +3302,6 @@ "node": ">=8.0" } }, - "node_modules/ts-jest": { - "version": "29.2.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.6.tgz", - "integrity": "sha512-yTNZVZqc8lSixm+QGVFcPe6+yj7+TWZwIesuOWvfcn4B9bz5x4NDzVCQQjOs7Hfouu36aEqfEbo9Qpo+gq8dDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "^0.2.6", - "ejs": "^3.1.10", - "fast-json-stable-stringify": "^2.1.0", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "^4.1.2", - "make-error": "^1.3.6", - "semver": "^7.7.1", - "yargs-parser": "^21.1.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/transform": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -6772,33 +3352,10 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": 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, - "license": "MIT", - "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, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true, "license": "Apache-2.0", "bin": { @@ -6839,37 +3396,6 @@ "node": ">= 10.0.0" } }, - "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, "node_modules/uuid": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", @@ -6890,47 +3416,6 @@ "dev": true, "license": "MIT" }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "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, - "license": "Apache-2.0", - "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, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -6963,25 +3448,6 @@ "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/xmlbuilder": { "version": "15.1.1", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", @@ -7001,13 +3467,6 @@ "node": ">=10" } }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, "node_modules/yargs": { "version": "17.7.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", @@ -7045,19 +3504,6 @@ "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, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } } } } diff --git a/package.json b/package.json index 147fdde..32402ee 100644 --- a/package.json +++ b/package.json @@ -21,38 +21,33 @@ ], "stability": "stable", "scripts": { - "test": "jest", - "cdk": "cdk", + "cdk": "npm run build && cdk", "clean": "git clean -fXd", "build": "jsii", "build:watch": "jsii --watch", "package": "jsii-pacmak -v" }, "devDependencies": { - "@types/jest": "^29.5.14", "@types/node": "22.7.9", - "aws-cdk": "2.177.0", - "aws-cdk-lib": "2.177.0", - "constructs": "10.1.312", - "jest": "^29.7.0", - "jsii": "^5.7.6", - "jsii-pacmak": "^1.108.0", - "prettier": "3.5.2", - "publib": "^0.2.955", - "ts-jest": "^29.2.5", - "ts-node": "^10.9.2", - "typescript": "~5.6.3" + "aws-cdk": "2.1002.0", + "aws-cdk-lib": "2.181.1", + "constructs": "10.4.2", + "jsii": "5.7.7", + "jsii-pacmak": "1.108.0", + "prettier": "3.5.3", + "publib": "0.2.956", + "ts-node": "10.9.2", + "typescript": "5.8.2" }, "bundledDependencies": [ "handlebars" ], "dependencies": { - "cdk-ecr-deployment": "^3.0.33", - "handlebars": "^4.7.8" + "handlebars": "4.7.8" }, "peerDependencies": { - "aws-cdk-lib": "2.177.0", - "constructs": "^10.1.312" + "aws-cdk-lib": "2.181.1", + "constructs": "10.4.2" }, "jsii": { "outdir": "dist", diff --git a/test/oncoanalyser-stack.test.ts b/test/oncoanalyser-stack.test.ts deleted file mode 100644 index df77870..0000000 --- a/test/oncoanalyser-stack.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -// import * as cdk from 'aws-cdk-lib'; -// import { Template } from 'aws-cdk-lib/assertions'; -// import * as OncoanalyserStack from '../lib/oncoanalyser-stack-stack'; - -// example test. To run these tests, uncomment this file along with the -// example resource in lib/oncoanalyser-stack-stack.ts -test('SQS Queue Created', () => { -// const app = new cdk.App(); -// // WHEN -// const stack = new OncoanalyserStack.OncoanalyserStackStack(app, 'MyTestStack'); -// // THEN -// const template = Template.fromStack(stack); - -// template.hasResourceProperties('AWS::SQS::Queue', { -// VisibilityTimeout: 300 -// }); -});