From 4c9f43891eaa15c0d9ffe6225a69906f64ffb22d Mon Sep 17 00:00:00 2001 From: Cody Edwards Date: Mon, 7 Aug 2023 21:04:22 +0000 Subject: [PATCH] chore(deps): bumping jsii to 5.1.9 and node to 18 Updated jsii and fixed issues that came up from that. jsii requires at least Node.js 16. 16 is EOL soon, so change minimum required version to 18. --- .github/workflows/ci.yml | 2 +- CONTRIBUTING.md | 6 +- README.md | 2 +- integ/.eslintignore | 1 + .../common/scripts/bash/deploy-utils.sh | 6 +- .../test/deadline_01_repository.test.ts | 3 + .../deadline_05_secretsManagement.test.ts | 20 ++-- integ/package.json | 4 +- integ/scripts/bash/deploy-infrastructure.sh | 2 +- integ/scripts/bash/teardown-infrastructure.sh | 2 +- lambda-layers/package.json | 2 +- .../aws-rfdk/docs/upgrade/upgrading-1.3.md | 8 ++ packages/aws-rfdk/lib/deadline/lib/stage.ts | 11 +-- .../lambdas/nodejs/asg-attach-eni/index.ts | 19 ++-- .../nodejs/asg-attach-eni/test/test.ts | 46 ++++++++++ .../lib/lambdas/nodejs/export-logs/index.ts | 2 +- .../lib/custom-resource/simple-resource.ts | 11 ++- .../lib/deadline-client/deadline-client.ts | 3 +- .../nodejs/lib/dynamodb/composite-table.ts | 18 ++-- .../nodejs/lib/secrets-manager/secret.ts | 13 +-- .../lib/secrets-manager/test/secret.test.ts | 6 +- .../nodejs/pad-efs-storage/handlers.ts | 2 +- .../nodejs/unhealthyFleetAction/index.ts | 3 +- .../nodejs/wait-for-stable-service/handler.ts | 4 +- .../nodejs/x509-certificate/acm-handlers.ts | 4 +- .../nodejs/x509-certificate/handlers.ts | 4 +- packages/aws-rfdk/package.json | 4 +- scripts/rfdk_build_environment.sh | 2 +- tools/pkglint/lib/rules.ts | 8 +- yarn.lock | 91 ++++++++++++++++++- 30 files changed, 228 insertions(+), 81 deletions(-) create mode 100644 packages/aws-rfdk/docs/upgrade/upgrading-1.3.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 377df201f..e2e4ae7ac 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: - node-version: [14.x, 16.x, 18.x] + node-version: [18.x, 20.x] steps: - uses: actions/checkout@v3 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4d740387b..a16c3cd8b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ and let us know if it's not up-to-date (even better, submit a PR with your corr The RFDK is written in Typescript and converted, using [jsii](https://github.com/aws/jsii), into Python. Thus, the minimal development environment must include: -- Node.js >= 14.19.3 +- Node.js >= 18.0.0 - docker >= 18 We also recommend developing on a Linux system. @@ -39,10 +39,10 @@ the [instructions](https://github.com/nvm-sh/nvm#installing-and-updating) to ins then you can install a version of Node.js and set your shell to make it available when you login: ```bash -# For example, the latest version of Node.js 14.x +# For example, the latest version of Node.js 18.x # Find out the version number for latest -LATEST_VERSION=$(nvm ls-remote | grep v14 | grep 'Latest' | awk '{print $1}') +LATEST_VERSION=$(nvm ls-remote | grep v18 | grep 'Latest' | awk '{print $1}') # Install it nvm install ${LATEST_VERSION} diff --git a/README.md b/README.md index e95c99574..380ed4286 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ It offers high-level object-oriented abstractions to define render farm infrastr using the power of Python and Typescript. The RFDK is available in: -- Javascript, Typescript ([Node.js >= 14.19.3](https://nodejs.org/download/release/latest-v14.x/)) +- Javascript, Typescript ([Node.js >= 18.0.0](https://nodejs.org/download/release/latest-v18.x/)) - We recommend using an [Active LTS Release](https://nodejs.org/en/about/releases/) - Python ([Python >= 3.6](https://www.python.org/downloads/)) diff --git a/integ/.eslintignore b/integ/.eslintignore index c3e81be67..9be418fd2 100644 --- a/integ/.eslintignore +++ b/integ/.eslintignore @@ -1,2 +1,3 @@ node_modules cdk.output +cdk.out diff --git a/integ/components/deadline/common/scripts/bash/deploy-utils.sh b/integ/components/deadline/common/scripts/bash/deploy-utils.sh index 90a7c9ef8..0e70fe05b 100755 --- a/integ/components/deadline/common/scripts/bash/deploy-utils.sh +++ b/integ/components/deadline/common/scripts/bash/deploy-utils.sh @@ -23,7 +23,7 @@ function deploy_component_stacks () { # (https://docs.aws.amazon.com/cdk/latest/guide/context.html#context_methods) # in our case this is for stack.availabilityZones - npx cdk synth &> "${INTEG_TEMP_DIR}/${COMPONENT_NAME}/synth.log" + npx cdk synth --output "$(pwd)/cdk.out" --app "npx ts-node --cwd $(pwd) bin/${COMPONENT_NAME}.ts" &> "${INTEG_TEMP_DIR}/${COMPONENT_NAME}/synth.log" SYNTH_EXIT_CODE=$? echo $SYNTH_EXIT_CODE > "${INTEG_TEMP_DIR}/${COMPONENT_NAME}/synth-exit-code" if [[ $SYNTH_EXIT_CODE -ne 0 ]] @@ -42,7 +42,7 @@ function deploy_component_stacks () { for stack in $(cdk_stack_deploy_order); do echo "$(timestamp) [${COMPONENT_NAME}] -> [${stack}] stack deployment started" - npx cdk deploy --app cdk.out --require-approval=never -e "${stack}" &>> "${deploy_log_path}" + npx cdk deploy --concurrency 10 --app $(pwd)/cdk.out --require-approval=never -e "${stack}" &>> "${deploy_log_path}" STACK_DEPLOY_EXIT_CODE=$? if [[ $STACK_DEPLOY_EXIT_CODE -ne 0 ]] then @@ -93,7 +93,7 @@ function destroy_component_stacks () { cp /dev/null "${destroy_log_path}" for stack in $(cdk_stack_destroy_order); do echo "$(timestamp) [${COMPONENT_NAME}] -> [${stack}] stack destroy started" - npx cdk destroy --app cdk.out -e -f "${stack}" &>> "${destroy_log_path}" + npx cdk destroy --app $(pwd)/cdk.out -e -f "${stack}" &>> "${destroy_log_path}" STACK_DESTROY_EXIT_CODE=$? if [[ $STACK_DESTROY_EXIT_CODE -ne 0 ]] then diff --git a/integ/components/deadline/deadline_01_repository/test/deadline_01_repository.test.ts b/integ/components/deadline/deadline_01_repository/test/deadline_01_repository.test.ts index e5b1015c4..942a4eaca 100644 --- a/integ/components/deadline/deadline_01_repository/test/deadline_01_repository.test.ts +++ b/integ/components/deadline/deadline_01_repository/test/deadline_01_repository.test.ts @@ -254,6 +254,7 @@ describe.each(testCases)('Deadline Repository tests (%s)', (_, id) => { ingestionTime: expect.anything(), message: expect.stringMatching( /Cloud-init v. / ), timestamp: expect.anything(), + eventId: expect.anything(), }, ); }); @@ -272,6 +273,7 @@ describe.each(testCases)('Deadline Repository tests (%s)', (_, id) => { ingestionTime: expect.anything(), message: expect.not.stringMatching( /\w*(? { ingestionTime: expect.anything(), message: expect.stringMatching( /Executing \/tmp\/repoinstalltemp\/deadlinecommand.exe/ ), timestamp: expect.anything(), + eventId: expect.anything(), }, ); }); diff --git a/integ/components/deadline/deadline_05_secretsManagement/test/deadline_05_secretsManagement.test.ts b/integ/components/deadline/deadline_05_secretsManagement/test/deadline_05_secretsManagement.test.ts index b7c5e7d53..8d964308c 100644 --- a/integ/components/deadline/deadline_05_secretsManagement/test/deadline_05_secretsManagement.test.ts +++ b/integ/components/deadline/deadline_05_secretsManagement/test/deadline_05_secretsManagement.test.ts @@ -3,12 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { BlockList } from 'net'; import { CloudFormation } from '@aws-sdk/client-cloudformation'; import { SecretsManager } from '@aws-sdk/client-secrets-manager'; -import { - CidrBlock, - NetworkUtils, -} from 'aws-cdk-lib/aws-ec2/lib/network-util'; import { ssmCommand } from '../../common/functions/awaitSsmCommand'; // Name of testing stack is derived from env variable to ensure uniqueness @@ -281,14 +278,17 @@ describe('Deadline Secrets Management tests', () => { // source IP and connection IP are within the expected subnet CIDR blocks. expect(identityInfos.some(identityInfo => { return expectedSubnetCidrPairs.some(expected => { - const connectionIpNum = NetworkUtils.ipToNum(identityInfo.connectionIpAddress); - const connectionSubnetCidr = new CidrBlock(expected.connectionSubnetCidrBlock); + const connectionSubnet = expected.connectionSubnetCidrBlock.split('/'); - const sourceIpNum = NetworkUtils.ipToNum(identityInfo.sourceIpAddress); - const sourceIpSubnetCidr = new CidrBlock(expected.sourceSubnetCidrBlock); + const connectionSubnetRange = new BlockList(); + connectionSubnetRange.addSubnet(connectionSubnet[0], parseInt(connectionSubnet[1])); - return sourceIpSubnetCidr.minAddress() <= sourceIpNum && sourceIpNum <= sourceIpSubnetCidr.maxAddress() && - connectionSubnetCidr.minAddress() <= connectionIpNum && connectionIpNum <= connectionSubnetCidr.maxAddress(); + const sourceSubnet = expected.sourceSubnetCidrBlock.split('/'); + + const sourceSubnetRange = new BlockList(); + sourceSubnetRange.addSubnet(sourceSubnet[0], parseInt(sourceSubnet[1])); + + return sourceSubnetRange.check(identityInfo.sourceIpAddress) && connectionSubnetRange.check(identityInfo.connectionIpAddress); }); })).toBeTruthy(); }); diff --git a/integ/package.json b/integ/package.json index efad638e8..d0df9d9bd 100644 --- a/integ/package.json +++ b/integ/package.json @@ -40,7 +40,7 @@ "build+test": "yarn run build", "build+test+package": "yarn run build+test", "watch": "tsc -w", - "test": "jest", + "test": "npx jest", "cdk": "cdk", "e2e": "./scripts/bash/rfdk-integ-e2e.sh", "e2e-automated": "./scripts/bash/run-e2e-automated.sh", @@ -85,6 +85,6 @@ "constructs": "^10.0.0" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.0.0" } } \ No newline at end of file diff --git a/integ/scripts/bash/deploy-infrastructure.sh b/integ/scripts/bash/deploy-infrastructure.sh index f6cc547d8..968fd1c3b 100755 --- a/integ/scripts/bash/deploy-infrastructure.sh +++ b/integ/scripts/bash/deploy-infrastructure.sh @@ -16,7 +16,7 @@ echo "$(date "+%Y-%m-%dT%H:%M:%S") [infrastructure] deployment started" set +e # Hide the deploy log unless something goes wrong (save the scrollback buffer) -npx cdk deploy "*" --require-approval=never &> "${INTEG_TEMP_DIR}/infrastructure/deploy.txt" +npx cdk deploy "*" --concurrency 10 --require-approval=never --output "$(pwd)/cdk.out" --app "npx ts-node --cwd $(pwd) bin/_infrastructure.ts" &> "${INTEG_TEMP_DIR}/infrastructure/deploy.txt" deploy_exit_code=$? # If an exit code was returned from the deployment, output the deploy log diff --git a/integ/scripts/bash/teardown-infrastructure.sh b/integ/scripts/bash/teardown-infrastructure.sh index eb5e28ed7..7945e9612 100755 --- a/integ/scripts/bash/teardown-infrastructure.sh +++ b/integ/scripts/bash/teardown-infrastructure.sh @@ -14,7 +14,7 @@ cd "$INFRASTRUCTURE_APP" mkdir -p "${INTEG_TEMP_DIR}/infrastructure" # Hide the destroy log unless something goes wrong (save the scrollback buffer) -npx cdk destroy "*" -f &> "${INTEG_TEMP_DIR}/infrastructure/destroy.txt" +npx cdk destroy "*" --app "$(pwd)/cdk.out" -f &> "${INTEG_TEMP_DIR}/infrastructure/destroy.txt" destroy_exit_code=$? # If an exit code was returned from the destroy, output the destroy log diff --git a/lambda-layers/package.json b/lambda-layers/package.json index 8262478d4..a90bbe84e 100644 --- a/lambda-layers/package.json +++ b/lambda-layers/package.json @@ -24,7 +24,7 @@ "watch": "tsc -w" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.0.0" }, "stability": "stable", "maturity": "stable", diff --git a/packages/aws-rfdk/docs/upgrade/upgrading-1.3.md b/packages/aws-rfdk/docs/upgrade/upgrading-1.3.md new file mode 100644 index 000000000..9c57281e1 --- /dev/null +++ b/packages/aws-rfdk/docs/upgrade/upgrading-1.3.md @@ -0,0 +1,8 @@ +# Upgrading to RFDK v1.3.x or Newer + +## Updating Node.js + +Node 14 is End of Life and RFDK >= 1.3.x no longer supports it. Node.js 18.0.0 is the minimum version +that RFDK now supports. + +You can follow our [installation guide](CONTRIBUTING.md#installing-nodejs) for Node.js to upgrade to the latest version. diff --git a/packages/aws-rfdk/lib/deadline/lib/stage.ts b/packages/aws-rfdk/lib/deadline/lib/stage.ts index 6ef842b35..3b87486f2 100644 --- a/packages/aws-rfdk/lib/deadline/lib/stage.ts +++ b/packages/aws-rfdk/lib/deadline/lib/stage.ts @@ -18,9 +18,7 @@ import { /** * Build arguments to supply to a Docker image build */ -export interface BuildArgs { - readonly [name: string]: string; -} +export type BuildArgs = Record; /** * Docker container image recipe @@ -54,12 +52,7 @@ export interface Recipe { /** * A collection of Deadline Docker recipes */ -export interface DeadlineDockerRecipes { - /** - * A mapping of name to recipe - */ - readonly [name: string]: Recipe; -} +export type DeadlineDockerRecipes = Record; /** * The manifest included with Deadline Docker image recipes diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/index.ts b/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/index.ts index dc75155ff..fc5782bde 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/index.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/index.ts @@ -5,8 +5,9 @@ /* eslint-disable no-console */ +import { types } from 'util'; // eslint-disable-next-line import/no-extraneous-dependencies -import {AutoScaling, EC2} from 'aws-sdk'; +import {AutoScaling, EC2, AWSError} from 'aws-sdk'; /** * Contents of the Message sent from Sns in response to a lifecycle event. @@ -45,7 +46,7 @@ async function completeLifecycle(success: boolean, message: SnsLaunchInstanceMes const response = await autoscaling.completeLifecycleAction(request).promise(); console.log('Got response: ' + JSON.stringify(response)); } catch (e) { - throw new Error(`Error sending completeLifecycleAction: ${e.code} -- ${e.message}`); + throw new Error(`Error sending completeLifecycleAction: ${(e as AWSError)?.code} -- ${(e as Error)?.message}`); } } @@ -64,7 +65,7 @@ async function attachEniToInstance(instanceId: string, eniId: string): Promise { await attachEniToInstance(message.EC2InstanceId, eniId); success = true; } catch (e) { - console.error(e.toString()); - console.error(e.stack); + console.error(String(e)); + console.error((e as Error)?.stack); } finally { // Note: Instance stays in 'Pending: Wait' state unless this lambda signals a lifecycle transition, so we must **always** send one. // https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_CompleteLifecycleAction.html @@ -94,8 +95,12 @@ export async function handler(event: { [key: string]: any }): Promise { } } } catch (e) { - console.error(e.toString()); - console.error(e.stack); + if (types.isNativeError(e)) { + console.error(e.toString()); + console.error(e.stack); + } else { + console.error(String(e)); + } } } } diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/test/test.ts b/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/test/test.ts index fff1e137a..68e75793e 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/test/test.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/asg-attach-eni/test/test.ts @@ -220,3 +220,49 @@ test('continues when complete lifecycle errors', async () => { await expect(handler(event)).resolves.not.toThrow(); expect(console.error).toHaveBeenCalledTimes(4); // 4 = each of the two records printing two error messages }); + +test('continues when complete lifecycle errors non-error thrown', async () => { + // GIVEN + const event = { + Records: [ + { + Sns: { + Message: JSON.stringify({ + LifecycleTransition: 'autoscaling:EC2_INSTANCE_LAUNCHING', + AutoScalingGroupName: 'ASG-Name-1', + LifecycleHookName: 'Hook-Name-1', + EC2InstanceId: 'i-0000000000', + LifecycleActionToken: 'Action-Token-1', + NotificationMetadata: JSON.stringify({ + eniId: 'eni-000000000', + }), + }), + }, + }, + { + Sns: { + Message: JSON.stringify({ + LifecycleTransition: 'autoscaling:EC2_INSTANCE_LAUNCHING', + AutoScalingGroupName: 'ASG-Name-1', + LifecycleHookName: 'Hook-Name-1', + EC2InstanceId: 'i-0000000000', + LifecycleActionToken: 'Action-Token-1', + NotificationMetadata: JSON.stringify({ + eniId: 'eni-000000000', + }), + }), + }, + }, + ], + }; + + attachSpy = jest.fn( (request) => successRequestMock(request) ); + mock('EC2', 'attachNetworkInterface', attachSpy); + + jest.spyOn(JSON, 'parse').mockImplementation(jest.fn( () => {throw 47;} )); + + // THEN + // eslint-disable-next-line: no-floating-promises + await expect(handler(event)).resolves.not.toThrow(); + expect(console.error).toHaveBeenCalledTimes(2); // 2 = each of the two records printing one error message. +}); diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/export-logs/index.ts b/packages/aws-rfdk/lib/lambdas/nodejs/export-logs/index.ts index fbab156ea..075a5147a 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/export-logs/index.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/export-logs/index.ts @@ -50,7 +50,7 @@ async function confirmTaskCompletion(taskId: string): Promise { } catch (e) { // Retry 3 times before giving up if (errorCount < 3) { - console.error(`${taskId}: Encountered failure #${errorCount} with message: ${e.message}`); + console.error(`${taskId}: Encountered failure #${errorCount} with message: ${(e as Error)?.message}`); errorCount++; } else { throw e; diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/lib/custom-resource/simple-resource.ts b/packages/aws-rfdk/lib/lambdas/nodejs/lib/custom-resource/simple-resource.ts index 95a57320f..fb5ef888b 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/lib/custom-resource/simple-resource.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/lib/custom-resource/simple-resource.ts @@ -17,6 +17,7 @@ /* eslint-disable no-console */ +import { types } from 'util'; import { LambdaContext } from '../aws-lambda'; import { calculateSha256Hash } from './hash'; import { CfnResponseStatus, sendCfnResponse } from './reply'; @@ -51,7 +52,7 @@ export abstract class SimpleCustomResource { * @param resourceProperties The ResourceProperties given to the handler. * @returns The Data to send back to CloudFormation as attributes of this CfnCustomResource */ - public abstract async doCreate(physicalId: string, resourceProperties: object): Promise; + public abstract doCreate(physicalId: string, resourceProperties: object): Promise; /** * Called to perform the 'Delete' action. There are three locations in the state-diagram @@ -64,7 +65,7 @@ export abstract class SimpleCustomResource { * @param physicalId A stable hash value derived from the value of ResourceProperties * @param resourceProperties The ResourceProperties given to the handler. */ - public abstract async doDelete(physicalId: string, resourceProperties: object): Promise; + public abstract doDelete(physicalId: string, resourceProperties: object): Promise; /** * Handler/engine for the CustomResource state machine. Users of this class should @@ -118,7 +119,11 @@ export abstract class SimpleCustomResource { // failure to notify results in a stuck stack that takes at least an hour to // timeout. status = CfnResponseStatus.FAILED; - failReason = `${e.message}\n${e.stack}`; + if (types.isNativeError(e)) { + failReason = `${e.message}\n${e.stack}`; + } else { + failReason = String(e); + } } finally { // Always send a response to CloudFormation, signal success or // failure based on whether or not we had an exception. diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/lib/deadline-client/deadline-client.ts b/packages/aws-rfdk/lib/lambdas/nodejs/lib/deadline-client/deadline-client.ts index a2f37b204..2f3415c6d 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/lib/deadline-client/deadline-client.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/lib/deadline-client/deadline-client.ts @@ -183,7 +183,8 @@ export class DeadlineClient { try { return await this.performRequest(options, data); } catch(exception) { - const { statusCode, statusMessage } = exception; + const statusCode = (exception as any)?.statusCode; + const statusMessage = (exception as any)?.statusMessage; if (statusCode !== undefined && statusMessage !== undefined) { if (statusCode >= 500 && retriesLeft > 0) { console.log(`Request failed with ${statusCode}: ${statusMessage}. Will retry after ${retryDelayMs} ms.`); diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/lib/dynamodb/composite-table.ts b/packages/aws-rfdk/lib/lambdas/nodejs/lib/dynamodb/composite-table.ts index 20949c2f7..b7b6118c8 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/lib/dynamodb/composite-table.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/lib/dynamodb/composite-table.ts @@ -6,7 +6,7 @@ /* eslint-disable no-console */ // eslint-disable-next-line import/no-extraneous-dependencies -import { DynamoDB } from 'aws-sdk'; +import { DynamoDB, AWSError } from 'aws-sdk'; export class CompositeStringIndexTable { public static readonly API_VERSION = '2012-08-10'; @@ -110,7 +110,7 @@ export class CompositeStringIndexTable { ); return table; } catch (e) { - throw new Error(`CreateTable '${args.name}': ${e.code} -- ${e.message}`); + throw new Error(`CreateTable '${args.name}': ${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } @@ -149,11 +149,11 @@ export class CompositeStringIndexTable { this.tableName = undefined; } catch (e) { - if (e.code === 'ResourceNotFoundException') { + if ((e as AWSError)?.code === 'ResourceNotFoundException') { // Already gone. We're good. this.tableName = undefined; } else { - throw new Error(`DeleteTable '${this.tableName}': ${e.code} -- ${e.message}`); + throw new Error(`DeleteTable '${this.tableName}': ${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } } @@ -207,11 +207,11 @@ export class CompositeStringIndexTable { const response = await this.client.putItem(request).promise(); console.debug(`PutItem response: ${JSON.stringify(response)}`); } catch (e) { - if (e.code === 'ConditionalCheckFailedException' && !props.allow_overwrite) { + if ((e as AWSError)?.code === 'ConditionalCheckFailedException' && !props.allow_overwrite) { return false; } throw new Error(`PutItem '${props.primaryKeyValue}' '${props.sortKeyValue}:" ` + - `${e.code} -- ${e.message}`); + `${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } return true; } @@ -256,7 +256,7 @@ export class CompositeStringIndexTable { return item; } catch (e) { throw new Error(`GetItem '${props.primaryKeyValue}' '${props.sortKeyValue}:" ` + - `${e.code} -- ${e.message}`); + `${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } @@ -296,7 +296,7 @@ export class CompositeStringIndexTable { return false; } catch (e) { throw new Error(`DeleteItem '${props.primaryKeyValue}' '${props.sortKeyValue}:" ` + - `${e.code} -- ${e.message}`); + `${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } @@ -356,7 +356,7 @@ export class CompositeStringIndexTable { } while (request.ExclusiveStartKey); return items; } catch (e) { - throw new Error(`Query '${primaryKeyValue}':" ${e.code} -- ${e.message}`); + throw new Error(`Query '${primaryKeyValue}':" ${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } } diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/secret.ts b/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/secret.ts index 111eeb723..b91f47a32 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/secret.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/secret.ts @@ -5,8 +5,9 @@ /* eslint-disable no-console */ +import { isUint8Array } from 'util/types'; // eslint-disable-next-line import/no-extraneous-dependencies -import { SecretsManager } from 'aws-sdk'; +import { SecretsManager, AWSError } from 'aws-sdk'; import { Key } from '../kms'; import { isArn } from './validation'; @@ -59,7 +60,7 @@ export class Secret { return undefined; } catch (e) { throw new Error(`CreateSecret '${args.name}' failed in region '${args.client.config.region}': ` + - `${e.code} -- ${e.message}`); + `${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } @@ -94,7 +95,7 @@ export class Secret { this.arn = undefined; } catch (e) { throw new Error(`DeleteSecret '${this.arn}' failed in region '${this.client.config.region}':` + - `${e.code} -- ${e.message}`); + `${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } @@ -121,7 +122,7 @@ export class Secret { console.debug(`PutSecret response: ${JSON.stringify(response)}`); } catch (e) { throw new Error(`PutSecret '${this.arn}' failed in region '${this.client.config.region}':` + - `${e.code} -- ${e.message}`); + `${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } @@ -146,7 +147,7 @@ export class Secret { return data; } else if (typeof data === 'string') { return Buffer.from(data, 'binary'); - } else if (ArrayBuffer.isView(data)) { + } else if (isUint8Array(data)) { return Buffer.from(data); } else { throw new Error('Unknown type for SecretBinary data'); @@ -155,7 +156,7 @@ export class Secret { return response.SecretString; } catch (e) { throw new Error(`GetSecret '${this.arn}' failed in region '${this.client.config.region}':` + - `${e.code} -- ${e.message}`); + `${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } } } diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/test/secret.test.ts b/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/test/secret.test.ts index 3511d0e63..49049eb2a 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/test/secret.test.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/lib/secrets-manager/test/secret.test.ts @@ -304,8 +304,8 @@ describe('Secret class', () => { expect(fakeGetSecretValue.callCount).toEqual(1); }); - test('SecretBinary ArrayBuffer success', async () => { - const value: ArrayBufferView = new Int32Array(); + test('SecretBinary Uint8Array success', async () => { + const value: Uint8Array = new Uint8Array(); const arn = 'arn:aws:secretsmanager:fake0secret1:123:secret:1a2b/'; const fakeGetSecretValue = fake.resolves({ @@ -319,7 +319,7 @@ describe('Secret class', () => { const client = new AWS.SecretsManager(); const secret = Secret.fromArn(arn, client); - await expect(secret.getValue()).resolves.toEqual(Buffer.from(value.buffer)); + await expect(secret.getValue()).resolves.toEqual(Buffer.from(value)); expect(fakeGetSecretValue.callCount).toEqual(1); }); diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/pad-efs-storage/handlers.ts b/packages/aws-rfdk/lib/lambdas/nodejs/pad-efs-storage/handlers.ts index d947b6f91..06f243715 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/pad-efs-storage/handlers.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/pad-efs-storage/handlers.ts @@ -103,7 +103,7 @@ export async function shrinkFilesystem(numFilesToRemove: number, mountPoint: str await fsp.unlink(filename); numFilesDeleted += 1; } catch (err) { - console.error(`Unable to delete: ${filename} -- Error: ${err.message}`); + console.error(`Unable to delete: ${filename} -- Error: ${(err as Error)?.message}`); } } } catch (err) { diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/unhealthyFleetAction/index.ts b/packages/aws-rfdk/lib/lambdas/nodejs/unhealthyFleetAction/index.ts index eb556fa80..cfebae6f7 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/unhealthyFleetAction/index.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/unhealthyFleetAction/index.ts @@ -5,6 +5,7 @@ /* eslint-disable no-console */ +import { isNativeError } from 'util/types'; // eslint-disable-next-line import/no-extraneous-dependencies import {AutoScaling} from 'aws-sdk'; @@ -79,7 +80,7 @@ export async function handler(event: AWSLambda.SNSEvent, context: AWSLambda.Cont console.error(`ERROR: Exception while processing the event: ${e}`); return { status: 'ERROR', - reason: e.message, + reason: isNativeError(e) ? e.message : String(e), }; } diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/wait-for-stable-service/handler.ts b/packages/aws-rfdk/lib/lambdas/nodejs/wait-for-stable-service/handler.ts index 7ca68b801..27d16cb67 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/wait-for-stable-service/handler.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/wait-for-stable-service/handler.ts @@ -6,7 +6,7 @@ /* eslint-disable no-console */ // eslint-disable-next-line import/no-extraneous-dependencies -import { ECS } from 'aws-sdk'; +import { ECS, AWSError } from 'aws-sdk'; import { LambdaContext } from '../lib/aws-lambda'; import { CfnRequestEvent, @@ -61,7 +61,7 @@ export class WaitForStableServiceResource extends SimpleCustomResource { await this.ecsClient.waitFor('servicesStable', options).promise(); console.log('Finished waiting. ECS services are stable.'); } catch (e) { - throw new Error(`ECS services failed to stabilize in expected time: ${e.code} -- ${e.message}`); + throw new Error(`ECS services failed to stabilize in expected time: ${(e as AWSError)?.code} -- ${(e as AWSError)?.message}`); } return undefined; diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/acm-handlers.ts b/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/acm-handlers.ts index c307fd427..fa0459bcf 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/acm-handlers.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/acm-handlers.ts @@ -7,7 +7,7 @@ import * as crypto from 'crypto'; // eslint-disable-next-line import/no-extraneous-dependencies -import { ACM, DynamoDB, SecretsManager } from 'aws-sdk'; +import { ACM, DynamoDB, SecretsManager, AWSError } from 'aws-sdk'; import { LambdaContext } from '../lib/aws-lambda'; import { BackoffGenerator } from '../lib/backoff-generator'; @@ -115,7 +115,7 @@ export class AcmCertificateImporter extends DynamoBackedCustomResource { // AccessDeniedException can happen if either: // a) We do not have the required permission to delete the Certificate (unlikely) // b) The Certificate has already been deleted (more likely) - if (e.message.indexOf('AccessDeniedException')) { + if ((e as AWSError)?.message.indexOf('AccessDeniedException')) { console.warn(`Could not delete Certificate ${arn}. Please ensure it has been deleted.`); } throw e; // Rethrow so the custom resource handler will error-out. diff --git a/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/handlers.ts b/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/handlers.ts index 37be935aa..6ce7c3a9f 100644 --- a/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/handlers.ts +++ b/packages/aws-rfdk/lib/lambdas/nodejs/x509-certificate/handlers.ts @@ -8,7 +8,7 @@ // eslint-disable-next-line import/no-extraneous-dependencies import { randomBytes } from 'crypto'; // eslint-disable-next-line import/no-extraneous-dependencies -import { DynamoDB, SecretsManager } from 'aws-sdk'; +import { DynamoDB, SecretsManager, AWSError } from 'aws-sdk'; import { LambdaContext } from '../lib/aws-lambda'; @@ -64,7 +64,7 @@ abstract class X509Common extends DynamoBackedCustomResource { // AccessDeniedException can happen if either: // a) We legit do not have the required permission to delete the secret (very unlikely) // b) The Secret has already been deleted (much more likely; so we continue) - if (e.message.indexOf('AccessDeniedException')) { + if ((e as AWSError)?.message.indexOf('AccessDeniedException')) { console.warn(`Could not delete Secret ${arn}. Please ensure it has been deleted.`); } throw e; // Rethrow so the custom resource handler will error-out. diff --git a/packages/aws-rfdk/package.json b/packages/aws-rfdk/package.json index 805284deb..5eb97fe00 100644 --- a/packages/aws-rfdk/package.json +++ b/packages/aws-rfdk/package.json @@ -83,7 +83,7 @@ "eslint-plugin-jest": "^27.2.1", "eslint-plugin-license-header": "^0.6.0", "jest": "^29.6.2", - "jsii": "^1.77.0", + "jsii": "~5.1.9", "jsii-pacmak": "1.86.0", "jsii-reflect": "1.86.0", "pkglint": "1.2.0", @@ -100,7 +100,7 @@ "constructs": "^10.0.0" }, "engines": { - "node": ">= 14.15.0" + "node": ">= 18.0.0" }, "stability": "stable", "maturity": "stable" diff --git a/scripts/rfdk_build_environment.sh b/scripts/rfdk_build_environment.sh index 5c8115546..1ac399e9a 100755 --- a/scripts/rfdk_build_environment.sh +++ b/scripts/rfdk_build_environment.sh @@ -42,5 +42,5 @@ docker run --rm \ ${USER_OPT} \ --net=host -it \ --env DOTNET_CLI_TELEMETRY_OPTOUT=1 \ - jsii/superchain:1-buster-slim-node14 + jsii/superchain:1-buster-slim-node18 diff --git a/tools/pkglint/lib/rules.ts b/tools/pkglint/lib/rules.ts index c07371792..112365ca7 100644 --- a/tools/pkglint/lib/rules.ts +++ b/tools/pkglint/lib/rules.ts @@ -295,11 +295,11 @@ export class NodeCompatibility extends ValidationRule { public validate(pkg: PackageJson): void { const atTypesNode = pkg.getDevDependency('@types/node'); - if (atTypesNode && !atTypesNode.startsWith('^14.')) { + if (atTypesNode && !atTypesNode.startsWith('^18.')) { pkg.report({ ruleName: this.name, - message: `packages must support node version 14 and up, but ${atTypesNode} is declared`, - fix: () => pkg.addDevDependency('@types/node', '^14.14.31'), + message: `packages must support node version 18 and up, but ${atTypesNode} is declared`, + fix: () => pkg.addDevDependency('@types/node', '^18.0.0'), }); } } @@ -428,7 +428,7 @@ export class MustHaveNodeEnginesDeclaration extends ValidationRule { public readonly name = 'package-info/engines'; public validate(pkg: PackageJson): void { - expectJSON(this.name, pkg, 'engines.node', '>= 14.15.0'); + expectJSON(this.name, pkg, 'engines.node', '>= 18.0.0'); } } diff --git a/yarn.lock b/yarn.lock index e3d3e79cd..80b25a85c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1461,6 +1461,14 @@ chalk "^4.1.2" semver "^7.3.8" +"@jsii/check-node@1.85.0": + version "1.85.0" + resolved "https://registry.yarnpkg.com/@jsii/check-node/-/check-node-1.85.0.tgz#548d03f3f98d8b0edd9f4aeac7e128940dfd290d" + integrity sha512-dOrye7NuafkHADt3jk0TxMu/2sOHXxOYTwAuKj9L1/Te1xFfw2fzni80J12rTBQeVQxLVFNgDynsl2J7cuFFtQ== + dependencies: + chalk "^4.1.2" + semver "^7.5.1" + "@jsii/check-node@1.86.0": version "1.86.0" resolved "https://registry.yarnpkg.com/@jsii/check-node/-/check-node-1.86.0.tgz#3f13844558504f194e88a2a08472b55844dcd8f1" @@ -1484,7 +1492,7 @@ dependencies: ajv "^8.12.0" -"@jsii/spec@1.86.1", "@jsii/spec@^1.86.0", "@jsii/spec@^1.86.1": +"@jsii/spec@1.86.1", "@jsii/spec@^1.85.0", "@jsii/spec@^1.86.0", "@jsii/spec@^1.86.1": version "1.86.1" resolved "https://registry.yarnpkg.com/@jsii/spec/-/spec-1.86.1.tgz#0f8911f5d5cfb2606628f143ac7d195b7870c890" integrity sha512-wD0Y0pVg/1jjbZImk2FIuj+YdpwLFEsKCpoC3XKLJyNyUZPSoJzrt3phLV8HRLmH0m52kw6rh044OIowedcc9A== @@ -4117,6 +4125,15 @@ dotgitignore@^2.1.0: find-up "^3.0.0" minimatch "^3.0.4" +downlevel-dts@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/downlevel-dts/-/downlevel-dts-0.11.0.tgz#514a2d723009c5845730c1db6c994484c596ed9c" + integrity sha512-vo835pntK7kzYStk7xUHDifiYJvXxVhUapt85uk2AI94gUUAQX9HNRtrcMHNSc3YHJUEHGbYIGsM99uIbgAtxw== + dependencies: + semver "^7.3.2" + shelljs "^0.8.3" + typescript next + duplexer@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -5182,6 +5199,18 @@ glob@^10.2.2: minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-scurry "^1.10.1" +glob@^7.0.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + 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" + glob@^7.1.3, glob@^7.1.4: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" @@ -5599,6 +5628,11 @@ internal-slot@^1.0.5: has "^1.0.3" side-channel "^1.0.4" +interpret@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== + ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" @@ -6483,7 +6517,7 @@ jsii-rosetta@^1.86.0: workerpool "^6.4.0" yargs "^16.2.0" -jsii@1.86.1, jsii@^1.77.0: +jsii@1.86.1: version "1.86.1" resolved "https://registry.yarnpkg.com/jsii/-/jsii-1.86.1.tgz#ba5f7d2d948b02c4efa2543260e1eb9e108bf436" integrity sha512-gAi/mGRdIpCYY7Na61VPE717Z6+/1HTYqgxjMC+VdLXxITbWpaQqO+DqsOnhtsIh+JyjIQM7VOSZ+5Ymf1A74A== @@ -6502,6 +6536,25 @@ jsii@1.86.1, jsii@^1.77.0: typescript "~3.9.10" yargs "^16.2.0" +jsii@~5.1.9: + version "5.1.10" + resolved "https://registry.yarnpkg.com/jsii/-/jsii-5.1.10.tgz#e9973ea816362cb0791775a6ef1f43ebc5ed5702" + integrity sha512-OvFBUj0V7H+ex7yGyg8bJwghiHnE/T8DmQBxJxUG6qApwKP9lJE+jSz0ONKuqdaxTK1RaLbZhatLkCRrkQrbJQ== + dependencies: + "@jsii/check-node" "1.85.0" + "@jsii/spec" "^1.85.0" + case "^1.6.3" + chalk "^4" + downlevel-dts "^0.11.0" + fast-deep-equal "^3.1.3" + log4js "^6.9.1" + semver "^7.5.4" + semver-intersect "^1.4.0" + sort-json "^2.0.1" + spdx-license-list "^6.6.0" + typescript "~5.1.6" + yargs "^17.7.2" + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -7103,7 +7156,7 @@ minimatch@3.0.5: dependencies: brace-expansion "^1.1.7" -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -8224,6 +8277,13 @@ readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== + dependencies: + resolve "^1.1.6" + redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -8292,6 +8352,15 @@ resolve.exports@^2.0.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== +resolve@^1.1.6: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.1: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" @@ -8439,7 +8508,7 @@ semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.4: +semver@^7.3.2, semver@^7.5.1, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -8470,6 +8539,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shelljs@^0.8.3: + version "0.8.5" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" + integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -9241,6 +9319,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@next: + version "5.2.0-dev.20230803" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.0-dev.20230803.tgz#295441ec60d4b260fa779e08088ab3974f0ff02e" + integrity sha512-DwCyutWHyT7Il7xpJCxtx4/S5F4qjAo2SE6QDRSLhEUtBFGwGHTHCvuyfm9KNrdwn67jGitdlw4gpbSTVVjoww== + typescript@~3.9.10: version "3.9.10" resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8"