├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Infra ├── README.md ├── bin │ └── app.ts ├── cdk.context.json ├── cdk.json ├── deployStack.sh ├── lib │ ├── AppStacks.ts │ ├── constructs │ │ └── MeetingProvider.ts │ ├── custom-resources │ │ └── upload-website-config │ │ │ └── app.py │ ├── graphql │ │ └── schema.graphql │ ├── stack │ │ ├── ApiStack.ts │ │ ├── AppSyncStack.ts │ │ ├── CognitoAuthStack.ts │ │ ├── StaticWebsiteStack.ts │ │ └── UserPoolStack.ts │ └── utils │ │ └── lambda.ts ├── package.json ├── tsconfig.json └── yarn.lock ├── LICENSE.txt ├── Lambdas ├── ChimeCallService │ ├── .babelrc │ ├── .eslintrc.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ ├── webpack.config.js │ └── yarn.lock ├── Common │ ├── .eslintrc.js │ ├── .gitignore │ ├── .npmignore │ ├── .prittierrc.js │ ├── README.md │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── yarn.lock └── README.md ├── NOTICE.txt ├── README.md ├── Website ├── .gitignore ├── README.md ├── config-overrides.js ├── package.json ├── public │ ├── index.html │ └── robots.txt ├── src │ ├── api │ │ ├── ChimeCallServiceClient.ts │ │ └── api.ts │ ├── components │ │ └── Controls │ │ │ └── ModalChimeDialog.tsx │ ├── containers │ │ ├── App │ │ │ └── index.tsx │ │ └── Home │ │ │ └── HomeContainer.tsx │ ├── index.css │ ├── index.tsx │ ├── react-app-env.d.ts │ └── serviceWorker.ts ├── tsconfig.json └── yarn.lock ├── appsync-sequence-diagram.png ├── architecture.png ├── screenshot-a.png └── screenshot-b.png /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | cdk.out 4 | .DS_Store 5 | *.iml 6 | *.idea 7 | .eslintcache 8 | 9 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *master* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | 61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. 62 | -------------------------------------------------------------------------------- /Infra/README.md: -------------------------------------------------------------------------------- 1 | # Cross Talk Infrastructure 2 | 3 | This package defines the infrastructure for the Cross Talk video chat sample using the Cloud Development Kit (CDK). 4 | 5 | ## Development 6 | 7 | ### Prerequisites 8 | 9 | - The [aws-cli](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) must be installed *and* configured with an AWS account on the deployment machine (see https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html for instructions on how to do this on your preferred development platform). 10 | - This project requires Node.js ≥ 10.17.0 and NPM. 11 | [Node](http://nodejs.org/) and [NPM](https://npmjs.org/) are really easy to install. 12 | To make sure you have them available on your machine, try running the following command. 13 | ```sh 14 | npm -v && node -v 15 | ``` 16 | - Install or update the [AWS CDK CLI] from npm. 17 | ```sh 18 | npm i -g aws-cdk 19 | ``` 20 | 21 | ### Install 22 | 23 | #### 1/ Bootstrapping your AWS account 24 | 25 | You only need to do this one time per environment where you want to deploy CDK applications. 26 | If you’re unsure whether your environment has been bootstrapped already, you can always run 27 | the command again. 28 | 29 | Make sure you have credentials for **ACCOUNT** (replace with your AWS account ID) in a profile 30 | named **account-profile**. For more information, see [Named profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html). 31 | 32 | Run the following commands in the root of the repository directory: 33 | 34 | ```sh 35 | cd Lambdas/Common 36 | yarn 37 | yarn build 38 | 39 | cd ../ChimeCallService 40 | yarn 41 | yarn build 42 | 43 | cd ../../Website 44 | yarn 45 | yarn build 46 | 47 | cd ../Infra 48 | yarn 49 | yarn build 50 | cdk bootstrap \ 51 | --profile account-profile \ 52 | --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ 53 | aws://ACCOUNT1/ap-southeast-2 54 | ``` 55 | 56 | #### 2/ Deploying 57 | 58 | A convenience script is provided to deploy all infrastructure to your environment. This builds 59 | all the lambdas, the website, the infrastructure and then initiates the CDK deployment. 60 | 61 | ``` 62 | ./deployStack.sh --profile 63 | ``` 64 | -------------------------------------------------------------------------------- /Infra/bin/app.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | // SPDX-License-Identifier: MIT-0 5 | 6 | import "source-map-support/register"; 7 | import * as cdk from "aws-cdk-lib"; 8 | import { AppStacks } from "../lib/AppStacks"; 9 | 10 | const app = new cdk.App(); 11 | new AppStacks(app, "CrossTalkStacks"); 12 | app.synth(); 13 | -------------------------------------------------------------------------------- /Infra/cdk.context.json: -------------------------------------------------------------------------------- 1 | { 2 | "application": "CrossTalk" 3 | } 4 | -------------------------------------------------------------------------------- /Infra/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "npx ts-node bin/app.ts" 3 | } 4 | -------------------------------------------------------------------------------- /Infra/deployStack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | # SPDX-License-Identifier: MIT-0 5 | 6 | set -e; 7 | 8 | CDK_PROFILE=default 9 | 10 | while [[ "$#" -gt 0 ]]; do case $1 in 11 | --profile) CDK_PROFILE="$2"; shift;; 12 | esac; shift; done 13 | 14 | echo "Using AWS profile '$CDK_PROFILE'" 15 | 16 | # Build all the lambdas 17 | cd ../Lambdas/Common && yarn && yarn build 18 | cd ../ChimeCallService && yarn && yarn build 19 | cd .. 20 | 21 | # Build the website 22 | cd ../Website && yarn && yarn build 23 | 24 | # Build the infrastructure cdk code 25 | cd ../Infra && yarn && yarn build 26 | 27 | # Synth and deploy the sandbox stack 28 | cdk --profile $CDK_PROFILE synth && cdk --profile $CDK_PROFILE deploy --all --require-approval never 29 | -------------------------------------------------------------------------------- /Infra/lib/AppStacks.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Construct } from "constructs"; 5 | import { CognitoAuthStack } from "./stack/CognitoAuthStack"; 6 | import { StaticWebsiteStack } from "./stack/StaticWebsiteStack"; 7 | import { ApiStack } from "./stack/ApiStack"; 8 | import { AppSyncStack } from "./stack/AppSyncStack"; 9 | import { UserPoolStack } from "./stack/UserPoolStack"; 10 | 11 | export class AppStacks extends Construct { 12 | constructor(scope: Construct, id: string) { 13 | super(scope, id); 14 | 15 | // see comment in source for this stack to understand why we inject this 16 | // into the cognito stack instead of doing it sanely... 17 | const userPoolStack = new UserPoolStack(this, 'UserPoolStack'); 18 | 19 | const appsyncStack = new AppSyncStack(this, 'AppSyncStack', { 20 | userPool: userPoolStack.userPool 21 | }); 22 | 23 | const apiStack = new ApiStack(this, 'ApiStack', { 24 | graphqlEndpoint: appsyncStack.graphqlApi.graphqlUrl 25 | }); 26 | 27 | const authStack = new CognitoAuthStack(this, 'CognitoAuthStack', { 28 | meetingProviderApi: apiStack.meetingApi, 29 | userPool: userPoolStack.userPool, 30 | graphqlApiArn: appsyncStack.graphqlApi.arn 31 | }); 32 | 33 | new StaticWebsiteStack(this, 'StaticWebsiteStack', { 34 | identityPoolId: authStack.identityPoolId, 35 | userPoolClientId: authStack.userPoolClientId, 36 | userPoolId: userPoolStack.userPool.userPoolId, 37 | graphqlEndpoint: appsyncStack.graphqlApi.graphqlUrl, 38 | apiUrl: apiStack.meetingApi.api.url 39 | }); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Infra/lib/constructs/MeetingProvider.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Construct } from "constructs"; 5 | import { Duration, Stack } from "aws-cdk-lib"; 6 | import * as apigateway from "aws-cdk-lib/aws-apigateway"; 7 | import * as iam from "aws-cdk-lib/aws-iam"; 8 | import * as lambda from "aws-cdk-lib/aws-lambda"; 9 | import { getLambdaPath } from "../utils/lambda"; 10 | 11 | export interface MeetingProviderProps { 12 | lambdaAssetDirectory: string; 13 | environment: { [key: string]: string }; 14 | policyStatements: iam.PolicyStatement[]; 15 | } 16 | 17 | export interface MeetingProviderApi { 18 | api: apigateway.RestApi; 19 | queryPath: string; 20 | } 21 | 22 | export default class MeetingProvider extends Construct { 23 | public readonly api: MeetingProviderApi; 24 | 25 | constructor(scope: Stack, id: string, props: MeetingProviderProps) { 26 | super(scope, id); 27 | 28 | const apiDefaults = { 29 | restApiName: `${id}Api`, 30 | description: `${id}Api`, 31 | defaultCorsPreflightOptions: { 32 | allowOrigins: apigateway.Cors.ALL_ORIGINS, 33 | allowMethods: apigateway.Cors.ALL_METHODS, 34 | }, 35 | policy: new iam.PolicyDocument({ 36 | statements: [ 37 | // Allow only callers with credentials from the AWS account 38 | // for this stage 39 | new iam.PolicyStatement({ 40 | effect: iam.Effect.ALLOW, 41 | principals: [new iam.AccountPrincipal(scope.account)], 42 | actions: ["execute-api:Invoke"], 43 | resources: ["execute-api:/*"], 44 | }), 45 | // Open up OPTIONS to allow browsers to make unauthenticated 46 | // preflight requests 47 | new iam.PolicyStatement({ 48 | effect: iam.Effect.ALLOW, 49 | principals: [new iam.AnyPrincipal()], 50 | actions: ["execute-api:Invoke"], 51 | resources: ["execute-api:/*/OPTIONS/*"], 52 | }), 53 | ], 54 | }), 55 | }; 56 | 57 | const api = new apigateway.RestApi(this, `${id}Api`, apiDefaults); 58 | 59 | const lambdaFn = new lambda.Function(scope, `${id}-Handler`, { 60 | runtime: lambda.Runtime.NODEJS_18_X, 61 | code: lambda.Code.fromAsset(getLambdaPath(props.lambdaAssetDirectory)), 62 | handler: `index.chimeCallHandler`, 63 | timeout: Duration.seconds(30), 64 | environment: props.environment, 65 | initialPolicy: props.policyStatements, 66 | }); 67 | 68 | const apiPath = "call-create"; 69 | const apiResource = api.root.addResource(apiPath); 70 | 71 | const lambdaIntegration = new apigateway.LambdaIntegration(lambdaFn); 72 | 73 | apiResource.addMethod("GET", lambdaIntegration, { 74 | authorizationType: apigateway.AuthorizationType.IAM, 75 | }); 76 | 77 | this.api = { 78 | api, 79 | queryPath: `/${apiPath}`, 80 | }; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Infra/lib/custom-resources/upload-website-config/app.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | SPDX-License-Identifier: MIT-0 4 | """ 5 | 6 | import logging 7 | import boto3 8 | import json 9 | from uuid import uuid4 10 | 11 | logger = logging.getLogger(__name__) 12 | logger.setLevel(logging.INFO) 13 | 14 | s3_client = boto3.client('s3') 15 | cloudfront_client = boto3.client('cloudfront') 16 | 17 | 18 | def on_event(event, context): 19 | logger.info(f'New event {json.dumps(event, indent=2)}') 20 | 21 | request_type = event['RequestType'] 22 | if request_type == 'Create' or request_type == 'Update': 23 | s3_bucket = event['ResourceProperties']['S3_BUCKET'] 24 | s3_key = event['ResourceProperties']['S3_CONFIG_FILE_KEY'] 25 | website_config = event['ResourceProperties']['WEBSITE_CONFIG'] 26 | distribution_id = event['ResourceProperties']['CLOUDFRONT_DISTRIBUTION_ID'] 27 | update_website_config(s3_bucket, s3_key, website_config, distribution_id) 28 | elif request_type == 'Delete': 29 | logger.info("Website config deletion") 30 | pass 31 | else: 32 | raise Exception("Invalid request type: %s" % request_type) 33 | 34 | 35 | def update_website_config(s3_bucket, s3_key, website_config, distribution_id): 36 | logger.info(f"Updating config file {s3_key}") 37 | s3_client.put_object(Body=website_config, Bucket=s3_bucket, Key=s3_key) 38 | 39 | logger.info(f"Invalidating Cloudfront distribution {distribution_id}") 40 | cloudfront_client.create_invalidation( 41 | DistributionId=distribution_id, 42 | InvalidationBatch={ 43 | 'Paths': { 44 | 'Quantity': 1, 45 | 'Items': [f'/{s3_key}'] 46 | }, 47 | 'CallerReference': str(uuid4()), 48 | }) 49 | 50 | logger.info(f"Website config updated succesfully") 51 | -------------------------------------------------------------------------------- /Infra/lib/graphql/schema.graphql: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | SPDX-License-Identifier: MIT-0 4 | """ 5 | 6 | type chimeSession @aws_cognito_user_pools @aws_iam { 7 | meeting: String 8 | attendee: String 9 | username: String 10 | } 11 | 12 | type Mutation { 13 | startChimeSession(meeting: String!, attendee: String!, username: String!): chimeSession 14 | @aws_iam 15 | claimChimeSession(meeting: String!): String 16 | @aws_iam 17 | } 18 | 19 | type Query { 20 | stub: String 21 | @deprecated(reason: "this is a None datasource and used only for subscriptions so this is a no-op") 22 | @aws_iam 23 | } 24 | 25 | type Subscription { 26 | chimeSessionStarted: chimeSession 27 | @aws_subscribe(mutations: ["startChimeSession"]) 28 | chimeSessionClaimed: String 29 | @aws_subscribe(mutations: ["claimChimeSession"]) 30 | } 31 | 32 | schema { 33 | query: Query 34 | mutation: Mutation 35 | subscription: Subscription 36 | } -------------------------------------------------------------------------------- /Infra/lib/stack/ApiStack.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Construct } from "constructs"; 5 | import { Stack } from "aws-cdk-lib"; 6 | import * as iam from "aws-cdk-lib/aws-iam"; 7 | import MeetingProvider, { MeetingProviderApi } from "../constructs/MeetingProvider"; 8 | 9 | export interface ApiStackProps { 10 | graphqlEndpoint: string; 11 | } 12 | 13 | /** 14 | * API for handling requests from the UI and routing to the appropriate channel 15 | */ 16 | export class ApiStack extends Stack { 17 | public readonly meetingApi: MeetingProviderApi; 18 | 19 | constructor(scope: Construct, id: string, props: ApiStackProps) { 20 | super(scope, id); 21 | 22 | const meetingProvider = new MeetingProvider(this, "MeetingProvider", { 23 | lambdaAssetDirectory: "ChimeCallService", 24 | environment: { GRAPHQL_ENDPOINT: props.graphqlEndpoint }, 25 | policyStatements: [ 26 | new iam.PolicyStatement({ 27 | effect: iam.Effect.ALLOW, 28 | actions: ["execute-api:Invoke", "chime:CreateMeeting", "chime:CreateAttendee"], 29 | resources: ["*"], 30 | }), 31 | ], 32 | }); 33 | 34 | this.meetingApi = meetingProvider.api; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Infra/lib/stack/AppSyncStack.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Construct } from "constructs"; 5 | import * as cdk from "aws-cdk-lib"; 6 | import * as cognito from "aws-cdk-lib/aws-cognito"; 7 | import * as appsync from "aws-cdk-lib/aws-appsync"; 8 | import * as path from "path"; 9 | 10 | export interface AppsyncStackProps extends cdk.StackProps { 11 | readonly userPool: cognito.UserPool; 12 | } 13 | 14 | interface ChimeSession { 15 | meeting: string; 16 | attendee: string; 17 | username: string; 18 | } 19 | 20 | export class AppSyncStack extends cdk.Stack { 21 | public readonly graphqlApi: appsync.GraphqlApi; 22 | 23 | constructor(scope: Construct, id: string, props: AppsyncStackProps) { 24 | super(scope, id, props); 25 | 26 | // Creates the AppSync API 27 | const api = new appsync.GraphqlApi(this, "ChimeSessionEventsApi", { 28 | name: "chime-session-api", 29 | schema: appsync.SchemaFile.fromAsset( 30 | path.join(__dirname, "../graphql/schema.graphql") 31 | ), 32 | authorizationConfig: { 33 | defaultAuthorization: { 34 | authorizationType: appsync.AuthorizationType.USER_POOL, 35 | userPoolConfig: { 36 | userPool: props.userPool, 37 | defaultAction: appsync.UserPoolDefaultAction.ALLOW, 38 | }, 39 | }, 40 | }, 41 | xrayEnabled: true, 42 | }); 43 | 44 | const noneDataSource = api.addNoneDataSource("NoneDataSource"); 45 | 46 | const meetingRequestTemplate = appsync.MappingTemplate.fromString( 47 | '{"version": "2018-05-29", "payload": { "meeting": "${ctx.args.meeting}", "attendee": "${ctx.args.attendee}", "username": "${ctx.args.username}" } }' 48 | ); 49 | 50 | const meetingResponseTemplate = appsync.MappingTemplate.fromString( 51 | "$util.toJson($context.result)" 52 | ); 53 | 54 | const claimChimeSessionRequestTemplate = appsync.MappingTemplate.fromString( 55 | '{"version": "2018-05-29", "payload": "${ctx.args.meeting}"}' 56 | ); 57 | 58 | noneDataSource.createResolver("id_stub", { 59 | typeName: "Query", 60 | fieldName: "stub", 61 | requestMappingTemplate: meetingRequestTemplate, 62 | responseMappingTemplate: meetingResponseTemplate, 63 | }); 64 | 65 | noneDataSource.createResolver("id_startChimeSession", { 66 | typeName: "Mutation", 67 | fieldName: "startChimeSession", 68 | requestMappingTemplate: meetingRequestTemplate, 69 | responseMappingTemplate: meetingResponseTemplate, 70 | }); 71 | 72 | noneDataSource.createResolver("id_claimChimeSession", { 73 | typeName: "Mutation", 74 | fieldName: "claimChimeSession", 75 | requestMappingTemplate: claimChimeSessionRequestTemplate, 76 | responseMappingTemplate: meetingResponseTemplate, 77 | }); 78 | 79 | noneDataSource.createResolver("id_chimeSessionStarted", { 80 | typeName: "Subscription", 81 | fieldName: "chimeSessionStarted", 82 | requestMappingTemplate: meetingRequestTemplate, 83 | responseMappingTemplate: meetingResponseTemplate, 84 | }); 85 | 86 | noneDataSource.createResolver("id_chimeSessionClaimed", { 87 | typeName: "Subscription", 88 | fieldName: "chimeSessionClaimed", 89 | requestMappingTemplate: claimChimeSessionRequestTemplate, 90 | responseMappingTemplate: meetingResponseTemplate, 91 | }); 92 | 93 | this.graphqlApi = api; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Infra/lib/stack/CognitoAuthStack.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Construct } from "constructs"; 5 | import { Stack } from "aws-cdk-lib"; 6 | import { MeetingProviderApi } from "../constructs/MeetingProvider"; 7 | import * as cognito from "aws-cdk-lib/aws-cognito"; 8 | import * as iam from "aws-cdk-lib/aws-iam"; 9 | 10 | export interface CognitoAuthStackProps { 11 | meetingProviderApi: MeetingProviderApi; 12 | graphqlApiArn: string; 13 | userPool: cognito.UserPool; 14 | } 15 | 16 | /** 17 | * Defines infrastructure for authentication, including assigning permissions to authenticated and unauthenticated user 18 | * roles. 19 | */ 20 | export class CognitoAuthStack extends Stack { 21 | public readonly userPoolClientId: string; 22 | public readonly identityPoolId: string; 23 | 24 | constructor(scope: Construct, id: string, props: CognitoAuthStackProps) { 25 | super(scope, id); 26 | 27 | /* 28 | * Cognito user pool 29 | */ 30 | 31 | const userPoolWebClient = props.userPool.addClient('UserPoolWebClient', { 32 | authFlows: { 33 | userPassword: true, 34 | userSrp: true, 35 | }, 36 | generateSecret: false, 37 | }); 38 | this.userPoolClientId = userPoolWebClient.userPoolClientId; 39 | 40 | /* 41 | * Cognito identity pool 42 | */ 43 | const identityPool = new cognito.CfnIdentityPool(this, "identityPool", { 44 | allowUnauthenticatedIdentities: true, 45 | cognitoIdentityProviders: [ 46 | { 47 | clientId: userPoolWebClient.userPoolClientId, 48 | providerName: props.userPool.userPoolProviderName, 49 | }, 50 | ], 51 | }); 52 | 53 | this.identityPoolId = identityPool.ref; 54 | 55 | const authenticatedRole = new iam.Role( 56 | this, 57 | "CognitoDefaultAuthenticatedRole", 58 | { 59 | assumedBy: new iam.FederatedPrincipal( 60 | "cognito-identity.amazonaws.com", 61 | { 62 | StringEquals: { 63 | "cognito-identity.amazonaws.com:aud": identityPool.ref 64 | }, 65 | "ForAnyValue:StringLike": { 66 | "cognito-identity.amazonaws.com:amr": "authenticated" 67 | } 68 | }, 69 | "sts:AssumeRoleWithWebIdentity" 70 | ) 71 | } 72 | ); 73 | 74 | // Add any policies that apply to both authenticated and unauthenticated users 75 | [authenticatedRole].forEach((role) => { 76 | role.addToPolicy(new iam.PolicyStatement({ 77 | effect: iam.Effect.ALLOW, 78 | actions: [ 79 | "cognito-sync:*", 80 | "cognito-identity:*", 81 | ], 82 | resources: ["*"] 83 | })); 84 | 85 | role.addToPolicy( 86 | new iam.PolicyStatement({ 87 | effect: iam.Effect.ALLOW, 88 | actions: ['appsync:GraphQL'], 89 | resources: [`${props.graphqlApiArn}/*`] 90 | }) 91 | ); 92 | 93 | role.addToPolicy(new iam.PolicyStatement({ 94 | effect: iam.Effect.ALLOW, 95 | actions: [ 96 | 'execute-api:Invoke', 97 | ], 98 | resources: [props.meetingProviderApi.api.arnForExecuteApi("*", props.meetingProviderApi.queryPath, "*")] 99 | })); 100 | }); 101 | 102 | new cognito.CfnIdentityPoolRoleAttachment( 103 | this, 104 | "DefaultValid", 105 | { 106 | identityPoolId: identityPool.ref, 107 | roles: { 108 | authenticated: authenticatedRole.roleArn 109 | }, 110 | } 111 | ); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Infra/lib/stack/StaticWebsiteStack.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Construct } from "constructs"; 5 | import * as cdk from "aws-cdk-lib"; 6 | import * as s3 from "aws-cdk-lib/aws-s3"; 7 | import * as s3Deployment from "aws-cdk-lib/aws-s3-deployment"; 8 | import * as cloudfront from "aws-cdk-lib/aws-cloudfront"; 9 | import * as lambda from "aws-cdk-lib/aws-lambda"; 10 | import * as iam from "aws-cdk-lib/aws-iam"; 11 | import * as cr from "aws-cdk-lib/custom-resources"; 12 | import * as path from "path"; 13 | 14 | export interface StaticWebsiteStackProps { 15 | userPoolId: string; 16 | userPoolClientId: string; 17 | identityPoolId: string; 18 | graphqlEndpoint: string; 19 | apiUrl: string; 20 | } 21 | 22 | /** 23 | * Defines the infrastructure for the user interface 24 | */ 25 | export class StaticWebsiteStack extends cdk.Stack { 26 | // This file will be used to provide configuration for the static website, eg identity pool id or api urls 27 | public readonly s3ConfigFileKey: string = 'runtime-config.js'; 28 | 29 | constructor(scope: Construct, id: string, props: StaticWebsiteStackProps) { 30 | super(scope, id); 31 | 32 | // S3 Website 33 | 34 | const websiteBucket = new s3.Bucket(this, 'WebsiteBucket', { 35 | websiteIndexDocument: 'index.html', 36 | blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, 37 | }); 38 | 39 | // Cloudfront distribution 40 | 41 | const cloudFrontOia = new cloudfront.OriginAccessIdentity(this, 'CloudfrontOia'); 42 | 43 | websiteBucket.grantRead(cloudFrontOia); 44 | 45 | const cloudFrontDistribution = new cloudfront.CloudFrontWebDistribution(this, 'CloudfrontDistribution', { 46 | originConfigs: [ 47 | { 48 | s3OriginSource: { 49 | s3BucketSource: websiteBucket, 50 | originAccessIdentity: cloudFrontOia, 51 | }, 52 | behaviors: [{ isDefaultBehavior: true }], 53 | } 54 | ], 55 | // We need to redirect "key not found errors" to index.html since our app is a Single Page App 56 | errorConfigurations: [{ 57 | errorCode: 404, 58 | responseCode: 200, 59 | responsePagePath: '/index.html', 60 | }], 61 | }); 62 | 63 | const websiteDeployment = new s3Deployment.BucketDeployment(this, 'WebsiteDeployment', { 64 | sources: [s3Deployment.Source.asset('../Website/build')], 65 | destinationBucket: websiteBucket, 66 | // Files in the distribution's edge caches will be invalidated after files are uploaded to the destination bucket. 67 | distribution: cloudFrontDistribution, 68 | serverSideEncryption: s3Deployment.ServerSideEncryption.AES_256, 69 | }); 70 | 71 | const uploadWebsiteConfigFunction = new lambda.Function(this, 'UploadWebsiteConfigFunction', { 72 | runtime: lambda.Runtime.PYTHON_3_10, 73 | handler: 'app.on_event', 74 | code: lambda.Code.fromAsset(path.join(__dirname, '../custom-resources/upload-website-config')), 75 | timeout: cdk.Duration.seconds(30), 76 | initialPolicy: [ 77 | new iam.PolicyStatement({ 78 | effect: iam.Effect.ALLOW, 79 | actions: ['cloudfront:GetInvalidation', 'cloudfront:CreateInvalidation'], 80 | resources: ['*'], 81 | }), 82 | ], 83 | }); 84 | 85 | websiteBucket.grantWrite(uploadWebsiteConfigFunction); 86 | 87 | const uploadWebsiteConfigProvider = new cr.Provider(this, 'UploadWebsiteConfigProvider', { 88 | onEventHandler: uploadWebsiteConfigFunction, 89 | }); 90 | 91 | const websiteConfiguration = `window['runConfig'] = { 92 | region: "${this.region}", 93 | userPoolId: "${props.userPoolId}", 94 | userPoolWebClientId: "${props.userPoolClientId}", 95 | identityPoolId: "${props.identityPoolId}", 96 | graphqlEndpoint: "${props.graphqlEndpoint}", 97 | apiUrl: "${props.apiUrl}" 98 | }`; 99 | 100 | const uploadWebsiteConfigResource = new cdk.CustomResource(this, 'UploadWebsiteConfigResource', { 101 | serviceToken: uploadWebsiteConfigProvider.serviceToken, 102 | // Pass the mapping file attributes as a property. Every time the mapping file changes, the custom resource will be updated which will trigger the corresponding Lambda. 103 | properties: { 104 | 'S3_BUCKET': websiteBucket.bucketName, 105 | 'S3_CONFIG_FILE_KEY': this.s3ConfigFileKey, 106 | 'WEBSITE_CONFIG': websiteConfiguration, 107 | 'CLOUDFRONT_DISTRIBUTION_ID': cloudFrontDistribution.distributionId, 108 | // The bucket deployment clears the s3 bucket, so we must always run the custom resource to write the config 109 | 'ALWAYS_UPDATE': new Date().toISOString(), 110 | }, 111 | }); 112 | 113 | uploadWebsiteConfigResource.node.addDependency(websiteDeployment); 114 | 115 | // Output 116 | 117 | new cdk.CfnOutput(this, 'CloudFrontUrl', { 118 | value: cloudFrontDistribution.distributionDomainName, 119 | }); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Infra/lib/stack/UserPoolStack.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Construct } from "constructs"; 5 | import * as cognito from "aws-cdk-lib/aws-cognito"; 6 | import * as cdk from "aws-cdk-lib"; 7 | 8 | /** 9 | * In stand-alone stack so that we can avoid various & sundry 10 | * cyclic dependencies between assorted other stacks. Sigh. 11 | */ 12 | export class UserPoolStack extends cdk.Stack { 13 | public readonly userPool: cognito.UserPool; 14 | 15 | constructor(scope: Construct, id: string) { 16 | super(scope, id); 17 | this.userPool = new cognito.UserPool(this, "UserPool", { 18 | selfSignUpEnabled: false, 19 | autoVerify: { 20 | email: true, 21 | }, 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Infra/lib/utils/lambda.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | export const getLambdaPath = (lambdaFolder: string) => `../Lambdas/${lambdaFolder}/dist`; 5 | -------------------------------------------------------------------------------- /Infra/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@aws-samples/crosstalk-infra", 3 | "version": "1.0.0", 4 | "license": "MIT-0", 5 | "private": true, 6 | "scripts": { 7 | "build": "tsc", 8 | "watch": "tsc -w", 9 | "cdk": "cdk", 10 | "deploy-sandbox": "cdk -a cdk.out/assembly-Sandbox deploy '*' --require-approval never", 11 | "lint": "eslint --ext .ts --ext .tsx --ext .js --ext .jsx ./src", 12 | "lint:fix": "eslint --ext .ts --ext .tsx --ext .js --ext .jsx --fix ./src" 13 | }, 14 | "devDependencies": { 15 | "@types/node": "10.17.5", 16 | "@typescript-eslint/eslint-plugin": "3.9.0", 17 | "@typescript-eslint/parser": "3.9.0", 18 | "aws-cdk-lib": "^2.93.0", 19 | "eslint": "^7.32.0", 20 | "eslint-plugin-header": "3.0.0", 21 | "lint-staged": "10.2.11", 22 | "prettier": "2.0.5", 23 | "tslint": "6.1.3", 24 | "typescript": "3.9.7" 25 | }, 26 | "lint-staged": { 27 | "src/**/*.{js,ts}": [ 28 | "npm run lint:fix", 29 | "prettier --write" 30 | ] 31 | }, 32 | "dependencies": { 33 | "aws-cdk-lib": "^2.93.0", 34 | "aws-sdk": "2.814.0", 35 | "constructs": "^10.0.0", 36 | "source-map-support": "0.5.19" 37 | }, 38 | "resolutions": { 39 | "netmask": "^2.0.1", 40 | "ansi-regex": "^5.0.1", 41 | "minimatch": "^3.0.5", 42 | "xml2js": "^0.5.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Infra/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": ["es2018", "es2019"], 6 | "declaration": true, 7 | "strict": true, 8 | "noImplicitAny": true, 9 | "strictNullChecks": true, 10 | "outDir": "dist", 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": false, 17 | "inlineSourceMap": true, 18 | "inlineSources": true, 19 | "experimentalDecorators": true, 20 | "strictPropertyInitialization": false, 21 | "typeRoots": ["./node_modules/@types"] 22 | }, 23 | "exclude": ["cdk.out", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /Infra/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@aws-cdk/asset-awscli-v1@^2.2.200": 6 | version "2.2.200" 7 | resolved "https://registry.yarnpkg.com/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.200.tgz#6ead533f73f705ad7350eb46955e2538e50cd013" 8 | integrity sha512-Kf5J8DfJK4wZFWT2Myca0lhwke7LwHcHBo+4TvWOGJrFVVKVuuiLCkzPPRBQQVDj0Vtn2NBokZAz8pfMpAqAKg== 9 | 10 | "@aws-cdk/asset-kubectl-v20@^2.1.2": 11 | version "2.1.2" 12 | resolved "https://registry.yarnpkg.com/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz#d8e20b5f5dc20128ea2000dc479ca3c7ddc27248" 13 | integrity sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg== 14 | 15 | "@aws-cdk/asset-node-proxy-agent-v6@^2.0.1": 16 | version "2.0.1" 17 | resolved "https://registry.yarnpkg.com/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.0.1.tgz#6dc9b7cdb22ff622a7176141197962360c33e9ac" 18 | integrity sha512-DDt4SLdLOwWCjGtltH4VCST7hpOI5DzieuhGZsBpZ+AgJdSI2GCjklCXm0GCTwJG/SolkL5dtQXyUKgg9luBDg== 19 | 20 | "@babel/code-frame@7.12.11": 21 | version "7.12.11" 22 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" 23 | integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== 24 | dependencies: 25 | "@babel/highlight" "^7.10.4" 26 | 27 | "@babel/code-frame@^7.0.0": 28 | version "7.16.7" 29 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" 30 | integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== 31 | dependencies: 32 | "@babel/highlight" "^7.16.7" 33 | 34 | "@babel/helper-validator-identifier@^7.16.7": 35 | version "7.16.7" 36 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" 37 | integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== 38 | 39 | "@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": 40 | version "7.16.10" 41 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" 42 | integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== 43 | dependencies: 44 | "@babel/helper-validator-identifier" "^7.16.7" 45 | chalk "^2.0.0" 46 | js-tokens "^4.0.0" 47 | 48 | "@balena/dockerignore@^1.0.2": 49 | version "1.0.2" 50 | resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" 51 | integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== 52 | 53 | "@eslint/eslintrc@^0.4.3": 54 | version "0.4.3" 55 | resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" 56 | integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== 57 | dependencies: 58 | ajv "^6.12.4" 59 | debug "^4.1.1" 60 | espree "^7.3.0" 61 | globals "^13.9.0" 62 | ignore "^4.0.6" 63 | import-fresh "^3.2.1" 64 | js-yaml "^3.13.1" 65 | minimatch "^3.0.4" 66 | strip-json-comments "^3.1.1" 67 | 68 | "@humanwhocodes/config-array@^0.5.0": 69 | version "0.5.0" 70 | resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" 71 | integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== 72 | dependencies: 73 | "@humanwhocodes/object-schema" "^1.2.0" 74 | debug "^4.1.1" 75 | minimatch "^3.0.4" 76 | 77 | "@humanwhocodes/object-schema@^1.2.0": 78 | version "1.2.1" 79 | resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" 80 | integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== 81 | 82 | "@types/eslint-visitor-keys@^1.0.0": 83 | version "1.0.0" 84 | resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" 85 | integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== 86 | 87 | "@types/json-schema@^7.0.3": 88 | version "7.0.9" 89 | resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" 90 | integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== 91 | 92 | "@types/node@10.17.5": 93 | version "10.17.5" 94 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.5.tgz#c1920150f7b90708a7d0f3add12a06bc9123c055" 95 | integrity sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA== 96 | 97 | "@types/parse-json@^4.0.0": 98 | version "4.0.0" 99 | resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" 100 | integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== 101 | 102 | "@typescript-eslint/eslint-plugin@3.9.0": 103 | version "3.9.0" 104 | resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.9.0.tgz#0fe529b33d63c9a94f7503ca2bb12c84b9477ff3" 105 | integrity sha512-UD6b4p0/hSe1xdTvRCENSx7iQ+KR6ourlZFfYuPC7FlXEzdHuLPrEmuxZ23b2zW96KJX9Z3w05GE/wNOiEzrVg== 106 | dependencies: 107 | "@typescript-eslint/experimental-utils" "3.9.0" 108 | debug "^4.1.1" 109 | functional-red-black-tree "^1.0.1" 110 | regexpp "^3.0.0" 111 | semver "^7.3.2" 112 | tsutils "^3.17.1" 113 | 114 | "@typescript-eslint/experimental-utils@3.9.0": 115 | version "3.9.0" 116 | resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-3.9.0.tgz#3171d8ddba0bf02a8c2034188593630914fcf5ee" 117 | integrity sha512-/vSHUDYizSOhrOJdjYxPNGfb4a3ibO8zd4nUKo/QBFOmxosT3cVUV7KIg8Dwi6TXlr667G7YPqFK9+VSZOorNA== 118 | dependencies: 119 | "@types/json-schema" "^7.0.3" 120 | "@typescript-eslint/types" "3.9.0" 121 | "@typescript-eslint/typescript-estree" "3.9.0" 122 | eslint-scope "^5.0.0" 123 | eslint-utils "^2.0.0" 124 | 125 | "@typescript-eslint/parser@3.9.0": 126 | version "3.9.0" 127 | resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-3.9.0.tgz#344978a265d9a5c7c8f13e62c78172a4374dabea" 128 | integrity sha512-rDHOKb6uW2jZkHQniUQVZkixQrfsZGUCNWWbKWep4A5hGhN5dLHMUCNAWnC4tXRlHedXkTDptIpxs6e4Pz8UfA== 129 | dependencies: 130 | "@types/eslint-visitor-keys" "^1.0.0" 131 | "@typescript-eslint/experimental-utils" "3.9.0" 132 | "@typescript-eslint/types" "3.9.0" 133 | "@typescript-eslint/typescript-estree" "3.9.0" 134 | eslint-visitor-keys "^1.1.0" 135 | 136 | "@typescript-eslint/types@3.9.0": 137 | version "3.9.0" 138 | resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-3.9.0.tgz#be9d0aa451e1bf3ce99f2e6920659e5b2e6bfe18" 139 | integrity sha512-rb6LDr+dk9RVVXO/NJE8dT1pGlso3voNdEIN8ugm4CWM5w5GimbThCMiMl4da1t5u3YwPWEwOnKAULCZgBtBHg== 140 | 141 | "@typescript-eslint/typescript-estree@3.9.0": 142 | version "3.9.0" 143 | resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-3.9.0.tgz#c6abbb50fa0d715cab46fef67ca6378bf2eaca13" 144 | integrity sha512-N+158NKgN4rOmWVfvKOMoMFV5n8XxAliaKkArm/sOypzQ0bUL8MSnOEBW3VFIeffb/K5ce/cAV0yYhR7U4ALAA== 145 | dependencies: 146 | "@typescript-eslint/types" "3.9.0" 147 | "@typescript-eslint/visitor-keys" "3.9.0" 148 | debug "^4.1.1" 149 | glob "^7.1.6" 150 | is-glob "^4.0.1" 151 | lodash "^4.17.15" 152 | semver "^7.3.2" 153 | tsutils "^3.17.1" 154 | 155 | "@typescript-eslint/visitor-keys@3.9.0": 156 | version "3.9.0" 157 | resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-3.9.0.tgz#44de8e1b1df67adaf3b94d6b60b80f8faebc8dd3" 158 | integrity sha512-O1qeoGqDbu0EZUC/MZ6F1WHTIzcBVhGqDj3LhTnj65WUA548RXVxUHbYhAW9bZWfb2rnX9QsbbP5nmeJ5Z4+ng== 159 | dependencies: 160 | eslint-visitor-keys "^1.1.0" 161 | 162 | acorn-jsx@^5.3.1: 163 | version "5.3.2" 164 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" 165 | integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== 166 | 167 | acorn@^7.4.0: 168 | version "7.4.1" 169 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" 170 | integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== 171 | 172 | aggregate-error@^3.0.0: 173 | version "3.1.0" 174 | resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" 175 | integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== 176 | dependencies: 177 | clean-stack "^2.0.0" 178 | indent-string "^4.0.0" 179 | 180 | ajv@^6.10.0, ajv@^6.12.4: 181 | version "6.12.6" 182 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" 183 | integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== 184 | dependencies: 185 | fast-deep-equal "^3.1.1" 186 | fast-json-stable-stringify "^2.0.0" 187 | json-schema-traverse "^0.4.1" 188 | uri-js "^4.2.2" 189 | 190 | ajv@^8.0.1: 191 | version "8.9.0" 192 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" 193 | integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== 194 | dependencies: 195 | fast-deep-equal "^3.1.1" 196 | json-schema-traverse "^1.0.0" 197 | require-from-string "^2.0.2" 198 | uri-js "^4.2.2" 199 | 200 | ansi-colors@^4.1.1: 201 | version "4.1.1" 202 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 203 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 204 | 205 | ansi-escapes@^4.3.0: 206 | version "4.3.2" 207 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" 208 | integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== 209 | dependencies: 210 | type-fest "^0.21.3" 211 | 212 | ansi-regex@^5.0.1: 213 | version "5.0.1" 214 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 215 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 216 | 217 | ansi-styles@^3.2.1: 218 | version "3.2.1" 219 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 220 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 221 | dependencies: 222 | color-convert "^1.9.0" 223 | 224 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 225 | version "4.3.0" 226 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 227 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 228 | dependencies: 229 | color-convert "^2.0.1" 230 | 231 | argparse@^1.0.7: 232 | version "1.0.10" 233 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 234 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 235 | dependencies: 236 | sprintf-js "~1.0.2" 237 | 238 | astral-regex@^2.0.0: 239 | version "2.0.0" 240 | resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" 241 | integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== 242 | 243 | aws-cdk-lib@^2.93.0: 244 | version "2.93.0" 245 | resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.93.0.tgz#545bc0072bc0f2e27cb0fecb0c9e54de29b10731" 246 | integrity sha512-kKbcKkts272Ju5xjGKI3pXTOpiJxW4OQbDF8Vmw/NIkkuJLo8GlRCFfeOfoN/hilvlYQgENA67GCgSWccbvu7w== 247 | dependencies: 248 | "@aws-cdk/asset-awscli-v1" "^2.2.200" 249 | "@aws-cdk/asset-kubectl-v20" "^2.1.2" 250 | "@aws-cdk/asset-node-proxy-agent-v6" "^2.0.1" 251 | "@balena/dockerignore" "^1.0.2" 252 | case "1.6.3" 253 | fs-extra "^11.1.1" 254 | ignore "^5.2.4" 255 | jsonschema "^1.4.1" 256 | minimatch "^3.1.2" 257 | punycode "^2.3.0" 258 | semver "^7.5.4" 259 | table "^6.8.1" 260 | yaml "1.10.2" 261 | 262 | aws-sdk@2.814.0: 263 | version "2.814.0" 264 | resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.814.0.tgz#7a1c36006e0b5826f14bd2511b1d229ef6814bb0" 265 | integrity sha512-empd1m/J/MAkL6d9OeRpmg9thobULu0wk4v8W3JToaxGi2TD7PIdvE6yliZKyOVAdJINhBWEBhxR4OUIHhcGbQ== 266 | dependencies: 267 | buffer "4.9.2" 268 | events "1.1.1" 269 | ieee754 "1.1.13" 270 | jmespath "0.15.0" 271 | querystring "0.2.0" 272 | sax "1.2.1" 273 | url "0.10.3" 274 | uuid "3.3.2" 275 | xml2js "0.4.19" 276 | 277 | balanced-match@^1.0.0: 278 | version "1.0.2" 279 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 280 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 281 | 282 | base64-js@^1.0.2: 283 | version "1.5.1" 284 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" 285 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 286 | 287 | brace-expansion@^1.1.7: 288 | version "1.1.11" 289 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 290 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 291 | dependencies: 292 | balanced-match "^1.0.0" 293 | concat-map "0.0.1" 294 | 295 | braces@^3.0.1: 296 | version "3.0.2" 297 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 298 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 299 | dependencies: 300 | fill-range "^7.0.1" 301 | 302 | buffer-from@^1.0.0: 303 | version "1.1.2" 304 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 305 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 306 | 307 | buffer@4.9.2: 308 | version "4.9.2" 309 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" 310 | integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== 311 | dependencies: 312 | base64-js "^1.0.2" 313 | ieee754 "^1.1.4" 314 | isarray "^1.0.0" 315 | 316 | builtin-modules@^1.1.1: 317 | version "1.1.1" 318 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 319 | integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= 320 | 321 | callsites@^3.0.0: 322 | version "3.1.0" 323 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" 324 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== 325 | 326 | case@1.6.3: 327 | version "1.6.3" 328 | resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" 329 | integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== 330 | 331 | chalk@^2.0.0, chalk@^2.3.0: 332 | version "2.4.2" 333 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 334 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 335 | dependencies: 336 | ansi-styles "^3.2.1" 337 | escape-string-regexp "^1.0.5" 338 | supports-color "^5.3.0" 339 | 340 | chalk@^4.0.0, chalk@^4.1.0: 341 | version "4.1.2" 342 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 343 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 344 | dependencies: 345 | ansi-styles "^4.1.0" 346 | supports-color "^7.1.0" 347 | 348 | clean-stack@^2.0.0: 349 | version "2.2.0" 350 | resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" 351 | integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== 352 | 353 | cli-cursor@^3.1.0: 354 | version "3.1.0" 355 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" 356 | integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== 357 | dependencies: 358 | restore-cursor "^3.1.0" 359 | 360 | cli-truncate@2.1.0, cli-truncate@^2.1.0: 361 | version "2.1.0" 362 | resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" 363 | integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== 364 | dependencies: 365 | slice-ansi "^3.0.0" 366 | string-width "^4.2.0" 367 | 368 | color-convert@^1.9.0: 369 | version "1.9.3" 370 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 371 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 372 | dependencies: 373 | color-name "1.1.3" 374 | 375 | color-convert@^2.0.1: 376 | version "2.0.1" 377 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 378 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 379 | dependencies: 380 | color-name "~1.1.4" 381 | 382 | color-name@1.1.3: 383 | version "1.1.3" 384 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 385 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 386 | 387 | color-name@~1.1.4: 388 | version "1.1.4" 389 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 390 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 391 | 392 | commander@^2.12.1: 393 | version "2.20.3" 394 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 395 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 396 | 397 | commander@^5.1.0: 398 | version "5.1.0" 399 | resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" 400 | integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== 401 | 402 | concat-map@0.0.1: 403 | version "0.0.1" 404 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 405 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 406 | 407 | constructs@^10.0.0: 408 | version "10.1.273" 409 | resolved "https://registry.yarnpkg.com/constructs/-/constructs-10.1.273.tgz#b460d89e473f7f33f08ea82396dde27c3282284a" 410 | integrity sha512-JRaydmKm58aQm7crUcai3qGXtqhsh9e/dXyjQoZV6RiiEamf1V9A3yLLJIjit66Kl0Sub9quXgPmtqRfPYYlIg== 411 | 412 | cosmiconfig@^6.0.0: 413 | version "6.0.0" 414 | resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" 415 | integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== 416 | dependencies: 417 | "@types/parse-json" "^4.0.0" 418 | import-fresh "^3.1.0" 419 | parse-json "^5.0.0" 420 | path-type "^4.0.0" 421 | yaml "^1.7.2" 422 | 423 | cross-spawn@^7.0.0, cross-spawn@^7.0.2: 424 | version "7.0.3" 425 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 426 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 427 | dependencies: 428 | path-key "^3.1.0" 429 | shebang-command "^2.0.0" 430 | which "^2.0.1" 431 | 432 | debug@^4.0.1, debug@^4.1.1: 433 | version "4.3.3" 434 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" 435 | integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== 436 | dependencies: 437 | ms "2.1.2" 438 | 439 | dedent@^0.7.0: 440 | version "0.7.0" 441 | resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" 442 | integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= 443 | 444 | deep-is@^0.1.3: 445 | version "0.1.4" 446 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" 447 | integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== 448 | 449 | diff@^4.0.1: 450 | version "4.0.2" 451 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 452 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 453 | 454 | doctrine@^3.0.0: 455 | version "3.0.0" 456 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" 457 | integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== 458 | dependencies: 459 | esutils "^2.0.2" 460 | 461 | emoji-regex@^8.0.0: 462 | version "8.0.0" 463 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 464 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 465 | 466 | end-of-stream@^1.1.0: 467 | version "1.4.4" 468 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 469 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 470 | dependencies: 471 | once "^1.4.0" 472 | 473 | enquirer@^2.3.5: 474 | version "2.3.6" 475 | resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" 476 | integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== 477 | dependencies: 478 | ansi-colors "^4.1.1" 479 | 480 | error-ex@^1.3.1: 481 | version "1.3.2" 482 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" 483 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== 484 | dependencies: 485 | is-arrayish "^0.2.1" 486 | 487 | escape-string-regexp@^1.0.5: 488 | version "1.0.5" 489 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 490 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 491 | 492 | escape-string-regexp@^4.0.0: 493 | version "4.0.0" 494 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 495 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 496 | 497 | eslint-plugin-header@3.0.0: 498 | version "3.0.0" 499 | resolved "https://registry.yarnpkg.com/eslint-plugin-header/-/eslint-plugin-header-3.0.0.tgz#0e048b5f0adfdd9754142d59d551ae6bfdaf90ad" 500 | integrity sha512-OIu2ciVW8jK4Ove4JHm1I7X0C98PZuLCyCsoUhAm2HpyGS+zr34qLM6iV06unnDvssvvEh5BkOfaLRF+N7cGoQ== 501 | 502 | eslint-scope@^5.0.0, eslint-scope@^5.1.1: 503 | version "5.1.1" 504 | resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" 505 | integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== 506 | dependencies: 507 | esrecurse "^4.3.0" 508 | estraverse "^4.1.1" 509 | 510 | eslint-utils@^2.0.0, eslint-utils@^2.1.0: 511 | version "2.1.0" 512 | resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" 513 | integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== 514 | dependencies: 515 | eslint-visitor-keys "^1.1.0" 516 | 517 | eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: 518 | version "1.3.0" 519 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" 520 | integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== 521 | 522 | eslint-visitor-keys@^2.0.0: 523 | version "2.1.0" 524 | resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" 525 | integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== 526 | 527 | eslint@^7.32.0: 528 | version "7.32.0" 529 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" 530 | integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== 531 | dependencies: 532 | "@babel/code-frame" "7.12.11" 533 | "@eslint/eslintrc" "^0.4.3" 534 | "@humanwhocodes/config-array" "^0.5.0" 535 | ajv "^6.10.0" 536 | chalk "^4.0.0" 537 | cross-spawn "^7.0.2" 538 | debug "^4.0.1" 539 | doctrine "^3.0.0" 540 | enquirer "^2.3.5" 541 | escape-string-regexp "^4.0.0" 542 | eslint-scope "^5.1.1" 543 | eslint-utils "^2.1.0" 544 | eslint-visitor-keys "^2.0.0" 545 | espree "^7.3.1" 546 | esquery "^1.4.0" 547 | esutils "^2.0.2" 548 | fast-deep-equal "^3.1.3" 549 | file-entry-cache "^6.0.1" 550 | functional-red-black-tree "^1.0.1" 551 | glob-parent "^5.1.2" 552 | globals "^13.6.0" 553 | ignore "^4.0.6" 554 | import-fresh "^3.0.0" 555 | imurmurhash "^0.1.4" 556 | is-glob "^4.0.0" 557 | js-yaml "^3.13.1" 558 | json-stable-stringify-without-jsonify "^1.0.1" 559 | levn "^0.4.1" 560 | lodash.merge "^4.6.2" 561 | minimatch "^3.0.4" 562 | natural-compare "^1.4.0" 563 | optionator "^0.9.1" 564 | progress "^2.0.0" 565 | regexpp "^3.1.0" 566 | semver "^7.2.1" 567 | strip-ansi "^6.0.0" 568 | strip-json-comments "^3.1.0" 569 | table "^6.0.9" 570 | text-table "^0.2.0" 571 | v8-compile-cache "^2.0.3" 572 | 573 | espree@^7.3.0, espree@^7.3.1: 574 | version "7.3.1" 575 | resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" 576 | integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== 577 | dependencies: 578 | acorn "^7.4.0" 579 | acorn-jsx "^5.3.1" 580 | eslint-visitor-keys "^1.3.0" 581 | 582 | esprima@^4.0.0: 583 | version "4.0.1" 584 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 585 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 586 | 587 | esquery@^1.4.0: 588 | version "1.4.0" 589 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" 590 | integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 591 | dependencies: 592 | estraverse "^5.1.0" 593 | 594 | esrecurse@^4.3.0: 595 | version "4.3.0" 596 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" 597 | integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== 598 | dependencies: 599 | estraverse "^5.2.0" 600 | 601 | estraverse@^4.1.1: 602 | version "4.3.0" 603 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" 604 | integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== 605 | 606 | estraverse@^5.1.0, estraverse@^5.2.0: 607 | version "5.3.0" 608 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" 609 | integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== 610 | 611 | esutils@^2.0.2: 612 | version "2.0.3" 613 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 614 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 615 | 616 | events@1.1.1: 617 | version "1.1.1" 618 | resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" 619 | integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= 620 | 621 | execa@^4.0.1: 622 | version "4.1.0" 623 | resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" 624 | integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== 625 | dependencies: 626 | cross-spawn "^7.0.0" 627 | get-stream "^5.0.0" 628 | human-signals "^1.1.1" 629 | is-stream "^2.0.0" 630 | merge-stream "^2.0.0" 631 | npm-run-path "^4.0.0" 632 | onetime "^5.1.0" 633 | signal-exit "^3.0.2" 634 | strip-final-newline "^2.0.0" 635 | 636 | fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: 637 | version "3.1.3" 638 | resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" 639 | integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== 640 | 641 | fast-json-stable-stringify@^2.0.0: 642 | version "2.1.0" 643 | resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" 644 | integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== 645 | 646 | fast-levenshtein@^2.0.6: 647 | version "2.0.6" 648 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 649 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 650 | 651 | figures@^3.2.0: 652 | version "3.2.0" 653 | resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" 654 | integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== 655 | dependencies: 656 | escape-string-regexp "^1.0.5" 657 | 658 | file-entry-cache@^6.0.1: 659 | version "6.0.1" 660 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" 661 | integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== 662 | dependencies: 663 | flat-cache "^3.0.4" 664 | 665 | fill-range@^7.0.1: 666 | version "7.0.1" 667 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 668 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 669 | dependencies: 670 | to-regex-range "^5.0.1" 671 | 672 | flat-cache@^3.0.4: 673 | version "3.0.4" 674 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" 675 | integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== 676 | dependencies: 677 | flatted "^3.1.0" 678 | rimraf "^3.0.2" 679 | 680 | flatted@^3.1.0: 681 | version "3.2.5" 682 | resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" 683 | integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== 684 | 685 | fs-extra@^11.1.1: 686 | version "11.1.1" 687 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" 688 | integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== 689 | dependencies: 690 | graceful-fs "^4.2.0" 691 | jsonfile "^6.0.1" 692 | universalify "^2.0.0" 693 | 694 | fs.realpath@^1.0.0: 695 | version "1.0.0" 696 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 697 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 698 | 699 | function-bind@^1.1.1: 700 | version "1.1.1" 701 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 702 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 703 | 704 | functional-red-black-tree@^1.0.1: 705 | version "1.0.1" 706 | resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" 707 | integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= 708 | 709 | get-own-enumerable-property-symbols@^3.0.0: 710 | version "3.0.2" 711 | resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" 712 | integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== 713 | 714 | get-stream@^5.0.0: 715 | version "5.2.0" 716 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" 717 | integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== 718 | dependencies: 719 | pump "^3.0.0" 720 | 721 | glob-parent@^5.1.2: 722 | version "5.1.2" 723 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 724 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 725 | dependencies: 726 | is-glob "^4.0.1" 727 | 728 | glob@^7.1.1, glob@^7.1.3, glob@^7.1.6: 729 | version "7.2.0" 730 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 731 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 732 | dependencies: 733 | fs.realpath "^1.0.0" 734 | inflight "^1.0.4" 735 | inherits "2" 736 | minimatch "^3.0.4" 737 | once "^1.3.0" 738 | path-is-absolute "^1.0.0" 739 | 740 | globals@^13.6.0, globals@^13.9.0: 741 | version "13.12.0" 742 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e" 743 | integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg== 744 | dependencies: 745 | type-fest "^0.20.2" 746 | 747 | graceful-fs@^4.1.6, graceful-fs@^4.2.0: 748 | version "4.2.9" 749 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" 750 | integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== 751 | 752 | has-flag@^3.0.0: 753 | version "3.0.0" 754 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 755 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 756 | 757 | has-flag@^4.0.0: 758 | version "4.0.0" 759 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 760 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 761 | 762 | has@^1.0.3: 763 | version "1.0.3" 764 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 765 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 766 | dependencies: 767 | function-bind "^1.1.1" 768 | 769 | human-signals@^1.1.1: 770 | version "1.1.1" 771 | resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" 772 | integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== 773 | 774 | ieee754@1.1.13: 775 | version "1.1.13" 776 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" 777 | integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== 778 | 779 | ieee754@^1.1.4: 780 | version "1.2.1" 781 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" 782 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 783 | 784 | ignore@^4.0.6: 785 | version "4.0.6" 786 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" 787 | integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== 788 | 789 | ignore@^5.2.4: 790 | version "5.2.4" 791 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" 792 | integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== 793 | 794 | import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: 795 | version "3.3.0" 796 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" 797 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== 798 | dependencies: 799 | parent-module "^1.0.0" 800 | resolve-from "^4.0.0" 801 | 802 | imurmurhash@^0.1.4: 803 | version "0.1.4" 804 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 805 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 806 | 807 | indent-string@^4.0.0: 808 | version "4.0.0" 809 | resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" 810 | integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== 811 | 812 | inflight@^1.0.4: 813 | version "1.0.6" 814 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 815 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 816 | dependencies: 817 | once "^1.3.0" 818 | wrappy "1" 819 | 820 | inherits@2: 821 | version "2.0.4" 822 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 823 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 824 | 825 | is-arrayish@^0.2.1: 826 | version "0.2.1" 827 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 828 | integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= 829 | 830 | is-core-module@^2.8.1: 831 | version "2.8.1" 832 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" 833 | integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== 834 | dependencies: 835 | has "^1.0.3" 836 | 837 | is-extglob@^2.1.1: 838 | version "2.1.1" 839 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 840 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 841 | 842 | is-fullwidth-code-point@^3.0.0: 843 | version "3.0.0" 844 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 845 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 846 | 847 | is-glob@^4.0.0, is-glob@^4.0.1: 848 | version "4.0.3" 849 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 850 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 851 | dependencies: 852 | is-extglob "^2.1.1" 853 | 854 | is-number@^7.0.0: 855 | version "7.0.0" 856 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 857 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 858 | 859 | is-obj@^1.0.1: 860 | version "1.0.1" 861 | resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" 862 | integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= 863 | 864 | is-regexp@^1.0.0: 865 | version "1.0.0" 866 | resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" 867 | integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= 868 | 869 | is-stream@^2.0.0: 870 | version "2.0.1" 871 | resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" 872 | integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== 873 | 874 | is-unicode-supported@^0.1.0: 875 | version "0.1.0" 876 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 877 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 878 | 879 | isarray@^1.0.0: 880 | version "1.0.0" 881 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 882 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 883 | 884 | isexe@^2.0.0: 885 | version "2.0.0" 886 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 887 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 888 | 889 | jmespath@0.15.0: 890 | version "0.15.0" 891 | resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" 892 | integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= 893 | 894 | js-tokens@^4.0.0: 895 | version "4.0.0" 896 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" 897 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 898 | 899 | js-yaml@^3.13.1: 900 | version "3.14.1" 901 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" 902 | integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== 903 | dependencies: 904 | argparse "^1.0.7" 905 | esprima "^4.0.0" 906 | 907 | json-parse-even-better-errors@^2.3.0: 908 | version "2.3.1" 909 | resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" 910 | integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== 911 | 912 | json-schema-traverse@^0.4.1: 913 | version "0.4.1" 914 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" 915 | integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== 916 | 917 | json-schema-traverse@^1.0.0: 918 | version "1.0.0" 919 | resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" 920 | integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== 921 | 922 | json-stable-stringify-without-jsonify@^1.0.1: 923 | version "1.0.1" 924 | resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" 925 | integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= 926 | 927 | jsonfile@^6.0.1: 928 | version "6.1.0" 929 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" 930 | integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== 931 | dependencies: 932 | universalify "^2.0.0" 933 | optionalDependencies: 934 | graceful-fs "^4.1.6" 935 | 936 | jsonschema@^1.4.1: 937 | version "1.4.1" 938 | resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" 939 | integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== 940 | 941 | levn@^0.4.1: 942 | version "0.4.1" 943 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" 944 | integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== 945 | dependencies: 946 | prelude-ls "^1.2.1" 947 | type-check "~0.4.0" 948 | 949 | lines-and-columns@^1.1.6: 950 | version "1.2.4" 951 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" 952 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== 953 | 954 | lint-staged@10.2.11: 955 | version "10.2.11" 956 | resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.2.11.tgz#713c80877f2dc8b609b05bc59020234e766c9720" 957 | integrity sha512-LRRrSogzbixYaZItE2APaS4l2eJMjjf5MbclRZpLJtcQJShcvUzKXsNeZgsLIZ0H0+fg2tL4B59fU9wHIHtFIA== 958 | dependencies: 959 | chalk "^4.0.0" 960 | cli-truncate "2.1.0" 961 | commander "^5.1.0" 962 | cosmiconfig "^6.0.0" 963 | debug "^4.1.1" 964 | dedent "^0.7.0" 965 | enquirer "^2.3.5" 966 | execa "^4.0.1" 967 | listr2 "^2.1.0" 968 | log-symbols "^4.0.0" 969 | micromatch "^4.0.2" 970 | normalize-path "^3.0.0" 971 | please-upgrade-node "^3.2.0" 972 | string-argv "0.3.1" 973 | stringify-object "^3.3.0" 974 | 975 | listr2@^2.1.0: 976 | version "2.6.2" 977 | resolved "https://registry.yarnpkg.com/listr2/-/listr2-2.6.2.tgz#4912eb01e1e2dd72ec37f3895a56bf2622d6f36a" 978 | integrity sha512-6x6pKEMs8DSIpA/tixiYY2m/GcbgMplMVmhQAaLFxEtNSKLeWTGjtmU57xvv6QCm2XcqzyNXL/cTSVf4IChCRA== 979 | dependencies: 980 | chalk "^4.1.0" 981 | cli-truncate "^2.1.0" 982 | figures "^3.2.0" 983 | indent-string "^4.0.0" 984 | log-update "^4.0.0" 985 | p-map "^4.0.0" 986 | rxjs "^6.6.2" 987 | through "^2.3.8" 988 | 989 | lodash.merge@^4.6.2: 990 | version "4.6.2" 991 | resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" 992 | integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== 993 | 994 | lodash.truncate@^4.4.2: 995 | version "4.4.2" 996 | resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" 997 | integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= 998 | 999 | lodash@^4.17.15: 1000 | version "4.17.21" 1001 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 1002 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 1003 | 1004 | log-symbols@^4.0.0: 1005 | version "4.1.0" 1006 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 1007 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 1008 | dependencies: 1009 | chalk "^4.1.0" 1010 | is-unicode-supported "^0.1.0" 1011 | 1012 | log-update@^4.0.0: 1013 | version "4.0.0" 1014 | resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" 1015 | integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== 1016 | dependencies: 1017 | ansi-escapes "^4.3.0" 1018 | cli-cursor "^3.1.0" 1019 | slice-ansi "^4.0.0" 1020 | wrap-ansi "^6.2.0" 1021 | 1022 | lru-cache@^6.0.0: 1023 | version "6.0.0" 1024 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" 1025 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 1026 | dependencies: 1027 | yallist "^4.0.0" 1028 | 1029 | merge-stream@^2.0.0: 1030 | version "2.0.0" 1031 | resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" 1032 | integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 1033 | 1034 | micromatch@^4.0.2: 1035 | version "4.0.4" 1036 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" 1037 | integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== 1038 | dependencies: 1039 | braces "^3.0.1" 1040 | picomatch "^2.2.3" 1041 | 1042 | mimic-fn@^2.1.0: 1043 | version "2.1.0" 1044 | resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" 1045 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 1046 | 1047 | minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.2: 1048 | version "3.1.2" 1049 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1050 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1051 | dependencies: 1052 | brace-expansion "^1.1.7" 1053 | 1054 | minimist@^1.2.5: 1055 | version "1.2.6" 1056 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" 1057 | integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== 1058 | 1059 | mkdirp@^0.5.3: 1060 | version "0.5.5" 1061 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" 1062 | integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== 1063 | dependencies: 1064 | minimist "^1.2.5" 1065 | 1066 | ms@2.1.2: 1067 | version "2.1.2" 1068 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1069 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1070 | 1071 | natural-compare@^1.4.0: 1072 | version "1.4.0" 1073 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 1074 | integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= 1075 | 1076 | netmask@^2.0.1: 1077 | version "2.0.2" 1078 | resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" 1079 | integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== 1080 | 1081 | normalize-path@^3.0.0: 1082 | version "3.0.0" 1083 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1084 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1085 | 1086 | npm-run-path@^4.0.0: 1087 | version "4.0.1" 1088 | resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" 1089 | integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== 1090 | dependencies: 1091 | path-key "^3.0.0" 1092 | 1093 | once@^1.3.0, once@^1.3.1, once@^1.4.0: 1094 | version "1.4.0" 1095 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1096 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 1097 | dependencies: 1098 | wrappy "1" 1099 | 1100 | onetime@^5.1.0: 1101 | version "5.1.2" 1102 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" 1103 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 1104 | dependencies: 1105 | mimic-fn "^2.1.0" 1106 | 1107 | optionator@^0.9.1: 1108 | version "0.9.1" 1109 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" 1110 | integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== 1111 | dependencies: 1112 | deep-is "^0.1.3" 1113 | fast-levenshtein "^2.0.6" 1114 | levn "^0.4.1" 1115 | prelude-ls "^1.2.1" 1116 | type-check "^0.4.0" 1117 | word-wrap "^1.2.3" 1118 | 1119 | p-map@^4.0.0: 1120 | version "4.0.0" 1121 | resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" 1122 | integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== 1123 | dependencies: 1124 | aggregate-error "^3.0.0" 1125 | 1126 | parent-module@^1.0.0: 1127 | version "1.0.1" 1128 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" 1129 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== 1130 | dependencies: 1131 | callsites "^3.0.0" 1132 | 1133 | parse-json@^5.0.0: 1134 | version "5.2.0" 1135 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" 1136 | integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== 1137 | dependencies: 1138 | "@babel/code-frame" "^7.0.0" 1139 | error-ex "^1.3.1" 1140 | json-parse-even-better-errors "^2.3.0" 1141 | lines-and-columns "^1.1.6" 1142 | 1143 | path-is-absolute@^1.0.0: 1144 | version "1.0.1" 1145 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1146 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 1147 | 1148 | path-key@^3.0.0, path-key@^3.1.0: 1149 | version "3.1.1" 1150 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 1151 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 1152 | 1153 | path-parse@^1.0.7: 1154 | version "1.0.7" 1155 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" 1156 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== 1157 | 1158 | path-type@^4.0.0: 1159 | version "4.0.0" 1160 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" 1161 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== 1162 | 1163 | picomatch@^2.2.3: 1164 | version "2.3.1" 1165 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1166 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1167 | 1168 | please-upgrade-node@^3.2.0: 1169 | version "3.2.0" 1170 | resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" 1171 | integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== 1172 | dependencies: 1173 | semver-compare "^1.0.0" 1174 | 1175 | prelude-ls@^1.2.1: 1176 | version "1.2.1" 1177 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" 1178 | integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== 1179 | 1180 | prettier@2.0.5: 1181 | version "2.0.5" 1182 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" 1183 | integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== 1184 | 1185 | progress@^2.0.0: 1186 | version "2.0.3" 1187 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 1188 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 1189 | 1190 | pump@^3.0.0: 1191 | version "3.0.0" 1192 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" 1193 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 1194 | dependencies: 1195 | end-of-stream "^1.1.0" 1196 | once "^1.3.1" 1197 | 1198 | punycode@1.3.2: 1199 | version "1.3.2" 1200 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" 1201 | integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= 1202 | 1203 | punycode@^2.1.0, punycode@^2.3.0: 1204 | version "2.3.0" 1205 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" 1206 | integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== 1207 | 1208 | querystring@0.2.0: 1209 | version "0.2.0" 1210 | resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" 1211 | integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= 1212 | 1213 | regexpp@^3.0.0, regexpp@^3.1.0: 1214 | version "3.2.0" 1215 | resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" 1216 | integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== 1217 | 1218 | require-from-string@^2.0.2: 1219 | version "2.0.2" 1220 | resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" 1221 | integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== 1222 | 1223 | resolve-from@^4.0.0: 1224 | version "4.0.0" 1225 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" 1226 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== 1227 | 1228 | resolve@^1.3.2: 1229 | version "1.22.0" 1230 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" 1231 | integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== 1232 | dependencies: 1233 | is-core-module "^2.8.1" 1234 | path-parse "^1.0.7" 1235 | supports-preserve-symlinks-flag "^1.0.0" 1236 | 1237 | restore-cursor@^3.1.0: 1238 | version "3.1.0" 1239 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" 1240 | integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== 1241 | dependencies: 1242 | onetime "^5.1.0" 1243 | signal-exit "^3.0.2" 1244 | 1245 | rimraf@^3.0.2: 1246 | version "3.0.2" 1247 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1248 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1249 | dependencies: 1250 | glob "^7.1.3" 1251 | 1252 | rxjs@^6.6.2: 1253 | version "6.6.7" 1254 | resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" 1255 | integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== 1256 | dependencies: 1257 | tslib "^1.9.0" 1258 | 1259 | sax@1.2.1: 1260 | version "1.2.1" 1261 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" 1262 | integrity sha1-e45lYZCyKOgaZq6nSEgNgozS03o= 1263 | 1264 | sax@>=0.6.0: 1265 | version "1.2.4" 1266 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" 1267 | integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== 1268 | 1269 | semver-compare@^1.0.0: 1270 | version "1.0.0" 1271 | resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" 1272 | integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= 1273 | 1274 | semver@^5.3.0: 1275 | version "5.7.2" 1276 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" 1277 | integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== 1278 | 1279 | semver@^7.2.1, semver@^7.3.2, semver@^7.5.4: 1280 | version "7.5.4" 1281 | resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" 1282 | integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== 1283 | dependencies: 1284 | lru-cache "^6.0.0" 1285 | 1286 | shebang-command@^2.0.0: 1287 | version "2.0.0" 1288 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 1289 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 1290 | dependencies: 1291 | shebang-regex "^3.0.0" 1292 | 1293 | shebang-regex@^3.0.0: 1294 | version "3.0.0" 1295 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 1296 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 1297 | 1298 | signal-exit@^3.0.2: 1299 | version "3.0.6" 1300 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" 1301 | integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== 1302 | 1303 | slice-ansi@^3.0.0: 1304 | version "3.0.0" 1305 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" 1306 | integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== 1307 | dependencies: 1308 | ansi-styles "^4.0.0" 1309 | astral-regex "^2.0.0" 1310 | is-fullwidth-code-point "^3.0.0" 1311 | 1312 | slice-ansi@^4.0.0: 1313 | version "4.0.0" 1314 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" 1315 | integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== 1316 | dependencies: 1317 | ansi-styles "^4.0.0" 1318 | astral-regex "^2.0.0" 1319 | is-fullwidth-code-point "^3.0.0" 1320 | 1321 | source-map-support@0.5.19: 1322 | version "0.5.19" 1323 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" 1324 | integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== 1325 | dependencies: 1326 | buffer-from "^1.0.0" 1327 | source-map "^0.6.0" 1328 | 1329 | source-map@^0.6.0: 1330 | version "0.6.1" 1331 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1332 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1333 | 1334 | sprintf-js@~1.0.2: 1335 | version "1.0.3" 1336 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 1337 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 1338 | 1339 | string-argv@0.3.1: 1340 | version "0.3.1" 1341 | resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" 1342 | integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== 1343 | 1344 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 1345 | version "4.2.3" 1346 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1347 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1348 | dependencies: 1349 | emoji-regex "^8.0.0" 1350 | is-fullwidth-code-point "^3.0.0" 1351 | strip-ansi "^6.0.1" 1352 | 1353 | stringify-object@^3.3.0: 1354 | version "3.3.0" 1355 | resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" 1356 | integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== 1357 | dependencies: 1358 | get-own-enumerable-property-symbols "^3.0.0" 1359 | is-obj "^1.0.1" 1360 | is-regexp "^1.0.0" 1361 | 1362 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1363 | version "6.0.1" 1364 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1365 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1366 | dependencies: 1367 | ansi-regex "^5.0.1" 1368 | 1369 | strip-final-newline@^2.0.0: 1370 | version "2.0.0" 1371 | resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" 1372 | integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== 1373 | 1374 | strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: 1375 | version "3.1.1" 1376 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1377 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1378 | 1379 | supports-color@^5.3.0: 1380 | version "5.5.0" 1381 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 1382 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 1383 | dependencies: 1384 | has-flag "^3.0.0" 1385 | 1386 | supports-color@^7.1.0: 1387 | version "7.2.0" 1388 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1389 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1390 | dependencies: 1391 | has-flag "^4.0.0" 1392 | 1393 | supports-preserve-symlinks-flag@^1.0.0: 1394 | version "1.0.0" 1395 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" 1396 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== 1397 | 1398 | table@^6.0.9, table@^6.8.1: 1399 | version "6.8.1" 1400 | resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" 1401 | integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== 1402 | dependencies: 1403 | ajv "^8.0.1" 1404 | lodash.truncate "^4.4.2" 1405 | slice-ansi "^4.0.0" 1406 | string-width "^4.2.3" 1407 | strip-ansi "^6.0.1" 1408 | 1409 | text-table@^0.2.0: 1410 | version "0.2.0" 1411 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 1412 | integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= 1413 | 1414 | through@^2.3.8: 1415 | version "2.3.8" 1416 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 1417 | integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= 1418 | 1419 | to-regex-range@^5.0.1: 1420 | version "5.0.1" 1421 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1422 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1423 | dependencies: 1424 | is-number "^7.0.0" 1425 | 1426 | tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: 1427 | version "1.14.1" 1428 | resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" 1429 | integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== 1430 | 1431 | tslint@6.1.3: 1432 | version "6.1.3" 1433 | resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" 1434 | integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== 1435 | dependencies: 1436 | "@babel/code-frame" "^7.0.0" 1437 | builtin-modules "^1.1.1" 1438 | chalk "^2.3.0" 1439 | commander "^2.12.1" 1440 | diff "^4.0.1" 1441 | glob "^7.1.1" 1442 | js-yaml "^3.13.1" 1443 | minimatch "^3.0.4" 1444 | mkdirp "^0.5.3" 1445 | resolve "^1.3.2" 1446 | semver "^5.3.0" 1447 | tslib "^1.13.0" 1448 | tsutils "^2.29.0" 1449 | 1450 | tsutils@^2.29.0: 1451 | version "2.29.0" 1452 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" 1453 | integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== 1454 | dependencies: 1455 | tslib "^1.8.1" 1456 | 1457 | tsutils@^3.17.1: 1458 | version "3.21.0" 1459 | resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" 1460 | integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== 1461 | dependencies: 1462 | tslib "^1.8.1" 1463 | 1464 | type-check@^0.4.0, type-check@~0.4.0: 1465 | version "0.4.0" 1466 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" 1467 | integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== 1468 | dependencies: 1469 | prelude-ls "^1.2.1" 1470 | 1471 | type-fest@^0.20.2: 1472 | version "0.20.2" 1473 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" 1474 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 1475 | 1476 | type-fest@^0.21.3: 1477 | version "0.21.3" 1478 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" 1479 | integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== 1480 | 1481 | typescript@3.9.7: 1482 | version "3.9.7" 1483 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.7.tgz#98d600a5ebdc38f40cb277522f12dc800e9e25fa" 1484 | integrity sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw== 1485 | 1486 | universalify@^2.0.0: 1487 | version "2.0.0" 1488 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" 1489 | integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== 1490 | 1491 | uri-js@^4.2.2: 1492 | version "4.4.1" 1493 | resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" 1494 | integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== 1495 | dependencies: 1496 | punycode "^2.1.0" 1497 | 1498 | url@0.10.3: 1499 | version "0.10.3" 1500 | resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" 1501 | integrity sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ= 1502 | dependencies: 1503 | punycode "1.3.2" 1504 | querystring "0.2.0" 1505 | 1506 | uuid@3.3.2: 1507 | version "3.3.2" 1508 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" 1509 | integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== 1510 | 1511 | v8-compile-cache@^2.0.3: 1512 | version "2.3.0" 1513 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" 1514 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 1515 | 1516 | which@^2.0.1: 1517 | version "2.0.2" 1518 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 1519 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 1520 | dependencies: 1521 | isexe "^2.0.0" 1522 | 1523 | word-wrap@^1.2.3: 1524 | version "1.2.4" 1525 | resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" 1526 | integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== 1527 | 1528 | wrap-ansi@^6.2.0: 1529 | version "6.2.0" 1530 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" 1531 | integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== 1532 | dependencies: 1533 | ansi-styles "^4.0.0" 1534 | string-width "^4.1.0" 1535 | strip-ansi "^6.0.0" 1536 | 1537 | wrappy@1: 1538 | version "1.0.2" 1539 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1540 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 1541 | 1542 | xml2js@0.4.19, xml2js@^0.5.0: 1543 | version "0.5.0" 1544 | resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.5.0.tgz#d9440631fbb2ed800203fad106f2724f62c493b7" 1545 | integrity sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA== 1546 | dependencies: 1547 | sax ">=0.6.0" 1548 | xmlbuilder "~11.0.0" 1549 | 1550 | xmlbuilder@~11.0.0: 1551 | version "11.0.1" 1552 | resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" 1553 | integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== 1554 | 1555 | yallist@^4.0.0: 1556 | version "4.0.0" 1557 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 1558 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 1559 | 1560 | yaml@1.10.2, yaml@^1.7.2: 1561 | version "1.10.2" 1562 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" 1563 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== 1564 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 4 | software and associated documentation files (the "Software"), to deal in the Software 5 | without restriction, including without limitation the rights to use, copy, modify, 6 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 10 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 11 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 12 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 13 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 14 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | -------------------------------------------------------------------------------- /Lambdas/ChimeCallService/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env", "@babel/preset-typescript", "@babel/preset-react"], 3 | "plugins": [ 4 | ["@babel/plugin-proposal-decorators", { "legacy": true }], 5 | [ 6 | "@babel/plugin-transform-runtime", 7 | { 8 | "regenerator": true 9 | } 10 | ], 11 | "@babel/proposal-class-properties", 12 | "@babel/proposal-object-rest-spread" 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /Lambdas/ChimeCallService/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', // Specifies the ESLint parser 3 | extends: [ 4 | 'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react 5 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin 6 | 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier 7 | 'plugin:prettier/recommended' // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. 8 | ], 9 | parserOptions: { 10 | ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features 11 | sourceType: 'module', // Allows for the use of imports 12 | ecmaFeatures: { 13 | jsx: true // Allows for the parsing of JSX 14 | } 15 | }, 16 | plugins: ['json'], 17 | rules: { 18 | 'import/prefer-default-export': 'warn', 19 | 'react/display-name': 'off', 20 | 'react/prop-types': 'off', 21 | 'react/jsx-key': 'off', 22 | "react/jsx-indent": ["error", 4], 23 | "react/jsx-indent-props": ["error", 4], 24 | 'react/jsx-filename-extension': [2, { 'extensions': ['.js', '.jsx', '.ts', '.tsx'] }], 25 | 'react/jsx-props-no-spreading': 'warn', 26 | '@typescript-eslint/no-var-requires': 'off', 27 | '@typescript-eslint/ban-ts-ignore': 'off', 28 | '@typescript-eslint/explicit-function-return-type': 'off', 29 | '@typescript-eslint/no-use-before-define': 'off' 30 | }, 31 | settings: { 32 | react: { 33 | version: 'detect' // Tells eslint-plugin-react to automatically detect the version of React to use 34 | }, 35 | "import/resolver": { 36 | node: { 37 | extensions: ['.js', '.jsx', '.ts', '.tsx'], 38 | paths: ['./src'] 39 | } 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Lambdas/ChimeCallService/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@aws-samples/crosstalk-chime-call-service", 3 | "version": "1.0.0", 4 | "license": "MIT-0", 5 | "description": "", 6 | "private": true, 7 | "scripts": { 8 | "test": "echo 'no tests' && exit 1", 9 | "dev": "NODE_ENV=development webpack --mode development", 10 | "build": "webpack --mode production", 11 | "eslint": "eslint --quiet --ext .ts --ext .tsx --ignore-pattern node_modules/ .", 12 | "eslint:fix": "eslint --fix --ext .ts --ext .tsx ." 13 | }, 14 | "keywords": [], 15 | "author": "", 16 | "dependencies": { 17 | "@types/node": "^12.20.15", 18 | "@types/uuid": "^8.3.0", 19 | "clsx": "^1.0.4", 20 | "@aws-samples/crosstalk-common": "../Common/", 21 | "object-path": "^0.11.8", 22 | "path": "^0.12.7" 23 | }, 24 | "devDependencies": { 25 | "@babel/core": "^7.23.2", 26 | "@babel/plugin-proposal-class-properties": "^7.14.5", 27 | "@babel/plugin-proposal-decorators": "^7.14.5", 28 | "@babel/plugin-proposal-object-rest-spread": "^7.14.5", 29 | "@babel/plugin-transform-runtime": "^7.14.5", 30 | "@babel/preset-env": "^7.22.20", 31 | "@babel/preset-react": "^7.14.5", 32 | "@babel/preset-typescript": "^7.14.5", 33 | "@typescript-eslint/eslint-plugin": "^5.10.1", 34 | "@typescript-eslint/parser": "^5.10.1", 35 | "aws-sdk": "^2.928.0", 36 | "babel-loader": "^9.1.3", 37 | "copy-webpack-plugin": "^10.2.1", 38 | "eslint": "^8.7.0", 39 | "eslint-config-prettier": "^6.3.0", 40 | "eslint-plugin-import": "^2.23.4", 41 | "eslint-plugin-json": "^1.4.0", 42 | "eslint-plugin-jsx-a11y": "^6.2.3", 43 | "eslint-plugin-prettier": "^3.4.0", 44 | "eslint-plugin-react": "^7.24.0", 45 | "file-loader": "^4.2.0", 46 | "fork-ts-checker-webpack-plugin": "^6.5.0", 47 | "html-loader": "^0.5.5", 48 | "mini-css-extract-plugin": "^0.8.0", 49 | "prettier": "^1.18.2", 50 | "source-map-loader": "^0.2.4", 51 | "ts-node": "^9.1.1", 52 | "tsconfig-paths-webpack-plugin": "^3.5.1", 53 | "typescript": "^3.9.9", 54 | "url-loader": "^2.1.0", 55 | "uuid": "^8.3.2", 56 | "webpack": "^5.88.2", 57 | "webpack-cli": "^4.9.2" 58 | }, 59 | "resolutions": { 60 | "glob-parent": "^5.1.2", 61 | "normalize-url": "^4.5.1", 62 | "ssri": "^8.0.1", 63 | "minimatch": "^3.0.5", 64 | "loader-utils": "^2.0.3", 65 | "json5": "^2.2.2", 66 | "xml2js": "^0.5.0", 67 | "semver": "^7.5.2" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Lambdas/ChimeCallService/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { respond } from "@aws-samples/crosstalk-common"; 5 | import * as AWS from "aws-sdk"; 6 | import { GuidString } from "aws-sdk/clients/chime"; 7 | import { v4 as uuid } from "uuid"; 8 | 9 | const chime = new AWS.Chime({ region: "us-east-1" }); 10 | 11 | /** 12 | * used by UI to create a new video chat session using the Chime SDK 13 | */ 14 | export const chimeCallHandler = async (event: any, context: any) => { 15 | const requestId = context.awsRequestId; 16 | const region = process.env.AWS_REGION; 17 | 18 | try { 19 | const meeting = await chime 20 | .createMeeting({ 21 | ClientRequestToken: requestId, 22 | MediaRegion: region 23 | }) 24 | .promise(); 25 | 26 | const meetingId: GuidString = meeting.Meeting!.MeetingId as GuidString; 27 | 28 | try { 29 | const caller = await chime 30 | .createAttendee({ 31 | MeetingId: meetingId, 32 | ExternalUserId: uuid() 33 | }) 34 | .promise(); 35 | 36 | const callee = await chime 37 | .createAttendee({ 38 | MeetingId: meetingId, 39 | ExternalUserId: uuid() 40 | }) 41 | .promise(); 42 | 43 | return respond(200, { 44 | Meeting: meeting.Meeting, 45 | Caller: caller.Attendee, 46 | Callee: callee.Attendee 47 | }); 48 | } catch (err) { 49 | console.log("err: ", err); 50 | } 51 | } catch (err) { 52 | console.log("err: ", err); 53 | } 54 | 55 | return respond(500, {}); 56 | }; 57 | -------------------------------------------------------------------------------- /Lambdas/ChimeCallService/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "target": "ES2018", 5 | "module": "commonjs", 6 | "lib": ["es2018", "dom"], 7 | "declaration": true, 8 | "strict": true, 9 | "noImplicitAny": true, 10 | "strictNullChecks": true, 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": false, 17 | "inlineSourceMap": true, 18 | "inlineSources": true, 19 | "experimentalDecorators": true, 20 | "strictPropertyInitialization": false, 21 | "typeRoots": ["./node_modules/@types"], 22 | "resolveJsonModule": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Lambdas/ChimeCallService/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const ROOT_PATH = path.resolve(__dirname, '.'); 3 | const OUTPUT_DIR = `${path.resolve(__dirname, '.')}/dist`; 4 | const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); 5 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); 6 | 7 | module.exports = { 8 | target: 'node', 9 | entry: { 10 | main: [path.join(ROOT_PATH, './src/index.ts')] 11 | }, 12 | devtool: 'source-map', 13 | output: { 14 | filename: 'index.js', 15 | path: OUTPUT_DIR, 16 | libraryTarget: 'commonjs2' 17 | }, 18 | resolve: { 19 | extensions: ['.mjs', '.js', '.jsx', '.ts', '.tsx'], 20 | plugins: [new TsconfigPathsPlugin({})] 21 | }, 22 | plugins: [ 23 | new ForkTsCheckerWebpackPlugin({ 24 | }), 25 | ], 26 | module: { 27 | rules: [ 28 | { 29 | test: /\.(js|jsx)$/, 30 | exclude: /node_modules/, 31 | use: { 32 | loader: 'babel-loader' 33 | } 34 | }, 35 | { 36 | test: /\.tsx?$/, 37 | exclude: /node_modules/, 38 | use: { 39 | loader: 'babel-loader' 40 | } 41 | }, 42 | { 43 | test: /\.js$/, 44 | use: ['source-map-loader'], 45 | enforce: 'pre', 46 | exclude: /node_modules/ 47 | }, 48 | ] 49 | }, 50 | performance: { 51 | hints: false 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /Lambdas/Common/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', // Specifies the ESLint parser 3 | extends: [ 4 | 'plugin:react/recommended', // Uses the recommended rules from @eslint-plugin-react 5 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin 6 | 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier 7 | 'plugin:prettier/recommended' // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. 8 | ], 9 | parserOptions: { 10 | ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features 11 | sourceType: 'module', // Allows for the use of imports 12 | ecmaFeatures: { 13 | jsx: true // Allows for the parsing of JSX 14 | } 15 | }, 16 | plugins: ['json'], 17 | rules: { 18 | 'import/prefer-default-export': 'warn', 19 | 'react/display-name': 'off', 20 | 'react/prop-types': 'off', 21 | 'react/jsx-key': 'off', 22 | "react/jsx-indent": ["error", 4], 23 | "react/jsx-indent-props": ["error", 4], 24 | 'react/jsx-filename-extension': [2, { 'extensions': ['.js', '.jsx', '.ts', '.tsx'] }], 25 | 'react/jsx-props-no-spreading': 'warn', 26 | '@typescript-eslint/no-var-requires': 'off', 27 | '@typescript-eslint/ban-ts-ignore': 'off', 28 | '@typescript-eslint/explicit-function-return-type': 'off', 29 | '@typescript-eslint/no-use-before-define': 'off' 30 | }, 31 | settings: { 32 | react: { 33 | version: 'detect' // Tells eslint-plugin-react to automatically detect the version of React to use 34 | }, 35 | "import/resolver": { 36 | node: { 37 | extensions: ['.js', '.jsx', '.ts', '.tsx'], 38 | paths: ['./src'] 39 | } 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Lambdas/Common/.gitignore: -------------------------------------------------------------------------------- 1 | src/**/*.d.ts 2 | -------------------------------------------------------------------------------- /Lambdas/Common/.npmignore: -------------------------------------------------------------------------------- 1 | src -------------------------------------------------------------------------------- /Lambdas/Common/.prittierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | trailingComma: 'none', 4 | singleQuote: true, 5 | printWidth: 120, 6 | tabWidth: 4 7 | }; 8 | -------------------------------------------------------------------------------- /Lambdas/Common/README.md: -------------------------------------------------------------------------------- 1 | ## Common 2 | 3 | This package provides some helper methods which can be shared between the other lambda packages. 4 | -------------------------------------------------------------------------------- /Lambdas/Common/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@aws-samples/crosstalk-common", 3 | "version": "1.0.0", 4 | "license": "MIT-0", 5 | "description": "", 6 | "private": true, 7 | "main": "dist/index.js", 8 | "types": "dist/index.d.ts", 9 | "scripts": { 10 | "test": "echo 'no tests' && exit 1", 11 | "build": "tsc", 12 | "eslint": "eslint --quiet --ext .ts --ext .tsx --ignore-pattern node_modules/ .", 13 | "eslint:fix": "eslint --fix --ext .ts --ext .tsx ." 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "dependencies": { 18 | "@types/node": "^12.20.15", 19 | "@types/uuid": "^8.3.0", 20 | "clsx": "^1.0.4", 21 | "object-path": "^0.11.8", 22 | "path": "^0.12.7", 23 | "ts-loader": "^8.3.0" 24 | }, 25 | "devDependencies": { 26 | "@babel/core": "^7.23.2", 27 | "@typescript-eslint/eslint-plugin": "^5.10.1", 28 | "@typescript-eslint/parser": "^5.10.1", 29 | "aws-sdk": "^2.928.0", 30 | "copy-webpack-plugin": "^10.2.1", 31 | "eslint": "^8.7.0", 32 | "eslint-config-prettier": "^6.3.0", 33 | "eslint-plugin-import": "^2.23.4", 34 | "eslint-plugin-json": "^1.4.0", 35 | "eslint-plugin-jsx-a11y": "^6.2.3", 36 | "eslint-plugin-prettier": "^3.4.0", 37 | "eslint-plugin-react": "^7.24.0", 38 | "file-loader": "^4.2.0", 39 | "fork-ts-checker-webpack-plugin": "^6.5.0", 40 | "html-loader": "^0.5.5", 41 | "mini-css-extract-plugin": "^0.8.0", 42 | "prettier": "^1.18.2", 43 | "source-map-loader": "^0.2.4", 44 | "ts-node": "^9.1.1", 45 | "tsconfig-paths-webpack-plugin": "^3.5.1", 46 | "typescript": "^3.9.9", 47 | "url-loader": "^2.1.0", 48 | "webpack": "^5.76.0", 49 | "webpack-cli": "^4.9.2" 50 | }, 51 | "resolutions": { 52 | "glob-parent": "^5.1.2", 53 | "normalize-url": "^4.5.1", 54 | "ssri": "^8.0.1", 55 | "minimatch": "^3.0.5", 56 | "loader-utils": "^2.0.3", 57 | "json5": "^2.2.2", 58 | "xml2js": "^0.5.0", 59 | "semver": "^7.5.2" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Lambdas/Common/src/index.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | const CORS_HEADERS = { 5 | "Access-Control-Allow-Origin": "*" 6 | }; 7 | 8 | export const respond = (statusCode: number, body: unknown) => 9 | respondRaw(statusCode, JSON.stringify(body)); 10 | 11 | export const respondRaw = (statusCode: number, body: string) => ({ 12 | statusCode, 13 | headers: { 14 | "Content-Type": "application/json", 15 | ...CORS_HEADERS 16 | }, 17 | body 18 | }); 19 | -------------------------------------------------------------------------------- /Lambdas/Common/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2018", 4 | "module": "commonjs", 5 | "lib": ["es2018", "dom"], 6 | "declaration": true, 7 | "outDir": "./dist", 8 | "strict": true, 9 | "noImplicitAny": true, 10 | "strictNullChecks": true, 11 | "noImplicitThis": true, 12 | "alwaysStrict": true, 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "noImplicitReturns": true, 16 | "noFallthroughCasesInSwitch": false, 17 | "inlineSourceMap": true, 18 | "inlineSources": true, 19 | "experimentalDecorators": true, 20 | "strictPropertyInitialization": false, 21 | "typeRoots": ["./node_modules/@types"], 22 | "resolveJsonModule": true 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Lambdas/README.md: -------------------------------------------------------------------------------- 1 | ## Lambdas 2 | 3 | This defines code to be deployed into various lambdas defined by in the `Infra` module. 4 | 5 | Please see the README.md in each package for details of their function. 6 | 7 | ### Development 8 | 9 | #### Building and Testing 10 | 11 | Each lambda package can be built using the following command: 12 | 13 | `yarn && yarn build` 14 | 15 | It's often useful to use a REPL to perform ad-hoc testing. You can spin up a typescript 16 | REPL with all of the dependencies of the package available using the following command: 17 | 18 | `npm run env -- ts-node` 19 | 20 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | ********************** 2 | THIRD PARTY COMPONENTS 3 | ********************** 4 | This software includes third party software subject to the following copyrights: 5 | 6 | AWS CDK under the Apache License Version 2.0 7 | aws-cdk-static-website under the MIT license 8 | 9 | The licenses for these third party components are included in LICENSE.txt -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cross Talk - Amazon Chime SDK Video Chat and AWS AppSync Local Resolver Sample 2 | 3 | ## Overview 4 | This repository contains source code for the full "Cross Talk" video chat Chime SDK sample. 5 | 6 | It consists of three core modules: 7 | 8 | - Infra: This defines the infrastructure as code using the Cloud Development Kit (CDK). 9 | - Lambdas: This contains the code which is deployed into a Lambda function defined in the Infra 10 | - Website: A React website for Cross Talk UI 11 | 12 | This sample aims to demonstrate a number of things: 13 | - Simple useage of the awesome new Chime SDK React components (https://github.com/aws/amazon-chime-sdk-component-library-react). The code in "Website/src/components/ModalChimeDialog.tsx" illustrates this. 14 | - An example of how to use the AppSync "None" data approach to resolvers to provide a direct pub/sub notification system over GraphQL without having persistent storage of the mutations (https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference-none.html). The client-side interaction with AppSync is shown in "Website/src/containers/Home/HomeContainer.tsx", with the AppSync resolvers configured in "Infra/lib/stack/AppSyncStack.ts". The diagram below shows the way the front-end utilises the local resolver to notify GraphQL subscribers of mutations to the local resolver: 15 | 16 |

17 | 18 | In addition to these points, this sample utilises the recently released NorthStar design system (https://northstar.aws-prototyping.cloud/) and the AWS Cloud Development Kit (https://aws.amazon.com/cdk/) for the deployment of all infrastructure. 19 | 20 | The application implements a simple broadcast chat user interface, where a logged in user can initiate a chat with any interested user by clicking on the "Start Chat" button. Other active users will see an alert advertising this chat request (this is implemented using the AppSync local resolver subscription). The first user to accept the chat request will "claim" that invitation, causing the alert to be removed for any other active uers. 21 | 22 | ![Logged in user screenshot](screenshot-a.png) 23 | 24 | The Chime SDK chat dialog that is displayed defaults to having the audio active and video inactive. These can be toggled via the buttons shown in the screenshot below: 25 | 26 | ![screenshot of Chime SDK video chat dialog](screenshot-b.png) 27 | 28 | The key services utilised by this sample are shown in the simple architecture diagram below: 29 | 30 |

31 | 32 | ## Bootstrap/Build/Deploy/Run 33 | Once you have locally cloned this repository, and assuming you have 34 | - an active AWS account 35 | 36 | - installed the current version of the AWS CLI 37 | 38 | - you have NodeJS 18 installed 39 | 40 | - installed the current version of the AWS CLI 41 | 42 | (this can be done by typing "npm i -g aws-cdk" in your preferred shell terminal session) 43 | 44 | ### Bootstrap 45 | You only need to do this one time per environment where you want to deploy CDK applications. 46 | If you’re unsure whether your environment has been bootstrapped already, you can always run 47 | the command again. 48 | 49 | Make sure you have credentials for **ACCOUNT** (replace with your AWS account ID) in a profile 50 | named **account-profile**. For more information, see [Named profiles](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html). 51 | 52 | Run the following commands in the root of the repository directory: 53 | 54 | ```sh 55 | cd Lambdas/Common 56 | yarn 57 | yarn build 58 | 59 | cd ../ChimeCallService 60 | yarn 61 | yarn build 62 | 63 | cd ../../Website 64 | yarn 65 | yarn build 66 | 67 | cd ../Infra 68 | yarn 69 | yarn build 70 | cdk bootstrap \ 71 | --profile account-profile \ 72 | --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess \ 73 | aws://ACCOUNT1/ap-southeast-2 74 | ``` 75 | 76 | ### Build/Deploy 77 | A convenience script is provided to deploy all infrastructure to your environment. This builds 78 | all the lambdas, the website, the infrastructure and then initiates the CDK deployment. From the "Infra" directory, you can run: 79 | 80 | ``` 81 | ./deployStack.sh --profile 82 | ``` 83 | 84 | ### Run 85 | 86 | Once the deployment has finished, you can open the CloudFront URL printed by the deployment script or run from a local Node session. To run a local instance of the React front-end, you will need to grab a copy of the "runtime-config.js" file that the CDK deployment process created (in the S3 static website bucket) and copy it to "Website/public". Note: account self-registration from the sign-in page has been disabled; to register a new account, open the relevant Cognito user pool in the AWS console and create a new user. 87 | 88 | 89 | ## Security 90 | 91 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 92 | 93 | ## License 94 | 95 | This library is licensed under the MIT-0 License. See the [LICENSE](LICENSE.txt) file. 96 | -------------------------------------------------------------------------------- /Website/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | 25 | public/runtime-config.js 26 | -------------------------------------------------------------------------------- /Website/README.md: -------------------------------------------------------------------------------- 1 | # Cross Talk Example Static Website 2 | 3 | ## Overview 4 | 5 | The UI is written in Typescript and makes use of React as the core UI framework, and [NorthStar](https://northstar.aws-prototyping.cloud/) as the primary component library. 6 | 7 | ## Getting Started 8 | 9 | ### Define a local `runtime-config.js` 10 | 11 | The UI requires `runtime-config.js` which specifies configuration values such as the Cognito user pool id. 12 | When the UI is deployed via CDK, the `runtime-config.js` file is automatically generated and added to the 13 | S3 bucket, but when running the UI locally we need a local copy. 14 | 15 | Deploy the sandbox stack using CDK (see the README in the `Infra` directory in the root of this package), find the 16 | S3 bucket the UI was deployed to, and download the `runtime-config.js`, copying it into the `public` directory in this 17 | package. This will point your locally running UI resources in the sandbox stack. 18 | 19 | ### Start the local dev server 20 | 21 | #### `yarn start` 22 | 23 | Runs the app in the development mode.
24 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 25 | 26 | The page will reload if you make edits.
27 | You will also see any lint errors in the console. 28 | 29 | ## Production Build 30 | 31 | #### `yarn && yarn build` 32 | 33 | Builds the app for production to the `build` folder.
34 | It correctly bundles React in production mode and optimizes the build for the best performance. 35 | 36 | The build is minified and the filenames include the hashes.
37 | Your app is ready to be deployed! 38 | 39 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 40 | 41 | ### Eject from `create-react-app` 42 | 43 | #### `yarn eject` 44 | 45 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 46 | 47 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 48 | 49 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 50 | 51 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 52 | 53 | ## Learn More 54 | 55 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 56 | 57 | To learn React, check out the [React documentation](https://reactjs.org/). 58 | -------------------------------------------------------------------------------- /Website/config-overrides.js: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | // ... so the webpack5 config used by react-scripts 5.0.0 5 | // doesn't like .mjs files, so we use react-scripts-rewire 6 | // to add support for this (the aws appsync modules, for 7 | // example, need this) 8 | // See: https://github.com/graphql/graphql-js/issues/2721 9 | 10 | module.exports = function override(config) { 11 | config.module.rules.push({ 12 | test: /\.m?js/, 13 | resolve: { 14 | fullySpecified: false, 15 | fallback: { 16 | crypto: false 17 | } 18 | } 19 | }); 20 | 21 | config.ignoreWarnings = [/Failed to parse source map/]; 22 | return config; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /Website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@aws-samples/crosstalk-website", 3 | "version": "1.0.0", 4 | "license": "MIT-0", 5 | "private": true, 6 | "dependencies": { 7 | "@aws-amplify/ui-react": "^1.2.2", 8 | "@aws-sdk/types": "^1.0.0-rc.10", 9 | "@aws-sdk/util-utf8-browser": "^1.0.0-rc.8", 10 | "@aws-sdk/util-utf8-node": "^1.0.0-rc.8", 11 | "@material-ui/core": "^4.11.4", 12 | "@material-ui/icons": "^4.11.2", 13 | "@types/react": "^16.14.8", 14 | "@types/react-dom": "^16.9.13", 15 | "@types/react-router-dom": "^5.1.7", 16 | "@types/styled-components": "^5.1.10", 17 | "amazon-chime-sdk-component-library-react": "^1.6.1", 18 | "amazon-chime-sdk-js": "^2.11.0", 19 | "aws-amplify": "^3.4.3", 20 | "aws-appsync": "^4.0.3", 21 | "aws-northstar": "^1.1.11", 22 | "aws-sdk": "^2.928.0", 23 | "axios": "^0.28.0", 24 | "graphql-tag": "^2.12.4", 25 | "install": "^0.13.0", 26 | "npm": "^8.11.0", 27 | "query-string": "^6.14.1", 28 | "react": "^16.13.1", 29 | "react-dom": "^16.13.1", 30 | "react-router-dom": "^5.2.0", 31 | "react-scripts": "^5.0.0", 32 | "styled-components": "^5.3.0", 33 | "styled-system": "^5.1.5", 34 | "typescript": "3.9.7" 35 | }, 36 | "devDependencies": { 37 | "@types/node": "^12.20.15", 38 | "browserslist": "^4.16.6", 39 | "react-app-rewired": "^2.1.11" 40 | }, 41 | "resolutions": { 42 | "axios": "^0.28.0", 43 | "ansi-regex": "^5.0.1", 44 | "node-forge": "^1.0.0", 45 | "nth-check": "^2.0.1", 46 | "glob-parent": "^5.1.2", 47 | "browserslist": "^4.16.5", 48 | "postcss": "^8.2.1", 49 | "immer": "^9.0.6", 50 | "follow-redirects": "^1.14.8", 51 | "prismjs": "^1.27.0", 52 | "async": "^2.6.4", 53 | "ejs": "^3.1.7", 54 | "protobufjs": "^6.11.3", 55 | "d3-color": "^3.1.0", 56 | "minimatch": "^3.0.5", 57 | "loader-utils": "^2.0.3", 58 | "json5": "^2.2.2", 59 | "xml2js": "^0.5.0", 60 | "fast-xml-parser": "^4.2.5", 61 | "semver": "^7.5.2" 62 | }, 63 | "scripts": { 64 | "start": "react-app-rewired start", 65 | "build": "react-app-rewired build", 66 | "eject": "react-app-rewired eject" 67 | }, 68 | "eslintConfig": { 69 | "extends": [ 70 | "react-app", 71 | "react-app/jest" 72 | ] 73 | }, 74 | "browserslist": { 75 | "production": [ 76 | ">0.2%", 77 | "not dead", 78 | "not op_mini all" 79 | ], 80 | "development": [ 81 | "last 1 chrome version", 82 | "last 1 firefox version", 83 | "last 1 safari version" 84 | ] 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /Website/public/index.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 16 | 17 | 21 | 22 | 31 | Cross Talk 32 | 33 | 34 | 35 | 36 | 37 | 38 |
39 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Website/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: / 4 | -------------------------------------------------------------------------------- /Website/src/api/ChimeCallServiceClient.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { sigv4SignedGet } from "./api"; 5 | 6 | const { 7 | apiUrl, 8 | // @ts-ignore 9 | } = window["runConfig"]; 10 | 11 | /** 12 | * Client for the patient diagnostic and connect query service, responsible 13 | * for further interaction from the diagnostic and contact card 14 | */ 15 | export class ChimeCallServiceClient { 16 | async createChimeSession(): Promise { 17 | try { 18 | const response = await sigv4SignedGet(`${apiUrl}call-create`); 19 | return await response.json(); 20 | } catch (e) { 21 | console.error(e); 22 | return undefined; 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /Website/src/api/api.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import { Auth, Signer } from "aws-amplify"; 5 | 6 | // @ts-ignore 7 | const { region } = window["runConfig"]; 8 | 9 | /** 10 | * Send a Signature Version 4 Signed GET request to the given url. Uses the current authenticated/unauthenticated user's 11 | * credentials 12 | */ 13 | export const sigv4SignedGet = async (url: string) => { 14 | const credentials = await Auth.currentCredentials(); 15 | 16 | const requestUrl = Signer.signUrl( 17 | url, 18 | { 19 | access_key: credentials.accessKeyId, 20 | secret_key: credentials.secretAccessKey, 21 | session_token: credentials.sessionToken, 22 | }, 23 | { region, service: "execute-api" } 24 | ); 25 | 26 | return await fetch(requestUrl); 27 | }; 28 | 29 | /** 30 | * Send a Signature Version 4 Signed request to the given url 31 | * @param url the url to send the request to 32 | * @param method the http method to use, PUT, POST etc 33 | * @param headers http headers to include in the request 34 | * @param body the body of the request 35 | */ 36 | export const sigv4SignedRequest = async ( 37 | url: string, 38 | method: string, 39 | headers: { [key: string]: string }, 40 | body: string 41 | ) => { 42 | const credentials = await Auth.currentCredentials(); 43 | 44 | const request = Signer.sign( 45 | { 46 | url, 47 | headers, 48 | method, 49 | data: body, 50 | }, 51 | { 52 | access_key: credentials.accessKeyId, 53 | secret_key: credentials.secretAccessKey, 54 | session_token: credentials.sessionToken, 55 | }, 56 | { region, service: "execute-api" } 57 | ); 58 | 59 | return await fetch(url, { 60 | ...request, 61 | body, 62 | }); 63 | }; 64 | 65 | /** 66 | * Send a Signature Version 4 Signed request to the given url, with a JSON payload 67 | */ 68 | export const sigv4SignedJsonRequest = (url: string, method: string, data: any) => { 69 | return sigv4SignedRequest( 70 | url, 71 | method, 72 | { 73 | "Content-Type": "application/json", 74 | }, 75 | JSON.stringify(data) 76 | ); 77 | }; 78 | 79 | export const sigv4SignedJsonPost = (url: string, data: any) => sigv4SignedJsonRequest(url, "POST", data); 80 | 81 | export const sigv4SignedJsonPut = (url: string, data: any) => sigv4SignedJsonRequest(url, "PUT", data); 82 | -------------------------------------------------------------------------------- /Website/src/components/Controls/ModalChimeDialog.tsx: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import React from "react"; 5 | 6 | import { 7 | PreviewVideo, 8 | RemoteVideo, 9 | useLocalVideo, 10 | useRemoteVideoTileState, 11 | useToggleLocalMute 12 | } from "amazon-chime-sdk-component-library-react"; 13 | 14 | import { 15 | Box, 16 | Button, 17 | Grid, 18 | Modal, 19 | Toggle 20 | } from "aws-northstar"; 21 | 22 | import Text from 'aws-northstar/components/Text'; 23 | 24 | interface ModalChimeDialogProperties { 25 | onEndCall: any; 26 | infoPanel?: React.ReactNode; 27 | } 28 | 29 | /** 30 | * This component is the initial implementation of a chime sdk chat interface - 31 | * with only very basic controls at this stage 32 | * 33 | * @param onEndCall - function object invoked when the user leaves the chime session 34 | */ 35 | const ModalChimeDialog: React.FC = ({ onEndCall, infoPanel }) => { 36 | const { toggleVideo, isVideoEnabled } = useLocalVideo(); 37 | const { muted, toggleMute } = useToggleLocalMute(); 38 | const { tiles } = useRemoteVideoTileState(); 39 | 40 | const videos = tiles.map((tileId) => ( 41 |
42 | 43 |
44 | )); 45 | 46 | return ( 47 | 48 | 49 | 50 |
51 | {tiles.length ? videos : 52 | 53 | No remote video available 54 | } 55 |
56 |
57 | {isVideoEnabled ? : 58 | 59 | Video disabled 60 | } 61 |
62 |
63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
79 | { infoPanel ?
: null} 80 | { infoPanel ? {infoPanel} : null} 81 |
82 | ) 83 | } 84 | 85 | export default ModalChimeDialog; 86 | -------------------------------------------------------------------------------- /Website/src/containers/App/index.tsx: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import React, { useState } from "react"; 5 | import HomeContainer from "../Home/HomeContainer"; 6 | import { withAuthenticator } from "@aws-amplify/ui-react"; 7 | import { ThemeProvider } from "styled-components"; 8 | import { darkTheme, MeetingProvider } from "amazon-chime-sdk-component-library-react"; 9 | import { AmplifyAuthenticator, AmplifySignIn } from '@aws-amplify/ui-react'; 10 | import { 11 | AppLayout, 12 | ButtonDropdown, 13 | Header, 14 | NorthStarThemeProvider, 15 | } from 'aws-northstar'; 16 | import Amplify, { Auth } from 'aws-amplify'; 17 | import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; 18 | 19 | const menuItems = [ 20 | { 21 | text: "Sign Out", 22 | onClick: async () => { 23 | await Auth.signOut(); 24 | window.location.reload(); 25 | }, 26 | }, 27 | ]; 28 | 29 | const { 30 | region, 31 | userPoolId, 32 | userPoolWebClientId, 33 | identityPoolId, 34 | graphqlEndpoint, 35 | // @ts-ignore 36 | } = window["runConfig"]; 37 | 38 | const awsConfig = { 39 | Auth: { 40 | region, 41 | userPoolId, 42 | userPoolWebClientId, 43 | identityPoolId, 44 | }, 45 | aws_appsync_graphqlEndpoint: graphqlEndpoint, 46 | aws_appsync_region: region, 47 | }; 48 | 49 | // Set up cognito auth, and configure our api endpoint 50 | Amplify.configure(awsConfig); 51 | 52 | const App: React.FC = () => { 53 | const [user, setUser] = useState(); 54 | 55 | const rightContent = ; 56 | 57 | return ( 58 | { 60 | try { 61 | setUser(await Auth.currentAuthenticatedUser()); 62 | } catch (err) { 63 | setUser(undefined); 64 | } 65 | }} 66 | > 67 | 68 |
69 |
70 |
71 | 72 | {user ? ( 73 | 74 | 75 | 76 | 77 | 83 | } 84 | > 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | ) : ( 94 | <> 95 | )} 96 |
97 | ); 98 | }; 99 | 100 | // Temporarily restrict access via a login page. For unauthenticated 101 | // access, replace with the commented line below 102 | export default withAuthenticator(App); 103 | -------------------------------------------------------------------------------- /Website/src/containers/Home/HomeContainer.tsx: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import React, { useEffect, useMemo, useState } from "react"; 5 | import { Alert, Button, Card, ColumnLayout, Inline, Stack } from "aws-northstar"; 6 | import { Auth } from "aws-amplify"; 7 | import { ChimeCallServiceClient } from "../../api/ChimeCallServiceClient"; 8 | import { useMeetingManager } from "amazon-chime-sdk-component-library-react"; 9 | import ModalChimeDialog from "../../components/Controls/ModalChimeDialog"; 10 | import AWSAppSyncClient from "aws-appsync"; 11 | import gql from "graphql-tag"; 12 | import VideoCallOutlined from '@material-ui/icons/VideoCallOutlined'; 13 | 14 | const { 15 | region, 16 | graphqlEndpoint, 17 | // @ts-ignore 18 | } = window["runConfig"]; 19 | 20 | const chimeSessionStartedSubscription = gql(` 21 | subscription chimeSessionStarted { 22 | chimeSessionStarted { 23 | meeting 24 | attendee 25 | username 26 | } 27 | } 28 | `); 29 | 30 | const chimeSessionClaimedSubscription = gql(` 31 | subscription chimeSessionClaimed { 32 | chimeSessionClaimed 33 | } 34 | `); 35 | 36 | // define stub-mutation to notify other sessions of new chime call 37 | const chimeSessionMutation = gql(` 38 | mutation startChimeSession($meeting: String!, $attendee: String!, $username: String!) { 39 | startChimeSession(meeting: $meeting, attendee: $attendee, username: $username) { 40 | meeting 41 | attendee 42 | username 43 | } 44 | } 45 | `); 46 | 47 | // define stub-mutation to notify other sessions of new chime call 48 | const claimChimeSessionMutation = gql(` 49 | mutation claimChimeSession($meeting: String!) { 50 | claimChimeSession(meeting: $meeting) 51 | } 52 | `); 53 | 54 | /** 55 | * Component for the main homepage 56 | */ 57 | const HomeContainer: React.FC = () => { 58 | const chimeServiceProvider = useMemo(() => new ChimeCallServiceClient(), []); 59 | const meetingManager = useMeetingManager(); 60 | const [showChimeChat, setShowChimeChat] = useState(false); 61 | const [newChimeSessionAvailable, setNewChimeSessionAvailable] = useState(false); 62 | const [currentMeeting, setCurrentMeeting] = useState(); 63 | const [currentAttendee, setCurrentAttendee] = useState(); 64 | const [callStarting, setCallStarting] = useState(false); 65 | const [appSyncClient, setAppSyncClient] = useState(); 66 | const [meetingSubscription, setMeetingSubscription] = useState(); 67 | const [claimedSubscription, setClaimedSubscription] = useState(); 68 | const [username, setUsername] = useState(); 69 | const [otherUsername, setOtherUsername] = useState(); 70 | 71 | const finishChimeCall = () => { 72 | meetingManager.leave(); 73 | setShowChimeChat(false); 74 | }; 75 | 76 | // workaround: complex types defined outside of graphql need 77 | // to be passed to mutations as json strings...except that 78 | // true json will be auto-boxed to an object, so we disguise 79 | // this as 'vanilla' string by replacing double quotes with 80 | // single quotes 81 | const graphqlify = (data: any) => { 82 | return JSON.stringify(data).replace(new RegExp('"', "g"), "'"); 83 | }; 84 | 85 | const joinChimeCall = async () => { 86 | const joinData = { 87 | meetingInfo: currentMeeting, 88 | attendeeInfo: currentAttendee, 89 | }; 90 | 91 | // Use the join API to create a meeting session 92 | await meetingManager.join(joinData); 93 | 94 | // At this point you can let users setup their devices, or start the session immediately 95 | await meetingManager.start(); 96 | 97 | setNewChimeSessionAvailable(false); 98 | setShowChimeChat(true); 99 | try { 100 | await appSyncClient.mutate({ 101 | mutation: claimChimeSessionMutation, 102 | variables: { 103 | meeting: graphqlify(currentMeeting), 104 | }, 105 | }); 106 | } catch (err) { 107 | console.log("err", err); 108 | } 109 | }; 110 | 111 | const startChimeCall = async () => { 112 | setCallStarting(true); 113 | 114 | const createChimeResult: any = await chimeServiceProvider.createChimeSession(); 115 | const meeting = createChimeResult.Meeting; 116 | const attendee = createChimeResult.Caller; 117 | 118 | const joinData = { 119 | meetingInfo: meeting, 120 | attendeeInfo: attendee, 121 | }; 122 | 123 | // Use the join API to create a meeting session 124 | await meetingManager.join(joinData); 125 | 126 | // At this point you can let users setup their devices, or 127 | // start the session immediately 128 | await meetingManager.start(); 129 | 130 | setShowChimeChat(true); 131 | setCallStarting(false); 132 | 133 | // notify logged-in users of a user wanting to chat via a 134 | // dummy graphql mutation - pass the meeting details as 135 | // stringified json 136 | try { 137 | await appSyncClient.mutate({ 138 | mutation: chimeSessionMutation, 139 | variables: { 140 | meeting: graphqlify(meeting), 141 | attendee: graphqlify(createChimeResult.Callee), 142 | username: "'" + username + "'", 143 | }, 144 | }); 145 | } catch (err) { 146 | console.log("err", err); 147 | } 148 | }; 149 | 150 | const onChimeSessionStarted = (event: any) => { 151 | const meeting = JSON.parse(event.data.chimeSessionStarted.meeting.replace(/'/g, '"')); 152 | const attendee = JSON.parse(event.data.chimeSessionStarted.attendee.replace(/'/g, '"')); 153 | const otherUsername = event.data.chimeSessionStarted.username.replace(/'/g, ''); 154 | 155 | setCurrentMeeting(meeting); 156 | setCurrentAttendee(attendee); 157 | setOtherUsername(otherUsername); 158 | setNewChimeSessionAvailable(true); 159 | }; 160 | 161 | const onChimeSessionClaimed = (event: any) => { 162 | setNewChimeSessionAvailable(false); 163 | }; 164 | 165 | useEffect(() => { 166 | (async () => { 167 | try { 168 | if (!username) { 169 | const user = await Auth.currentAuthenticatedUser(); 170 | setUsername(user.getUsername()); 171 | } 172 | } catch (e) { 173 | // No user currently logged in 174 | } 175 | })(); 176 | 177 | if (!callStarting && !showChimeChat) { 178 | const client = new AWSAppSyncClient({ 179 | url: graphqlEndpoint, 180 | region: region, 181 | disableOffline: true, 182 | auth: { 183 | type: "AMAZON_COGNITO_USER_POOLS", 184 | jwtToken: async () => (await Auth.currentSession()).getAccessToken().getJwtToken(), 185 | }, 186 | complexObjectsCredentials: async () => await Auth.currentCredentials(), 187 | }); 188 | 189 | client.hydrated().then(() => { 190 | const observable = client.subscribe({ 191 | query: chimeSessionStartedSubscription, 192 | }); 193 | const subscription = observable.subscribe({ 194 | next: onChimeSessionStarted, 195 | complete: console.log, 196 | error: console.log, 197 | }); 198 | setMeetingSubscription(subscription); 199 | 200 | if (!claimedSubscription) { 201 | const callClaimedObservable = client.subscribe({ 202 | query: chimeSessionClaimedSubscription, 203 | }); 204 | const callClaimedSubscription = callClaimedObservable.subscribe({ 205 | next: onChimeSessionClaimed, 206 | complete: console.log, 207 | error: console.log, 208 | }); 209 | setClaimedSubscription(callClaimedSubscription); 210 | } 211 | 212 | setAppSyncClient(client); 213 | }); 214 | } else { 215 | if (meetingSubscription) meetingSubscription.unsubscribe(); 216 | } 217 | // don't want to do updates for 'claimedSubscription', 'meetingSubscription', and 'username' 218 | // eslint-disable-next-line 219 | }, [callStarting, showChimeChat]); 220 | 221 | return ( 222 | 223 | 224 | 225 | {newChimeSessionAvailable && !showChimeChat ? ( 226 | setNewChimeSessionAvailable(false)} 231 | onButtonClick={joinChimeCall} 232 | > 233 | Incomming video call 234 | 235 | ) : null} 236 | 237 | 242 | 243 | 250 | 251 | {showChimeChat ? : null} 252 | 253 | 254 | 255 | ); 256 | }; 257 | 258 | export default HomeContainer; 259 | -------------------------------------------------------------------------------- /Website/src/index.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | */ 5 | 6 | body { 7 | margin: 0; 8 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 9 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 10 | sans-serif; 11 | -webkit-font-smoothing: antialiased; 12 | -moz-osx-font-smoothing: grayscale; 13 | } 14 | 15 | code { 16 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 17 | monospace; 18 | } 19 | 20 | :focus { 21 | outline: none; 22 | } 23 | 24 | a.MuiButtonBase-root.MuiButton-root.MuiButton-text { 25 | border-color: black; 26 | } 27 | -------------------------------------------------------------------------------- /Website/src/index.tsx: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | import React from "react"; 5 | import ReactDOM from "react-dom"; 6 | import "./index.css"; 7 | import App from "./containers/App"; 8 | import * as serviceWorker from "./serviceWorker"; 9 | 10 | 11 | import Amplify from 'aws-amplify'; 12 | 13 | const { region, userPoolId, userPoolWebClientId, identityPoolId } = 14 | // @ts-ignore 15 | window['runConfig']; 16 | 17 | Amplify.configure({ 18 | Auth: { 19 | region: region, 20 | userPoolId: userPoolId, 21 | userPoolWebClientId: userPoolWebClientId, 22 | identityPoolId: identityPoolId, 23 | } 24 | }); 25 | 26 | ReactDOM.render( 27 | 28 | 29 | , 30 | document.getElementById("root") 31 | ); 32 | 33 | // If you want your app to work offline and load faster, you can change 34 | // unregister() to register() below. Note this comes with some pitfalls. 35 | // Learn more about service workers: https://bit.ly/CRA-PWA 36 | serviceWorker.unregister(); 37 | -------------------------------------------------------------------------------- /Website/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /Website/src/serviceWorker.ts: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | // This optional code is used to register a service worker. 5 | // register() is not called by default. 6 | 7 | // This lets the app load faster on subsequent visits in production, and gives 8 | // it offline capabilities. However, it also means that developers (and users) 9 | // will only see deployed updates on subsequent visits to a page, after all the 10 | // existing tabs open on the page have been closed, since previously cached 11 | // resources are updated in the background. 12 | 13 | // To learn more about the benefits of this model and instructions on how to 14 | // opt-in, read https://bit.ly/CRA-PWA 15 | 16 | const isLocalhost = Boolean( 17 | window.location.hostname === "localhost" || 18 | // [::1] is the IPv6 localhost address. 19 | window.location.hostname === "[::1]" || 20 | // 127.0.0.0/8 are considered localhost for IPv4. 21 | window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/) 22 | ); 23 | 24 | type Config = { 25 | onSuccess?: (registration: ServiceWorkerRegistration) => void; 26 | onUpdate?: (registration: ServiceWorkerRegistration) => void; 27 | }; 28 | 29 | export function register(config?: Config) { 30 | if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { 31 | // The URL constructor is available in all browsers that support SW. 32 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 33 | if (publicUrl.origin !== window.location.origin) { 34 | // Our service worker won't work if PUBLIC_URL is on a different origin 35 | // from what our page is served on. This might happen if a CDN is used to 36 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 37 | return; 38 | } 39 | 40 | window.addEventListener("load", () => { 41 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 42 | 43 | if (isLocalhost) { 44 | // This is running on localhost. Let's check if a service worker still exists or not. 45 | checkValidServiceWorker(swUrl, config); 46 | 47 | // Add some additional logging to localhost, pointing developers to the 48 | // service worker/PWA documentation. 49 | navigator.serviceWorker.ready.then(() => { 50 | console.log( 51 | "This web app is being served cache-first by a service " + 52 | "worker. To learn more, visit https://bit.ly/CRA-PWA" 53 | ); 54 | }); 55 | } else { 56 | // Is not localhost. Just register service worker 57 | registerValidSW(swUrl, config); 58 | } 59 | }); 60 | } 61 | } 62 | 63 | function registerValidSW(swUrl: string, config?: Config) { 64 | navigator.serviceWorker 65 | .register(swUrl) 66 | .then((registration) => { 67 | registration.onupdatefound = () => { 68 | const installingWorker = registration.installing; 69 | if (installingWorker == null) { 70 | return; 71 | } 72 | installingWorker.onstatechange = () => { 73 | if (installingWorker.state === "installed") { 74 | if (navigator.serviceWorker.controller) { 75 | // At this point, the updated precached content has been fetched, 76 | // but the previous service worker will still serve the older 77 | // content until all client tabs are closed. 78 | console.log( 79 | "New content is available and will be used when all " + 80 | "tabs for this page are closed. See https://bit.ly/CRA-PWA." 81 | ); 82 | 83 | // Execute callback 84 | if (config && config.onUpdate) { 85 | config.onUpdate(registration); 86 | } 87 | } else { 88 | // At this point, everything has been precached. 89 | // It's the perfect time to display a 90 | // "Content is cached for offline use." message. 91 | console.log("Content is cached for offline use."); 92 | 93 | // Execute callback 94 | if (config && config.onSuccess) { 95 | config.onSuccess(registration); 96 | } 97 | } 98 | } 99 | }; 100 | }; 101 | }) 102 | .catch((error) => { 103 | console.error("Error during service worker registration:", error); 104 | }); 105 | } 106 | 107 | function checkValidServiceWorker(swUrl: string, config?: Config) { 108 | // Check if the service worker can be found. If it can't reload the page. 109 | fetch(swUrl, { 110 | headers: { "Service-Worker": "script" }, 111 | }) 112 | .then((response) => { 113 | // Ensure service worker exists, and that we really are getting a JS file. 114 | const contentType = response.headers.get("content-type"); 115 | if (response.status === 404 || (contentType != null && contentType.indexOf("javascript") === -1)) { 116 | // No service worker found. Probably a different app. Reload the page. 117 | navigator.serviceWorker.ready.then((registration) => { 118 | registration.unregister().then(() => { 119 | window.location.reload(); 120 | }); 121 | }); 122 | } else { 123 | // Service worker found. Proceed as normal. 124 | registerValidSW(swUrl, config); 125 | } 126 | }) 127 | .catch(() => { 128 | console.log("No internet connection found. App is running in offline mode."); 129 | }); 130 | } 131 | 132 | export function unregister() { 133 | if ("serviceWorker" in navigator) { 134 | navigator.serviceWorker.ready 135 | .then((registration) => { 136 | registration.unregister(); 137 | }) 138 | .catch((error) => { 139 | console.error(error.message); 140 | }); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /Website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "noEmit": true, 20 | "jsx": "react", 21 | "noFallthroughCasesInSwitch": true 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /appsync-sequence-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-chime-sdk-aws-appsync-sample/31c0df83f484bd08bf85233ce86c79c2d10f0ddd/appsync-sequence-diagram.png -------------------------------------------------------------------------------- /architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-chime-sdk-aws-appsync-sample/31c0df83f484bd08bf85233ce86c79c2d10f0ddd/architecture.png -------------------------------------------------------------------------------- /screenshot-a.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-chime-sdk-aws-appsync-sample/31c0df83f484bd08bf85233ce86c79c2d10f0ddd/screenshot-a.png -------------------------------------------------------------------------------- /screenshot-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/amazon-chime-sdk-aws-appsync-sample/31c0df83f484bd08bf85233ce86c79c2d10f0ddd/screenshot-b.png --------------------------------------------------------------------------------