diff --git a/.all-contributorsrc b/.all-contributorsrc index e76869e7..a96c9411 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -632,6 +632,15 @@ "contributions": [ "code" ] + }, + { + "login": "nvanlo", + "name": "Nik Van Looy", + "avatar_url": "https://avatars.githubusercontent.com/u/68108702?v=4", + "profile": "https://github.com/nvanlo", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7 diff --git a/.gitignore b/.gitignore index 9c5ae359..e8c772fa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ node_modules npm-debug.log yarn-error.json +yarn-error.log users.json # serverless zip diff --git a/README.md b/README.md index 0c47e210..cffd2ba1 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![Tests](https://github.com/sid88in/serverless-appsync-plugin/workflows/Tests/badge.svg)](https://github.com/sid88in/serverless-appsync-plugin/actions?query=workflow%3ATests) -[![All Contributors](https://img.shields.io/badge/all_contributors-69-orange.svg?style=flat-square)](#contributors-) +[![All Contributors](https://img.shields.io/badge/all_contributors-70-orange.svg?style=flat-square)](#contributors-) Deploy [AppSync](https://aws.amazon.com/appsync) API's in minutes using this [Serverless](https://www.serverless.com/) plugin. @@ -8,14 +8,14 @@ Deploy [AppSync](https://aws.amazon.com/appsync) API's in minutes using this [Se Be sure to check out all that [AWS AppSync](https://aws.amazon.com/appsync) has to offer. Here are a few resources to help you understand everything needed to get started! -* [Mapping Templates](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference.html) - Not sure how to create Mapping Templates for **DynamoDB**, **Lambda** or **Elasticsearch**? Here's a great place to start! -* [Data Sources and Resolvers](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials.html) - Get more information on what data sources are supported and how to set them up! -* [Security](https://docs.aws.amazon.com/appsync/latest/devguide/security.html) - Checkout this guide to find out more information on securing your API endpoints with AWS_IAM or Cognito User Pools! +- [Mapping Templates](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-mapping-template-reference.html) - Not sure how to create Mapping Templates for **DynamoDB**, **Lambda** or **Elasticsearch**? Here's a great place to start! +- [Data Sources and Resolvers](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials.html) - Get more information on what data sources are supported and how to set them up! +- [Security](https://docs.aws.amazon.com/appsync/latest/devguide/security.html) - Checkout this guide to find out more information on securing your API endpoints with AWS_IAM or Cognito User Pools! # Minimum requirements -* [Node.js v8 or higher](https://nodejs.org) -* [Serverless v1.30.0 or higher](https://github.com/serverless/serverless) +- [Node.js v8 or higher](https://nodejs.org) +- [Serverless v1.30.0 or higher](https://github.com/serverless/serverless) # Installation & Configuration @@ -33,19 +33,22 @@ npm install serverless-appsync-plugin ## Configuring the plugin -Add ```serverless-appsync-plugin``` to the plugins section of ```serverless.yml``` +Add `serverless-appsync-plugin` to the plugins section of `serverless.yml` ``` plugins: - serverless-appsync-plugin ``` -Add the following config to the custom section of ```serverless.yml``` and update it accordingly to your needs +Add the following config to the custom section of `serverless.yml` and update it accordingly to your needs ```yaml custom: appSync: - name: # defaults to api + name: # defaults to api + domain: # custom domain. See the Custom Domains section below + name: api.example.com + certificateArn: arn:aws:acm:us-east-1123456789:certificate/1c4e4c36-9a63-4685-94b7-e873402baca3 # apiKey # only required for update-appsync/delete-appsync # apiId # if provided, will update the specified API. authenticationType: API_KEY or AWS_IAM or AMAZON_COGNITO_USER_POOLS or OPENID_CONNECT or AWS_LAMBDA @@ -64,7 +67,7 @@ custom: awsRegion: # defaults to provider region defaultAction: # required # ALLOW or DENY userPoolId: # required # user pool ID - appIdClientRegex: # optional + appIdClientRegex: # optional # if AWS_LAMBDA lambdaAuthorizerConfig: functionName: # The function name in your serverless.yml. Ignored if lambdaFunctionArn is provided. @@ -111,7 +114,7 @@ custom: logConfig: loggingRoleArn: { Fn::GetAtt: [AppSyncLoggingServiceRole, Arn] } # Where AppSyncLoggingServiceRole is a role with CloudWatch Logs write access level: ERROR # Logging Level: NONE | ERROR | ALL - excludeVerboseContent: false + excludeVerboseContent: false # Bool, Optional. Enable ExcludeVerboseContent. disabled by default(= Include verbose content in logs is default). defaultMappingTemplates: # default templates. Useful for Lambda templates that are often repetitive. Will be used if the template is not specified in a resolver request: my.request.template.tpl # or, e.g: false for Direct lambdas response: my.response.template.tpl # or e.g.: false for Direct lambdas @@ -122,9 +125,10 @@ custom: field: getUserInfo # kind: UNIT (default, not required) or PIPELINE (required for pipeline resolvers) functions: # array of functions if kind === 'PIPELINE' - - # function name + - # function name request: # request mapping template name | defaults to `defaultMappingTemplates.request` or {type}.{field}.request.vtl response: # response mapping template name | defaults to `defaultMappingTemplates.response` or {type}.{field}.response.vtl + maxBatchSize: # maximum number of requests for BatchInvoke operations # When caching is enaled with `PER_RESOLVER_CACHING`, # the caching options of the resolver. # Disabled by default. @@ -136,8 +140,8 @@ custom: # $context.arguments and $context.identity caching: keys: # array. A list of VTL variables to use as cache key. - - "$context.identity.sub" - - "$context.arguments.id" + - '$context.identity.sub' + - '$context.arguments.id' ttl: 1000 # override the ttl for this resolver. (default comes from global config) # When versioning is enabled with `versioned` on the datasource, # the datasync options of the resolver. @@ -153,7 +157,7 @@ custom: conflictDetection: VERSION # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appsync-resolver-syncconfig.html conflictHandler: OPTIMISTIC_CONCURRENCY # when not using lambda conflict handler choose The Conflict Resolution strategy to perform in the event of a conflict. OPTIMISTIC_CONCURRENCY / AUTOMERGE / LAMBDA functionName: graphql # The function name in your serverless.yml. Ignored if lambdaFunctionArn is provided. - lambdaFunctionArn: "arn:aws:lambda:{REGION}:{ACCOUNT_ID}:myFunction" + lambdaFunctionArn: 'arn:aws:lambda:{REGION}:{ACCOUNT_ID}:myFunction' - ${file({fileLocation}.yml)} # link to a file with arrays of mapping templates functionConfigurationsLocation: # defaults to mappingTemplatesLocation (mapping-templates) @@ -162,6 +166,7 @@ custom: dataSource: # data source name request: # request mapping template name | defaults to {name}.request.vtl response: # reponse mapping template name | defaults to {name}.response.vtl + maxBatchSize: # maximum number of requests for BatchInvoke operations dataSources: - type: NONE name: none @@ -172,12 +177,12 @@ custom: tableName: { Ref: MyTable } # Where MyTable is a dynamodb table defined in Resources serviceRoleArn: { Fn::GetAtt: [AppSyncDynamoDBServiceRole, Arn] } # Where AppSyncDynamoDBServiceRole is an IAM role defined in Resources iamRoleStatements: # custom IAM Role statements for this DataSource. Ignored if `serviceRoleArn` is present. Auto-generated if both `serviceRoleArn` and `iamRoleStatements` are omitted - - Effect: "Allow" + - Effect: 'Allow' Action: - - "dynamodb:GetItem" + - 'dynamodb:GetItem' Resource: - - "arn:aws:dynamodb:{REGION}:{ACCOUNT_ID}:myTable" - - "arn:aws:dynamodb:{REGION}:{ACCOUNT_ID}:myTable/*" + - 'arn:aws:dynamodb:{REGION}:{ACCOUNT_ID}:myTable' + - 'arn:aws:dynamodb:{REGION}:{ACCOUNT_ID}:myTable/*' # Versioned DataSource configuration versioned: false # (default, not required) # When you enable versioning on a DynamoDB data source, you specify the following fields @@ -198,23 +203,23 @@ custom: databaseName: # optional database name schema: # optional database schema iamRoleStatements: # custom IAM Role statements for this DataSource. Ignored if `serviceRoleArn` is present. Auto-generated if both `serviceRoleArn` and `iamRoleStatements` are omitted - - Effect: "Allow" + - Effect: 'Allow' Action: - - "rds-data:DeleteItems" - - "rds-data:ExecuteSql" - - "rds-data:ExecuteStatement" - - "rds-data:GetItems" - - "rds-data:InsertItems" - - "rds-data:UpdateItems" + - 'rds-data:DeleteItems' + - 'rds-data:ExecuteSql' + - 'rds-data:ExecuteStatement' + - 'rds-data:GetItems' + - 'rds-data:InsertItems' + - 'rds-data:UpdateItems' Resource: - - "arn:aws:rds:{REGION}:{ACCOUNT_ID}:cluster:mydbcluster" - - "arn:aws:rds:{REGION}:{ACCOUNT_ID}:cluster:mydbcluster:*" - - Effect: "Allow" + - 'arn:aws:rds:{REGION}:{ACCOUNT_ID}:cluster:mydbcluster' + - 'arn:aws:rds:{REGION}:{ACCOUNT_ID}:cluster:mydbcluster:*' + - Effect: 'Allow' Action: - - "secretsmanager:GetSecretValue" + - 'secretsmanager:GetSecretValue' Resource: - - "arn:aws:secretsmanager:{REGION}:{ACCOUNT_ID}:secret:mysecret" - - "arn:aws:secretsmanager:{REGION}:{ACCOUNT_ID}:secret:mysecret:*" + - 'arn:aws:secretsmanager:{REGION}:{ACCOUNT_ID}:secret:mysecret' + - 'arn:aws:secretsmanager:{REGION}:{ACCOUNT_ID}:secret:mysecret:*' region: # Overwrite default region for this data source - type: AMAZON_ELASTICSEARCH @@ -225,11 +230,11 @@ custom: endpoint: # required if `domain` not provided. Ex: "https://{XXX}.{REGION}.es.amazonaws.com" serviceRoleArn: { Fn::GetAtt: [AppSyncESServiceRole, Arn] } # Where AppSyncESServiceRole is an IAM role defined in Resources iamRoleStatements: # custom IAM Role statements for this DataSource. Ignored if `serviceRoleArn` is present. Auto-generated if both `serviceRoleArn` and `iamRoleStatements` are omitted - - Effect: "Allow" + - Effect: 'Allow' Action: - - "es:ESHttpGet" + - 'es:ESHttpGet' Resource: - - "arn:aws:es:{REGION}:{ACCOUNT_ID}:{DOMAIN}" + - 'arn:aws:es:{REGION}:{ACCOUNT_ID}:{DOMAIN}' - type: AWS_LAMBDA name: # data source name description: 'Lambda DataSource' @@ -238,12 +243,12 @@ custom: lambdaFunctionArn: { Fn::GetAtt: [GraphqlLambdaFunction, Arn] } # Where GraphqlLambdaFunction is the lambda function cloudformation resource created by serverless for the serverless function named graphql serviceRoleArn: { Fn::GetAtt: [AppSyncLambdaServiceRole, Arn] } # Where AppSyncLambdaServiceRole is an IAM role defined in Resources iamRoleStatements: # custom IAM Role statements for this DataSource. Ignored if `serviceRoleArn` is present. Auto-generated if both `serviceRoleArn` and `iamRoleStatements` are omitted - - Effect: "Allow" + - Effect: 'Allow' Action: - - "lambda:invokeFunction" + - 'lambda:invokeFunction' Resource: - - "arn:aws:lambda:{REGION}:{ACCOUNT_ID}:myFunction" - - "arn:aws:lambda:{REGION}:{ACCOUNT_ID}:myFunction:*" + - 'arn:aws:lambda:{REGION}:{ACCOUNT_ID}:myFunction' + - 'arn:aws:lambda:{REGION}:{ACCOUNT_ID}:myFunction:*' - type: HTTP name: # data source name description: 'Http endpoint' @@ -252,8 +257,8 @@ custom: - ${file({dataSources}.yml)} # link to a file with an array or object of datasources substitutions: # allows to pass variables from here to velocity templates # ${exampleVar1} will be replaced with given value in all mapping templates - exampleVar1: "${self:service.name}" - exampleVar2: {'Fn::ImportValue': 'Some-external-stuff'} + exampleVar1: '${self:service.name}' + exampleVar2: { 'Fn::ImportValue': 'Some-external-stuff' } xrayEnabled: true # Bool, Optional. Enable X-Ray. disabled by default. wafConfig: enabled: true @@ -284,7 +289,8 @@ custom: If you already have an API created in AppSync through the UI or from a different CF stack and want to manage it via Serverless then the plugin can also support that. -There is an optional *apiId* parameter that you can use to specify the ID of an existing AppSync API: +There is an optional _apiId_ parameter that you can use to specify the ID of an existing AppSync API: + ```yaml custom: appSync: @@ -292,17 +298,17 @@ custom: apiId: 1234abcd # ... ``` -Without *apiId* parameter the plugin will create a different endpoint with the same name alongside the original one. +Without _apiId_ parameter the plugin will create a different endpoint with the same name alongside the original one. -You can find the *apiId* value in the AppSync console, just open your existing AppSync API +You can find the _apiId_ value in the AppSync console, just open your existing AppSync API and go to Settings. In that case, the plugin will not attempt to create a new endpoint for you, instead, it will attach all newly configured resources to the existing endpoint. The following configuration options are only associated with the creation of a new AppSync endpoint -and will be ignored if you provide *apiId* parameter: +and will be ignored if you provide _apiId_ parameter: - name - authenticationType @@ -316,7 +322,7 @@ and will be ignored if you provide *apiId* parameter: - wafConfig So later, if you wanted to change the name of the API, or add some tags, or change the logging configuration, - anything from the list above you would have to do that via a different method, for example from the UI. +anything from the list above you would have to do that via a different method, for example from the UI. If the existing API already contains schema and resolvers those will be completely replaced by the new schema and resolvers from the code. @@ -366,15 +372,16 @@ Amazon supports [direct lambda resolvers](https://docs.aws.amazon.com/appsync/la With a direct lambda resolver, no VTL mapping template is required for either request or response. This can be an option if you would like to avoid usage of the Apache VTL langauge or require a complex resolver. You can enable direct Lambda resolvers by setting `false` as the `request` and/or `response` value. Example: + ```yml custom: appsync: mappingTemplates: - - type: Query - request: false - response: false - dataSource: myLambdaSource - field: getMyData + - type: Query + request: false + response: false + dataSource: myLambdaSource + field: getMyData ``` Furthermore, direct resolution can be enabled separately for the request and response templates. @@ -419,13 +426,13 @@ Since v1.5.0, api keys management is supported. You can pass one or more api key The keys can either be a string (name of the key with defaults) or an object of the following shape: -| property | default | description| -|--------------| ------------------|------------| -| name | *auto-generated* | Name of the key. This is used under the hood to differentiate keys in the deployment process.

Names are used in the Cfn resource name. Please, keep them short and without spaces or special characters to avoid issues. Key names are case sensitive. | -| description | *name of the key* | A short description for that key | -| expiresAfter | 365d | Expiration time for the key.
Can be expressed in hours or in "human" format (As in momentjs [add](https://momentjscom.readthedocs.io/en/latest/moment/03-manipulating/01-add/)).
eg: `24`, `30d`, `1M`, `2w`, `1y`
Min: 1d, max: 1y | -| expiresAt | *one year from now* | A specific expiration date in ISO 8601 format. Or as a unix timestamp | -| apiKeyId | `undefined` | the id if the api to update. Useful for when an api key has been created manually in the AWS console. | +| property | default | description | +| ------------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| name | _auto-generated_ | Name of the key. This is used under the hood to differentiate keys in the deployment process.

Names are used in the Cfn resource name. Please, keep them short and without spaces or special characters to avoid issues. Key names are case sensitive. | +| description | _name of the key_ | A short description for that key | +| expiresAfter | 365d | Expiration time for the key.
Can be expressed in hours or in "human" format (As in momentjs [add](https://momentjscom.readthedocs.io/en/latest/moment/03-manipulating/01-add/)).
eg: `24`, `30d`, `1M`, `2w`, `1y`
Min: 1d, max: 1y | +| expiresAt | _one year from now_ | A specific expiration date in ISO 8601 format. Or as a unix timestamp | +| apiKeyId | `undefined` | the id if the api to update. Useful for when an api key has been created manually in the AWS console. | If both `expiresAfter` and `expiresAt` are specified, `expiresAfter` takes precedence. @@ -442,6 +449,7 @@ Unnamed keys are named automatically sequentially Key1, Key2, Key3 and so forth. :bulb: If a key expires, or you have manually deleted it from the cosole, subsequent deployments will fail (after 60 days in the case it expires). You can fix that by simply removing the key from your yml file, or by renaming it (in which case, a new key will be generated). Example: + ```yml apiKeys: - name: Default # default API key. Use this name if you already have an auto-generated API key @@ -471,11 +479,9 @@ apiKeys: GeoMatchStatement: CountryCodes: - US - - ``` -:bulb: Finally, if you dont't want serverless to handle keys for you, just pass an empty array: +:bulb: Finally, if you dont't want serverless to handle keys for you, just pass an empty array: ```yml # Handle keys manually in the aws console. @@ -494,7 +500,7 @@ Throttling will disallow requests coming from the same ip address when a limit i There are several ways to enable it. Here are some examples: -````yml +```yml wafConfig: enabled: true rules: @@ -507,18 +513,18 @@ wafConfig: forwardedIPConfig: headerName: 'X-Forwarded-For' fallbackBehavior: 'MATCH' -```` +``` ### Disable Introspection Sometimes, you want to disable introspection to disallow untrusted consumers to discover the structure of your API. -````yml +```yml wafConfig: enabled: true rules: - - disableIntrospection # disables introspection for everyone -```` + - disableIntrospection # disables introspection for everyone +``` ### Using AWS Managed Rules @@ -544,29 +550,29 @@ Managed rules require `overrideAction` set and `action` not set. For more information view the [AWS Managed Rule Groups List](https://docs.aws.amazon.com/waf/latest/developerguide/aws-managed-rule-groups-list.html). - ### Per Api Key rules In some cases, you might want to enable a rule only for a given API key only. You can specify `wafRules` under the `apiKeys` configuration. The rules will apply only to the api key under which the rule is set. -````yml +```yml apiKeys: - name: MyApiKey expiresAfter: 365d wafRules: - throttle # throttles this API key - disableIntrospection # disables introspection for this API key -```` +``` Adding a rule to an API key without any _statement_ will add a "match-all" rule for that key. This is usefull for example to exclude api keys from high-level rules. In that case, you need to make sure to attribute a higher priority to that rule. Example: + - Block all requests by default - Add a rule to allow US requests - Except for the `WorldWideApiKey` key, that should have worldwide access. -````yml +```yml wafConfig: enabled: true defaultAction: Block # Block all by default @@ -587,7 +593,7 @@ apiKeys: - name: WorldWideApiKeyRule action: Allow priority: 1 # Make sure the priority is higher (lower number) to evaluate it first -```` +``` ### About priority @@ -602,7 +608,7 @@ For more info about how rules are executed, pease refer to [the documentation](h Example: -````yml +```yml wafConfig: enabled: true rules: @@ -625,8 +631,7 @@ apiKeys: priority: 1 # Priority = 1 - name: Rule7 # (no-set) Priority = 104 -```` - +``` ### Advanced usage @@ -634,7 +639,7 @@ You can also specify custom rules. For more info on how to define a rule, see th Example: -````yml +```yml wafConfig: enabled: true defaultAction: Block @@ -646,32 +651,37 @@ wafConfig: geoMatchStatement: countryCodes: - US -```` +``` ### Schema Comments -In some cases you want to enable usage of old-style comments (#) in appSync. setting the ``allowHashDescription`` setting + +In some cases you want to enable usage of old-style comments (#) in appSync. setting the `allowHashDescription` setting to true, will enable this. Example: + ```yml custom: appSync: - name: # defaults to api + name: # defaults to api allowHashDescription: true # ... other settings ``` ### Stack Outputs & Exports + `GraphQlApiId`and `GraphQlApiUrl` are exported to allow cross-stack resource reference using `Fn::ImportValue`. Output Exports are named with a `${AWS::StackName}-` prefix to the logical IDs. For example, `${AWS::StackName}-GraphQlApiId`. + > Note: CloudFormation stack outputs and logical IDs will be changed from the defaults to api name prefixed. This allows you to differentiate the APIs on your stack if you want to work with multiple APIs. + # Cli Usage ## `serverless deploy` This command will deploy all AppSync resources in the same CloudFormation template used by the other serverless resources. -* Providing the `--conceal` option will conceal the API keys from the output when the authentication type of `API_KEY` is used. +- Providing the `--conceal` option will conceal the API keys from the output when the authentication type of `API_KEY` is used. ## `validate-schema` @@ -683,7 +693,7 @@ This command will start a local graphql-playground server which is connected to For API_KEY, either the GraphQLApiKeyDefault output or the --apiKey option is required -For AMAZON_COGNITO_USER_POOLS, the -u/--username and -p/--password arguments are required. The cognito user pool client id can be provided with the --clientId option or directly in the yaml file (```custom.appSync.userPoolConfig.playgroundClientId```) +For AMAZON_COGNITO_USER_POOLS, the -u/--username and -p/--password arguments are required. The cognito user pool client id can be provided with the --clientId option or directly in the yaml file (`custom.appSync.userPoolConfig.playgroundClientId`) For OPENID_CONNECT, the --jwtToken option is required. @@ -701,7 +711,6 @@ There are 2 ways to work with offline development for serverless appsync. [serverless-appsync-offline](https://github.com/aheissenberger/serverless-appsync-offline) is based on [AppSync Emulator](https://github.com/ConduitVC/aws-utils/tree/appsync/packages/appsync-emulator-serverless). Both these packages are currently unmaintained. - # Split Stacks Plugin You can use [serverless-plugin-split-stacks](https://github.com/dougmoscrop/serverless-plugin-split-stacks) to migrate AppSync resources in nested stacks in order to work around the [~~200~~](~~) 500 resource limit. @@ -730,15 +739,85 @@ plugins: module.exports = { 'AWS::AppSync::ApiKey': { destination: 'AppSync', allowSuffix: true }, 'AWS::AppSync::DataSource': { destination: 'AppSync', allowSuffix: true }, - 'AWS::AppSync::FunctionConfiguration': { destination: 'AppSync', allowSuffix: true }, + 'AWS::AppSync::FunctionConfiguration': { + destination: 'AppSync', + allowSuffix: true, + }, 'AWS::AppSync::GraphQLApi': { destination: 'AppSync', allowSuffix: true }, 'AWS::AppSync::GraphQLSchema': { destination: 'AppSync', allowSuffix: true }, - 'AWS::AppSync::Resolver': { destination: 'AppSync', allowSuffix: true } -} + 'AWS::AppSync::Resolver': { destination: 'AppSync', allowSuffix: true }, +}; ``` 5. Enjoy :beers: +# Custom domains + +AppSync [supports custom domains](https://aws.amazon.com/blogs/mobile/introducing-custom-domain-names-for-aws-appsync-apis/). + +You need to generate and provide a valid certificate ARN for the domain (Note: Taht certificate ust be in the `us-east-1` region, no matter where you deploy your AppSync API). + +example: + +```yaml +custom: + appSync: + domain: + name: api.example.com + certificateArn: arn:aws:acm:us-east-1123456789:certificate/1c4e4c36-9a63-4685-94b7-e873402baca3 + route53: + hostedZoneId: ABCDEFGHIJKLMN # optional. If not provided, the plugin will try to find the best match from the domain name + hostedZoneName: example.com # optional. If not provided, the plugin will try to find the best match from the domain name +``` + +Domains are managed trhough the CLI commands. This allows a better flexibility and control over your domains and APIs. + +e.g. You can swap one API with another on a domain easily (for blue/green deployments) + +Note: This is currently only supported for one API. If you have multiple APIs in your stack, the first one will be used. + +## Create/delete a domain + +Before associating a domain to an API, you must first create it. You can do so using the following command. + +```bash +sls appsync-domain create +``` + +And to delete it: + +```bash +sls appsync-domain delete +``` + +If an API is associated to it, you will need to disassociate it first. + +## Associate/disassociate an API to the domain + +```bash +sls appsync-domain assoc --stage dev +``` + +You can associate an API to a domain that already has another API attached to it. The old API will be replaced by the new one. + +To disassociate an API from the domain, use + +```bash +sls appsync-domain disassoc --stage dev +``` + +## Create/delete a route53 record + +If you use Route53 for your hosted zone, you can also manage the CNAME record for your custom domain easily using the following commands. + +```bash +sls appsync-domain create-record +``` + +```bash +sls appsync-domain delete-record +``` + # Contributing If you have any questions, issue, feature request, please feel free to [open an issue](/issues/new). @@ -748,22 +827,23 @@ You are also very welcome to open a PR and we will gladely review it. # Resources ## VSCode extensions + - [AppSync Utils](https://marketplace.visualstudio.com/items?itemName=bboure.vscode-appsync-utils): A collection of snippets that make AppSync development easier - [AppSync Resolver Autocomplete](https://marketplace.visualstudio.com/items?itemName=theBenForce.appsync-resolver-autocomplete): Autocomplete support for VTL template files. ## Video tutorials -- [Building an AppSync + Serverless Framework Backend | FooBar](https://www.youtube.com/watch?v=eTUYqI_LCQ4) +- [Building an AppSync + Serverless Framework Backend | FooBar](https://www.youtube.com/watch?v=eTUYqI_LCQ4) ## Blog tutorial -- *Part 1:* [Running a scalable & reliable GraphQL endpoint with Serverless](https://serverless.com/blog/running-scalable-reliable-graphql-endpoint-with-serverless/) +- _Part 1:_ [Running a scalable & reliable GraphQL endpoint with Serverless](https://serverless.com/blog/running-scalable-reliable-graphql-endpoint-with-serverless/) -- *Part 2:* [AppSync Backend: AWS Managed GraphQL Service](https://medium.com/@sid88in/running-a-scalable-reliable-graphql-endpoint-with-serverless-24c3bb5acb43) +- _Part 2:_ [AppSync Backend: AWS Managed GraphQL Service](https://medium.com/@sid88in/running-a-scalable-reliable-graphql-endpoint-with-serverless-24c3bb5acb43) -- *Part 3:* [AppSync Frontend: AWS Managed GraphQL Service](https://hackernoon.com/running-a-scalable-reliable-graphql-endpoint-with-serverless-db16e42dc266) +- _Part 3:_ [AppSync Frontend: AWS Managed GraphQL Service](https://hackernoon.com/running-a-scalable-reliable-graphql-endpoint-with-serverless-db16e42dc266) -- *Part 4:* [Serverless AppSync Plugin: Top 10 New Features](https://medium.com/hackernoon/serverless-appsync-plugin-top-10-new-features-3faaf6789480) +- _Part 4:_ [Serverless AppSync Plugin: Top 10 New Features](https://medium.com/hackernoon/serverless-appsync-plugin-top-10-new-features-3faaf6789480) # Contributors ✨ @@ -861,6 +941,7 @@ Thanks goes to these wonderful people :clap:
Aleksa Cukovic

💻
Scott Davey

💻
Mateus Holzschuh

💻 +
Nik Van Looy

💻 diff --git a/__snapshots__/index.test.js.snap b/__snapshots__/index.test.js.snap index b85909cd..fb83abc2 100644 --- a/__snapshots__/index.test.js.snap +++ b/__snapshots__/index.test.js.snap @@ -2448,6 +2448,125 @@ Object { }, "Type": "AWS::IAM::Role", }, + "GraphQlDsOpenSearchSource2Role": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sts:AssumeRole", + ], + "Effect": "Allow", + "Principal": Object { + "Service": Array [ + "appsync.amazonaws.com", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Policies": Array [ + Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "es:ESHttpDelete", + "es:ESHttpGet", + "es:ESHttpHead", + "es:ESHttpPost", + "es:ESHttpPut", + "es:ESHttpPatch", + ], + "Effect": "Allow", + "Resource": Array [ + Object { + "Fn::Join": Array [ + "/", + Array [ + Object { + "Fn::GetAtt": Array [ + Object { + "Ref": "OSDomain", + }, + "Arn", + ], + }, + "*", + ], + ], + }, + ], + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "GraphQlDsOpenSearchSource2Policy", + }, + ], + }, + "Type": "AWS::IAM::Role", + }, + "GraphQlDsOpenSearchSourceRole": Object { + "Properties": Object { + "AssumeRolePolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "sts:AssumeRole", + ], + "Effect": "Allow", + "Principal": Object { + "Service": Array [ + "appsync.amazonaws.com", + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "Policies": Array [ + Object { + "PolicyDocument": Object { + "Statement": Array [ + Object { + "Action": Array [ + "es:ESHttpDelete", + "es:ESHttpGet", + "es:ESHttpHead", + "es:ESHttpPost", + "es:ESHttpPut", + "es:ESHttpPatch", + ], + "Effect": "Allow", + "Resource": Array [ + Object { + "Fn::Join": Array [ + ":", + Array [ + "arn", + "aws", + "es", + "us-east-1", + Object { + "Ref": "AWS::AccountId", + }, + "domain/search-my-os-domain-abcdefghijklmnop.us-east-1.es.amazonaws.com/*", + ], + ], + }, + ], + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "GraphQlDsOpenSearchSourcePolicy", + }, + ], + }, + "Type": "AWS::IAM::Role", + }, "GraphQlDsRelationalDbSourceRole": Object { "Properties": Object { "AssumeRolePolicyDocument": Object { diff --git a/example/yarn.lock b/example/yarn.lock index 15aba884..329caf86 100644 --- a/example/yarn.lock +++ b/example/yarn.lock @@ -235,9 +235,9 @@ async-each@^1.0.1: integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== async@^2.0.0, async@^2.1.2, async@^2.1.4: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + version "2.6.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221" + integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== dependencies: lodash "^4.17.14" @@ -3141,9 +3141,9 @@ locate-path@^2.0.0: path-exists "^3.0.0" lodash@^4.17.14, lodash@^4.17.4, lodash@^4.8.0: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== longest@^1.0.1: version "1.0.1" diff --git a/index.test.js b/index.test.js index db5b07ef..11a690f1 100644 --- a/index.test.js +++ b/index.test.js @@ -949,6 +949,27 @@ describe('iamRoleStatements', () => { }, }, }, + { + type: 'AMAZON_OPENSEARCH_SERVICE', + name: 'OpenSearchSource', + description: 'My OpenSearch Source', + config: { + region: 'us-east-1', + endpoint: + 'https://search-my-os-domain-abcdefghijklmnop.us-east-1.es.amazonaws.com', + }, + }, + { + type: 'AMAZON_OPENSEARCH_SERVICE', + name: 'OpenSearchSource2', + description: 'other OS Source', + config: { + region: 'us-east-1', + domain: { + Ref: 'OSDomain', + }, + }, + }, ], }); @@ -1009,6 +1030,18 @@ describe('iamRoleStatements', () => { 'https://search-my-domain-abcdefghijklmnop.us-east-1.es.amazonaws.com', }, }, + { + type: 'AMAZON_OPENSEARCH', + name: 'OpenSearchSource', + description: 'My OpenSearch Source', + config: { + serviceRoleArn: + 'arn:aws:iam::123456789012:role/service-role/myOsRole', + region: 'us-east-1', + endpoint: + 'https://search-my-os-domain-abcdefghijklmnop.us-east-1.es.amazonaws.com', + }, + }, { type: 'HTTP', name: 'HTTPSource', @@ -1447,7 +1480,27 @@ describe('Templates', () => { ).not.toHaveProperty('ResponseMappingTemplate'); }); - test('Pileline Resolver with template', () => { + test('Batch resolvers', () => { + const apiConfig = { + ...config, + mappingTemplates: [ + { + dataSource: 'ds', + type: 'Query', + field: 'field', + maxBatchSize: 5, + }, + ], + }; + + const apiResources = plugin.getResolverResources(apiConfig); + expect(apiResources.GraphQlResolverQueryfield.Properties).toHaveProperty( + 'MaxBatchSize', + 5, + ); + }); + + test('Pipeline Resolver with template', () => { const apiConfig = { ...config, functionConfigurationsLocation: 'mapping-templates', @@ -1470,7 +1523,7 @@ describe('Templates', () => { ).toHaveProperty('ResponseMappingTemplate'); }); - test('Pileline Resolver without template', () => { + test('Pipeline Resolver without template', () => { const apiConfig = { ...config, functionConfigurationsLocation: 'mapping-templates', @@ -1491,6 +1544,25 @@ describe('Templates', () => { apiResources.GraphQlFunctionConfigurationpipeline.Properties, ).not.toHaveProperty('ResponseMappingTemplate'); }); + + test('Pipeline Resolver with batching', () => { + const apiConfig = { + ...config, + functionConfigurationsLocation: 'mapping-templates', + functionConfigurations: [ + { + dataSource: 'ds', + name: 'pipeline', + maxBatchSize: 5, + }, + ], + }; + + const apiResources = plugin.getFunctionConfigurationResources(apiConfig); + expect( + apiResources.GraphQlFunctionConfigurationpipeline.Properties, + ).toHaveProperty('MaxBatchSize', 5); + }); }); describe('SyncConfig', () => { @@ -2026,4 +2098,20 @@ describe('WAF', () => { }; expect(plugin.getWafResources(apiConfig)).toMatchSnapshot(); }); + + it('should generate API key WAF with tags', () => { + const apiConfig = { + ...config, + wafConfig: { enabled: true }, + tags: { + testKey: 'testValue', + }, + }; + + const waf = plugin.getWafResources(apiConfig); + const tags = waf.GraphQlWaf.Properties.Tags; + + expect(tags[0].Key).toBe('testKey'); + expect(tags[0].Value).toBe('testValue'); + }); }); diff --git a/package.json b/package.json index 37ba3a11..0ae6873a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "serverless-appsync-plugin", - "version": "1.12.0", + "version": "1.13.0", "description": "AWS AppSync support for the Serverless Framework", "main": "src/index.js", "repository": "https://github.com/sid88in/serverless-appsync-plugin", diff --git a/src/index.js b/src/index.js index e17d48b9..204277fb 100644 --- a/src/index.js +++ b/src/index.js @@ -5,8 +5,14 @@ const { buildASTSchema } = require('graphql/utilities'); const runPlayground = require('./graphql-playground'); const getConfig = require('./get-config'); const chalk = require('chalk'); -const { has, merge } = require('ramda'); -const { parseDuration, toCfnKeys } = require('./utils'); +const { has, merge, last } = require('ramda'); +const { + parseDuration, + toCfnKeys, + getHostedZoneName, + confirmAction, + wait, +} = require('./utils'); const moment = require('moment'); const MIGRATION_DOCS = @@ -90,6 +96,89 @@ class ServerlessAppsyncPlugin { usage: 'DEPRECATED: Helps you update AppSync API', lifecycleEvents: ['update'], }, + 'appsync-domain': { + usage: 'Manage the domain for this AppSync API', + commands: { + create: { + usage: 'Create the domain in AppSync', + lifecycleEvents: ['run'], + options: { + quiet: { + usage: "Don't return an error if the domain already exists", + shortcut: 'q', + required: false, + type: 'boolean', + }, + }, + }, + delete: { + usage: 'Delete the domain from AppSync', + lifecycleEvents: ['run'], + options: { + quiet: { + usage: "Don't return an error if the domain does not exist", + shortcut: 'q', + required: false, + type: 'boolean', + }, + }, + }, + 'create-record': { + usage: 'Create the CNAME record for this domain in Route53', + lifecycleEvents: ['run'], + options: { + quiet: { + usage: "Don't return an error if the record already exists", + shortcut: 'q', + required: false, + type: 'boolean', + }, + }, + }, + 'delete-record': { + usage: 'Deletes the CNAME record for this domain from Route53', + lifecycleEvents: ['run'], + options: { + quiet: { + usage: "Don't return an error if the record does not exist", + shortcut: 'q', + required: false, + type: 'boolean', + }, + }, + }, + assoc: { + usage: 'Associate this AppSync API with the domain', + lifecycleEvents: ['run'], + options: { + yes: { + usage: 'Automatic yes to prompts', + shortcut: 'y', + required: false, + type: 'boolean', + }, + }, + }, + disassoc: { + usage: 'Disassociate the AppSync API associated to the domain', + lifecycleEvents: ['run'], + options: { + yes: { + usage: 'Automatic yes to prompts', + shortcut: 'y', + required: false, + type: 'boolean', + }, + force: { + usage: 'Force the disassociation of *any* API from this domain', + shortcut: 'f', + required: false, + type: 'boolean', + }, + }, + }, + }, + }, }; this.log = this.log.bind(this); @@ -114,6 +203,12 @@ class ServerlessAppsyncPlugin { 'after:aws:info:gatherData': () => this.gatherData(), 'after:aws:info:displayEndpoints': () => this.displayEndpoints(), 'after:aws:info:displayApiKeys': () => this.displayApiKeys(), + 'appsync-domain:create:run': async () => this.createDomain(), + 'appsync-domain:delete:run': async () => this.deleteDomain(), + 'appsync-domain:assoc:run': async () => this.assocDomain(), + 'appsync-domain:disassoc:run': async () => this.disassocDomain(), + 'appsync-domain:create-record:run': async () => this.createRecord(), + 'appsync-domain:delete-record:run': async () => this.deleteRecord(), }; } @@ -898,7 +993,8 @@ class ServerlessAppsyncPlugin { defaultStatements.push(dbStatement, secretManagerStatement); break; } - case 'AMAZON_ELASTICSEARCH': { + case 'AMAZON_ELASTICSEARCH': + case 'AMAZON_OPENSEARCH_SERVICE': { let arn; if (ds.config.domain) { arn = { @@ -916,7 +1012,7 @@ class ServerlessAppsyncPlugin { const result = rx.exec(ds.config.endpoint); if (!result) { throw new this.serverless.classes.Error( - `Invalid AWS ElasticSearch endpoint: '${ds.config.endpoint}`, + `Invalid AWS OpenSearch/ElasticSearch endpoint: '${ds.config.endpoint}`, ); } arn = { @@ -1026,6 +1122,19 @@ class ServerlessAppsyncPlugin { ], }, }; + } else if (ds.type === 'AMAZON_OPENSEARCH_SERVICE') { + resource.Properties.OpenSearchServiceConfig = { + AwsRegion: ds.config.region || config.region, + Endpoint: ds.config.endpoint || { + 'Fn::Join': [ + '', + [ + 'https://', + { 'Fn::GetAtt': [ds.config.domain, 'DomainEndpoint'] }, + ], + ], + }, + }; } else if (ds.type === 'RELATIONAL_DATABASE') { resource.Properties.RelationalDatabaseConfig = { RdsHttpEndpointConfig: { @@ -1131,6 +1240,10 @@ class ServerlessAppsyncPlugin { FunctionVersion: '2018-05-29', }; + if (tpl.maxBatchSize) { + Properties.MaxBatchSize = tpl.maxBatchSize; + } + const requestTemplate = has('request')(tpl) ? tpl.request : config.defaultMappingTemplates.request; @@ -1193,6 +1306,10 @@ class ServerlessAppsyncPlugin { FieldName: tpl.field, }; + if (tpl.maxBatchSize) { + Properties.MaxBatchSize = tpl.maxBatchSize; + } + const requestTemplate = has('request')(tpl) ? tpl.request : config.defaultMappingTemplates.request; @@ -1337,7 +1454,7 @@ class ServerlessAppsyncPlugin { wafConfig.visibilityConfig, Name, ), - Tags: apiConfig.tags, + Tags: !apiConfig.tags ? undefined : this.getTagsConfig(apiConfig), }, }, [wafAssocLogicalId]: { @@ -1706,6 +1823,344 @@ class ServerlessAppsyncPlugin { } return { 'Fn::Join': ['', templateJoin] }; } + + async getApiId() { + const { StackResources } = await this.provider.request( + 'CloudFormation', + 'describeStackResources', + { + StackName: this.provider.naming.getStackName(), + }, + ); + + const api = StackResources.find( + (resource) => resource.ResourceType === 'AWS::AppSync::GraphQLApi', + ); + + if (!api) { + throw new this.serverless.classes.Error( + 'AppSync Api not found in stack. Did you forget to deploy?', + ); + } + + return last(api.PhysicalResourceId.split('/')); + } + + getDomain() { + const config = this.loadConfig(); + const { domain } = config[0]; + + if (!domain) { + throw new this.serverless.classes.Error('Domain configuration not found'); + } + + return domain; + } + + async createDomain() { + try { + const domain = this.getDomain(); + await this.provider.request('AppSync', 'createDomainName', { + domainName: domain.name, + certificateArn: domain.certificateArn, + }); + this.log(`Domain '${domain.name}' created successfully`, { + color: 'green', + }); + } catch (error) { + if ( + error instanceof this.serverless.classes.Error && + this.options.quiet + ) { + this.log(error.message, { color: 'red' }); + } else { + throw error; + } + } + } + + async deleteDomain() { + try { + const domain = this.getDomain(); + this.log(`The domain '${domain.name} will be deleted.`); + if (!this.options.yes && !(await confirmAction())) { + return; + } + await this.provider.request('AppSync', 'deleteDomainName', { + domainName: domain.name, + }); + this.log(`Domain '${domain.name}' deleted successfully`, { + color: 'green', + }); + } catch (error) { + if ( + error instanceof this.serverless.classes.Error && + this.options.quiet + ) { + this.log(error.message, { color: 'red' }); + } else { + throw error; + } + } + } + + async getApiAssocStatus(name) { + try { + const result = await this.provider.request( + 'AppSync', + 'getApiAssociation', + { + domainName: name, + }, + ); + return result.apiAssociation; + } catch (error) { + if ( + error instanceof this.serverless.classes.Error && + error.providerErrorCodeExtension === 'NOT_FOUND_EXCEPTION' + ) { + return { associationStatus: 'NOT_FOUND' }; + } + throw error; + } + } + + async showApiAssocStatus({ name, message, desiredStatus }) { + this.log(message); + let status; + do { + const result = await this.getApiAssocStatus(name); + status = result.associationStatus || 'UNKNOWN'; + if (status !== desiredStatus) { + await wait(1000); + process.stdout.write('.'); + } + } while (status !== desiredStatus); + process.stdout.write('\n'); + } + + async assocDomain() { + const domain = this.getDomain(); + const apiId = await this.getApiId(); + const assoc = await this.getApiAssocStatus(domain.name); + + if (assoc.associationStatus !== 'NOT_FOUND' && assoc.apiId !== apiId) { + this.log( + `The domain ${domain.name} is currently associated to another API (${assoc.apiId})`, + { color: 'orange' }, + ); + if (!this.options.yes && !(await confirmAction())) { + return; + } + } else if (assoc.apiId === apiId) { + this.log('The domain is already associated to this API', { + color: 'green', + }); + return; + } + + await this.provider.request('AppSync', 'associateApi', { + domainName: domain.name, + apiId, + }); + + const message = `Associating API with domain '${domain.name}'`; + await this.showApiAssocStatus({ + name: domain.name, + message, + desiredStatus: 'SUCCESS', + }); + this.log(`API successfully associated to domain '${domain.name}'`, { + color: 'green', + }); + } + + async disassocDomain() { + const domain = this.getDomain(); + const apiId = await this.getApiId(); + const assoc = await this.getApiAssocStatus(domain.name); + + if (assoc.associationStatus === 'NOT_FOUND') { + this.log( + `The domain ${domain.name} is currently not associated to any API`, + ); + return; + } + + if (assoc.apiId !== apiId && !this.options.force) { + throw new this.serverless.classes.Error( + `The domain ${domain.name} is currently associated to another API (${assoc.apiId})\n` + + `Try running this command from that API's stack or stage, or use the --force / -f flag`, + ); + } + this.log( + `The domain ${domain.name} will be disassociated from API '${apiId}'`, + ); + + if (!this.options.yes && !(await confirmAction())) { + return; + } + + await this.provider.request('AppSync', 'disassociateApi', { + domainName: domain.name, + }); + + const message = `Disassociating API from domain '${domain.name}'`; + await this.showApiAssocStatus({ + name: domain.name, + message, + desiredStatus: 'NOT_FOUND', + }); + + this.log(`API successfully disassociated from domain '${domain.name}'`, { + color: 'green', + }); + } + + async getHostedZoneId() { + const domain = this.getDomain(); + if (typeof domain.route53 === 'object' && domain.route53.hostedZoneId) { + return domain.route53.hostedZoneId; + } else { + const { HostedZones } = await this.provider.request( + 'Route53', + 'listHostedZonesByName', + {}, + ); + const hostedZoneName = + typeof domain.route53 === 'object' && domain.route53.hostedZoneName + ? domain.route53.hostedZoneName + : getHostedZoneName(domain.name); + const foundHostedZone = HostedZones.find( + (zone) => zone.Name === hostedZoneName, + ).Id; + if (!foundHostedZone) { + throw new this.serverless.classes.Error( + `No hosted zone found for domain ${domain.name}`, + ); + } + return foundHostedZone.replace('/hostedzone/', ''); + } + } + + async getAppSyncDomainName() { + const domain = this.getDomain(); + const { domainNameConfig } = await this.provider.request( + 'AppSync', + 'getDomainName', + { + domainName: domain.name, + }, + ); + const { appsyncDomainName } = domainNameConfig || {}; + if (!appsyncDomainName) { + throw new this.serverless.classes.Error( + `Domain ${domain.name} not found\nDid you forget to run 'sls appsync domain create'?`, + ); + } + + return appsyncDomainName; + } + + async createRecord() { + this.log('Creating route53 record'); + + const domain = this.getDomain(); + const appsyncDomainName = await this.getAppSyncDomainName(); + const hostedZoneId = await this.getHostedZoneId(); + const changeId = await this.changeRoute53Record( + 'CREATE', + hostedZoneId, + appsyncDomainName, + ); + if (changeId) { + await this.checkRoute53RecordStatus(changeId); + this.log( + `CNAME record '${domain.name}' with value '${appsyncDomainName}' was created in Hosted Zone '${hostedZoneId}'`, + ); + this.log('Route53 record created successfuly', { color: 'green' }); + } + } + + async deleteRecord() { + const domain = this.getDomain(); + const appsyncDomainName = await this.getAppSyncDomainName(); + const hostedZoneId = await this.getHostedZoneId(); + + this.log( + `CNAME record '${domain.name}' with value '${appsyncDomainName}' will be deleted from Hosted Zone '${hostedZoneId}'`, + ); + if (!this.options.yes && !(await confirmAction())) { + return; + } + + this.log('Deleting route53 record'); + + const changeId = await this.changeRoute53Record( + 'DELETE', + hostedZoneId, + appsyncDomainName, + ); + if (changeId) { + await this.checkRoute53RecordStatus(changeId); + this.log( + `CNAME record '${domain.name}' with value '${appsyncDomainName}' was deleted from Hosted Zone '${hostedZoneId}'`, + ); + this.log('Route53 record deleted successfuly', { color: 'green' }); + } + } + + async checkRoute53RecordStatus(changeId) { + let result; + do { + result = await this.provider.request('Route53', 'getChange', { + Id: changeId, + }); + if (result.ChangeInfo.Status !== 'INSYNC') { + await wait(1000); + process.stdout.write('.'); + } + } while (result.ChangeInfo.Status !== 'INSYNC'); + process.stdout.write('\n'); + } + + async changeRoute53Record(action, hostedZoneId, cname) { + const domain = this.getDomain(); + + try { + const { ChangeInfo } = await this.provider.request( + 'Route53', + 'changeResourceRecordSets', + { + HostedZoneId: hostedZoneId, + ChangeBatch: { + Changes: [ + { + Action: action, + ResourceRecordSet: { + Name: domain.name, + Type: 'CNAME', + ResourceRecords: [{ Value: cname }], + TTL: 300, + }, + }, + ], + }, + }, + ); + + return ChangeInfo.Id; + } catch (error) { + if ( + error instanceof this.serverless.classes.Error && + this.options.quiet + ) { + this.log(error.message, { color: 'red' }); + } else { + throw error; + } + } + } } module.exports = ServerlessAppsyncPlugin; diff --git a/src/utils.js b/src/utils.js index dc0cdb27..1ffa18f4 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,5 +1,7 @@ const moment = require('moment'); const { upperFirst, transform } = require('lodash'); +const { promisify } = require('util'); +const readline = require('readline'); const timeUnits = [ 'years?', @@ -31,6 +33,37 @@ const toCfnKeys = (object) => return acc; }); +const question = async (question) => { + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + const q = promisify((question, cb) => { + rl.question(question, (a) => { + cb(null, a); + }); + }).bind(rl); + + const answer = await q(`${question}: `); + rl.close(); + + return answer; +}; + +const confirmAction = async () => { + const answer = await question('Do you want to continue? y/N'); + + return answer.toLowerCase() === 'y'; +}; + +const wait = async (time) => { + await new Promise((resolve) => setTimeout(resolve, time)); +}; + +const getHostedZoneName = (domain) => { + return `${domain.split('.').slice(1).join('.')}.`; +}; + module.exports = { parseDuration: (input) => { let duration; @@ -71,4 +104,7 @@ module.exports = { return duration; }, toCfnKeys, + getHostedZoneName, + confirmAction, + wait, }; diff --git a/yarn.lock b/yarn.lock index bfc03a52..f934ca78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18,33 +18,38 @@ "@babel/highlight" "^7.10.4" "@babel/code-frame@^7.0.0-beta.35": - version "7.15.8" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503" - integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg== + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== dependencies: - "@babel/highlight" "^7.14.5" + "@babel/highlight" "^7.16.7" -"@babel/helper-validator-identifier@^7.14.5": - version "7.15.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" - integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== -"@babel/highlight@^7.10.4", "@babel/highlight@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" - integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== +"@babel/highlight@^7.10.4", "@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== dependencies: - "@babel/helper-validator-identifier" "^7.14.5" + "@babel/helper-validator-identifier" "^7.16.7" chalk "^2.0.0" js-tokens "^4.0.0" "@babel/runtime@^7.14.6", "@babel/runtime@^7.7.6": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" - integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" + integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== dependencies: regenerator-runtime "^0.13.4" +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -69,21 +74,21 @@ "@graphql-tools/utils" "8.0.2" tslib "~2.3.0" -"@graphql-tools/merge@^8.2.0": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.0.tgz#8f6638eeecf19f59fef28598024308e0452dd0a2" - integrity sha512-nfMLYF7zczjnIbChZtqbvozRfuRweMD1Fe9HHd4RXd3Tcsj6E17srW0QJfxUoIIWh4pitj+XwZAwhj1PWBDU7g== +"@graphql-tools/merge@^8.2.1": + version "8.2.2" + resolved "https://registry.yarnpkg.com/@graphql-tools/merge/-/merge-8.2.2.tgz#433566c662a33f5a9c3cc5f3ce3753fb0019477a" + integrity sha512-2DyqhIOMUMKbCPqo8p6xSdll2OBcBxGdOrxlJJlFQvinsSaYqp/ct3dhAxNtzaIcvSVgXvttQqfD7O2ziFtE7Q== dependencies: - "@graphql-tools/utils" "^8.4.0" + "@graphql-tools/utils" "^8.5.1" tslib "~2.3.0" "@graphql-tools/schema@^8.0.2": - version "8.3.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.0.tgz#ddf4297859c6d7ac1ebbbd91460260ed424115db" - integrity sha512-OJD4Q1Xa3sffRiHzy0sskZz9ZWeqaujINfoim4CTk5Y9es1LS+WnKi25wVhmL2SGzzmKuAv7oDn+dpQAlM+Gfw== + version "8.3.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/schema/-/schema-8.3.1.tgz#1ee9da494d2da457643b3c93502b94c3c4b68c74" + integrity sha512-3R0AJFe715p4GwF067G5i0KCr/XIdvSfDLvTLEiTDQ8V/hwbOHEKHKWlEBHGRQwkG5lwFQlW1aOn7VnlPERnWQ== dependencies: - "@graphql-tools/merge" "^8.2.0" - "@graphql-tools/utils" "^8.4.0" + "@graphql-tools/merge" "^8.2.1" + "@graphql-tools/utils" "^8.5.1" tslib "~2.3.0" value-or-promise "1.0.11" @@ -94,10 +99,10 @@ dependencies: tslib "~2.3.0" -"@graphql-tools/utils@^8.4.0": - version "8.5.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.5.0.tgz#439487ac756d9458a33091e5e0435ddf8e794f3e" - integrity sha512-jMwLm6YdN+Vbqntg5GHqDvGLpLa/xPSpRs/c40d0rBuel77wo7AaQ8jHeBSpp9y+7kp7HrGSWff1u7yJ7F8ppw== +"@graphql-tools/utils@^8.5.1": + version "8.6.1" + resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-8.6.1.tgz#52c7eb108f2ca2fd01bdba8eef85077ead1bf882" + integrity sha512-uxcfHCocp4ENoIiovPxUWZEHOnbXqj3ekWc0rm7fUhW93a1xheARNHcNKhwMTR+UKXVJbTFQdGI1Rl5XdyvDBg== dependencies: tslib "~2.3.0" @@ -111,9 +116,9 @@ minimatch "^3.0.4" "@humanwhocodes/object-schema@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" - integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@mrmlnc/readdir-enhanced@^2.2.1": version "2.2.1" @@ -203,9 +208,9 @@ integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= "@serverless/cli@^1.5.2": - version "1.5.3" - resolved "https://registry.yarnpkg.com/@serverless/cli/-/cli-1.5.3.tgz#61045cdc11c0f41f50ee1ce784dfa8f0f4f26416" - integrity sha512-ZJ0Y7CsYoE/i45XkIMl/XBZO4KIlt0XH1qwxxNE2/84bZlih5cgRV6MZ+rKt7GlrD0iDAgQGyGv5dpyt+SGhKw== + version "1.6.0" + resolved "https://registry.yarnpkg.com/@serverless/cli/-/cli-1.6.0.tgz#d020f67748401ca209a4fc6407929581810573e2" + integrity sha512-1Muw/KhS4sZ6+ZrXBdmVY9zAwZh03lF7v1DKtaZ0cmxjqQBwPLoO40rOGXlxR97pyufe2NS6rD/p+ri8NGqeXg== dependencies: "@serverless/core" "^1.1.2" "@serverless/template" "^1.1.3" @@ -475,9 +480,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.123": - version "4.14.176" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.176.tgz#641150fc1cda36fbfa329de603bbb175d7ee20c0" - integrity sha512-xZmuPTa3rlZoIbtDUyJKZQimJV3bxCmzMIO2c9Pz9afyDro6kr7R79GwcB6mRhuoPmV2p1Vb66WOJH7F886WKQ== + version "4.14.178" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.178.tgz#341f6d2247db528d4a13ddbb374bcdc80406f4f8" + integrity sha512-0d5Wd09ItQWH1qFbEyQ7oTQ3GZrMfth5JkbN3EvTKLXcHLRDSXeLnlvlOn0wvxVIwK5o2M8JzP/OWz7T3NRsbw== "@types/long@^4.0.1": version "4.0.1" @@ -490,9 +495,9 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/node@*", "@types/node@>=13.7.0": - version "16.11.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.4.tgz#90771124822d6663814f7c1c9b45a6654d8fd964" - integrity sha512-TMgXmy0v2xWyuCSCJM6NCna2snndD8yvQF67J29ipdzMcsPa9u+o0tjF5+EQNdhcuZplYuouYqpc4zcd5I6amQ== + version "17.0.17" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.17.tgz#a8ddf6e0c2341718d74ee3dc413a13a042c45a0c" + integrity sha512-e8PUNQy1HgJGV3iU/Bp2+D/DXh3PYeyli8LgIwsQcs1Ar1LoaWHSIT6Rw+H2rNJmiq6SNWiDytfx8+gYj7wDHw== "@types/object-assign@^4.0.30": version "4.0.30" @@ -507,9 +512,9 @@ "@types/request" "*" "@types/request@*", "@types/request@^2.48.3": - version "2.48.7" - resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.7.tgz#a962d11a26e0d71d9a9913d96bb806dc4d4c2f19" - integrity sha512-GWP9AZW7foLd4YQxyFZDBepl0lPsWLMEXDZUjQ/c1gqVPDPECrRZyEzuhJdnPWioFCq3Tv0qoGpMD6U+ygd4ZA== + version "2.48.8" + resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.8.tgz#0b90fde3b655ab50976cb8c5ac00faca22f5a82c" + integrity sha512-whjk1EDJPcAR2kYHRbFl/lKeeKYTi05A15K9bnLInCVroNDCtXce57xKdI0/rQaA3K+6q0eFyUBPmqfSndUZdQ== dependencies: "@types/caseless" "*" "@types/node" "*" @@ -527,12 +532,12 @@ abab@^2.0.0: integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== accepts@^1.3.5: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" acorn-globals@^4.1.0: version "4.3.4" @@ -605,9 +610,9 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6: uri-js "^4.2.2" ajv@^8.0.1: - version "8.6.3" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.3.tgz#11a66527761dc3e9a3845ea775d2d3c0414e8764" - integrity sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw== + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -857,9 +862,9 @@ arrify@^1.0.1: integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + version "0.2.6" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== dependencies: safer-buffer "~2.1.0" @@ -896,9 +901,9 @@ async@^2.1.4, async@^2.6.1, async@^2.6.3: lodash "^4.17.14" async@^3.0.1, async@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.1.tgz#d3274ec66d107a47476a4c49136aacdb00665fc8" - integrity sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg== + version "3.2.3" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9" + integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g== asynckit@^0.4.0: version "0.4.0" @@ -911,14 +916,14 @@ atob@^2.1.2: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== aws-sdk@^2.869.0, aws-sdk@^2.881.0: - version "2.1013.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1013.0.tgz#85babc473b0bc90cc1160eb48baf616ddb86e346" - integrity sha512-TXxkp/meAdofpC15goFpNuur7fvh/mcMRfHJoP1jYzTtD0wcoB4FK16GLcny0uDYgkQgZuiO9QYv3Rq5bhGCqQ== + version "2.1073.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1073.0.tgz#96c0c25c89f814c4aa4262e6eeef20eec9fda0da" + integrity sha512-TtyHDL4ZEs8Zh/DqWY/hv745DTWrIwOyBAvfjBJ45RE9h0TjpWqCIowEtb6gRPAKyPPyfGH4s+rEYu07vNK1Hg== dependencies: buffer "4.9.2" events "1.1.1" ieee754 "1.1.13" - jmespath "0.15.0" + jmespath "0.16.0" querystring "0.2.0" sax "1.2.1" url "0.10.3" @@ -1414,13 +1419,10 @@ caw@^2.0.1: tunnel-agent "^0.6.0" url-to-options "^1.0.1" -chalk@*, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" +chalk@*: + version "5.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.0.tgz#bd96c6bb8e02b96e08c0c3ee2a9d90e050c7b832" + integrity sha512-/duVOqst+luxCQRKEo4bNxinsOQtMP80ZYm7mMqzuh5PociNL0PvmHFvREJ9ueYL2TxlHjBcmLCdmocx9Vg+IQ== chalk@^1.1.3: version "1.1.3" @@ -1442,6 +1444,14 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -1459,9 +1469,9 @@ child-process-ext@^2.1.1: stream-promise "^3.2.0" chokidar@^3.4.1, chokidar@^3.4.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" - integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -1601,9 +1611,9 @@ color-name@^1.0.0, color-name@~1.1.4: integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== color-string@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.6.0.tgz#c3915f61fe267672cb7e1e064c9d692219f6c312" - integrity sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA== + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.0.tgz#63b6ebd1bec11999d1df3a79a7569451ac2be8aa" + integrity sha512-9Mrz2AQLefkH1UvASKj6v6hj/7eWgjnT/cVsR8CumieLoT+g900exWeNogqtweI8dxloXN9BDQTYro1oWu/5CQ== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -1626,11 +1636,6 @@ colors@1.3.x: resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - colorspace@1.1.x: version "1.1.4" resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.4.tgz#8d442d1186152f60453bf8070cd66eb364e59243" @@ -1715,11 +1720,11 @@ config-chain@^1.1.11: proto-list "~1.2.1" content-disposition@^0.5.2, content-disposition@~0.5.2: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: - safe-buffer "5.1.2" + safe-buffer "5.2.1" content-type@^1.0.4: version "1.0.4" @@ -1857,9 +1862,9 @@ dayjs@^1.10.4: integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig== debug@4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: ms "2.1.2" @@ -2042,9 +2047,9 @@ depd@~1.1.2: integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= destroy@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + version "1.1.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.1.0.tgz#b77ae22e472d85437141319d32ae40b344dff38a" + integrity sha512-R5QZrOXxSs0JDUIU/VANvRJlQVMts9C0L76HToQdPdlftfZCE7W6dyH0G4GZ5UW9fRqUOhAoCE2aGekuu+3HjQ== detect-indent@^4.0.0: version "4.0.0" @@ -2397,33 +2402,32 @@ eslint-import-resolver-node@^0.3.6: debug "^3.2.7" resolve "^1.20.0" -eslint-module-utils@^2.7.0: - version "2.7.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz#b435001c9f8dd4ab7f6d0efcae4b9696d4c24b7c" - integrity sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ== +eslint-module-utils@^2.7.2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz#ad7e3a10552fdd0642e1e55292781bd6e34876ee" + integrity sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ== dependencies: debug "^3.2.7" find-up "^2.1.0" - pkg-dir "^2.0.0" eslint-plugin-import@^2.22.1: - version "2.25.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz#b3b9160efddb702fc1636659e71ba1d10adbe9e9" - integrity sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g== + version "2.25.4" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz#322f3f916a4e9e991ac7af32032c25ce313209f1" + integrity sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA== dependencies: array-includes "^3.1.4" array.prototype.flat "^1.2.5" debug "^2.6.9" doctrine "^2.1.0" eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.7.0" + eslint-module-utils "^2.7.2" has "^1.0.3" - is-core-module "^2.7.0" + is-core-module "^2.8.0" is-glob "^4.0.3" minimatch "^3.0.4" object.values "^1.1.5" resolve "^1.20.0" - tsconfig-paths "^3.11.0" + tsconfig-paths "^3.12.0" eslint-plugin-prettier@^4.0.0: version "4.0.0" @@ -2540,9 +2544,11 @@ esrecurse@^4.3.0: estraverse "^5.2.0" essentials@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/essentials/-/essentials-1.1.1.tgz#03befbfbee7078301741279b38a806b6ca624821" - integrity sha512-SmaxoAdVu86XkZQM/u6TYSu96ZlFGwhvSk1l9zAkznFuQkMb9mRDS2iq/XWDow7R8OwBwdYH8nLyDKznMD+GWw== + version "1.2.0" + resolved "https://registry.yarnpkg.com/essentials/-/essentials-1.2.0.tgz#c6361fb648f5c8c0c51279707f6139e521a05807" + integrity sha512-kP/j7Iw7KeNE8b/o7+tr9uX2s1wegElGOoGZ2Xm35qBr4BbbEcH3/bxR2nfH9l9JANCq9AUrvKw+gRuHtZp0HQ== + dependencies: + uni-global "^1.0.0" estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" @@ -2550,9 +2556,9 @@ estraverse@^4.1.1, estraverse@^4.2.0: integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" - integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" @@ -2651,7 +2657,7 @@ ext-name@^5.0.0: ext-list "^2.0.0" sort-keys-length "^1.0.0" -ext@^1.1.2: +ext@^1.1.2, ext@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== @@ -2714,9 +2720,9 @@ extsprintf@1.3.0: integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + version "1.4.1" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" + integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" @@ -2740,10 +2746,10 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" -fast-glob@^3.0.3, fast-glob@^3.1.1: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== +fast-glob@^3.0.3, fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -2899,9 +2905,9 @@ fill-range@^7.0.1: to-regex-range "^5.0.1" find-process@^1.4.3: - version "1.4.5" - resolved "https://registry.yarnpkg.com/find-process/-/find-process-1.4.5.tgz#6a0e4c87a32ca927c05cbed7b9078d62ffaac1a4" - integrity sha512-v11rJYYISUWn+s8qZzgGnBvlzRKf3bOtlGFM8H0kw56lGQtOmLuLCzuclA5kehA2j7S5sioOWdI4woT3jDavAw== + version "1.4.7" + resolved "https://registry.yarnpkg.com/find-process/-/find-process-1.4.7.tgz#8c76962259216c381ef1099371465b5b439ea121" + integrity sha512-/U4CYp1214Xrp3u3Fqr9yNynUrr5Le4y0SsJh2lMDDSbpwYSz3M2SMWQC+wqcx79cN8PQtHQIL8KnuY9M66fdg== dependencies: chalk "^4.0.0" commander "^5.1.0" @@ -2952,9 +2958,9 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.1.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561" - integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA== + version "3.2.5" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" + integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== follow-redirects@1.5.10: version "1.5.10" @@ -3006,9 +3012,9 @@ form-data@~2.3.2: mime-types "^2.1.12" formidable@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" - integrity sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q== + version "1.2.6" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168" + integrity sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ== fragment-cache@^0.2.1: version "0.2.1" @@ -3220,9 +3226,9 @@ glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, gl path-is-absolute "^1.0.0" globals@^13.6.0, globals@^13.9.0: - version "13.11.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7" - integrity sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g== + version "13.12.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.1.tgz#ec206be932e6c77236677127577aa8e50bf1c5cb" + integrity sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw== dependencies: type-fest "^0.20.2" @@ -3246,15 +3252,15 @@ globby@^10.0.2: slash "^3.0.0" globby@^11.0.3: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" globby@^9.2.0: @@ -3312,9 +3318,9 @@ got@^9.6.0: url-parse-lax "^3.0.0" graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.6: - version "4.2.8" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" - integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== graphlib@^2.1.8: version "2.1.8" @@ -3323,19 +3329,19 @@ graphlib@^2.1.8: dependencies: lodash "^4.17.15" -graphql-playground-html@^1.6.29: - version "1.6.29" - resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.29.tgz#5b0c60a0161cc0f3116085f64c5a16cb3b2d9a16" - integrity sha512-fbF/zZKuw2sdfKp8gjTORJ/I9xBsqeEYRseWxBzuR15NHMptRTT9414IyRCs3ognZzUDr5MDJgx97SlLZCtQyA== +graphql-playground-html@^1.6.30: + version "1.6.30" + resolved "https://registry.yarnpkg.com/graphql-playground-html/-/graphql-playground-html-1.6.30.tgz#14c2a8eb7fc17bfeb1a746bbb28a11e34bf0b391" + integrity sha512-tpCujhsJMva4aqE8ULnF7/l3xw4sNRZcSHu+R00VV+W0mfp+Q20Plvcrp+5UXD+2yS6oyCXncA+zoQJQqhGCEw== dependencies: xss "^1.0.6" graphql-playground-middleware-koa@^1.6.21: - version "1.6.21" - resolved "https://registry.yarnpkg.com/graphql-playground-middleware-koa/-/graphql-playground-middleware-koa-1.6.21.tgz#8963342ed06406a1471947e5de1565e0e5bdaaaa" - integrity sha512-MswXglk3lfKN9OH2tYYZTrSLgOLEyw0onIxHmqYuBxRnMaXp79HSH/cvgk0oRK4N+4HjJZzSkcdhxIG0Wg8qhw== + version "1.6.22" + resolved "https://registry.yarnpkg.com/graphql-playground-middleware-koa/-/graphql-playground-middleware-koa-1.6.22.tgz#23937dd4dd73ae4c4cb8599b904b5ba59b4a2c3d" + integrity sha512-soVUM76ecq5GHk12H69Ce7afzbYuWWc73oKMOcEkmtAn/G9NUdsNvLjLdCnHQX1V0cOUeSbmcYcrebyBOIYGMQ== dependencies: - graphql-playground-html "^1.6.29" + graphql-playground-html "^1.6.30" graphql@^14.7.0: version "14.7.0" @@ -3514,15 +3520,15 @@ http-cache-semantics@^4.0.0: integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== http-errors@^1.6.3, http-errors@~1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.0.tgz#75d1bbe497e1044f51e4ee9e704a62f28d336507" - integrity sha512-4I8r0C5JDhT5VkvI47QktDW75rNlGVsUf/8hzjCC/wkWI/jdTRmBb9aI7erSG82r1bjKY3F6k28WnsVxB1C73A== + version "1.8.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.8.1.tgz#7c3f28577cbc8a207388455dbd62295ed07bd68c" + integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== dependencies: depd "~1.1.2" inherits "2.0.4" setprototypeof "1.2.0" statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" + toidentifier "1.0.1" http-signature@~1.2.0: version "1.2.0" @@ -3571,10 +3577,10 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.1.1, ignore@^5.1.4, ignore@^5.1.8: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.1.1, ignore@^5.1.8, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== immediate@~3.0.5: version "3.0.6" @@ -3766,10 +3772,10 @@ is-ci@^1.0.10: dependencies: ci-info "^1.5.0" -is-core-module@^2.2.0, is-core-module@^2.7.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548" - integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw== +is-core-module@^2.8.0, is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== dependencies: has "^1.0.3" @@ -3917,9 +3923,9 @@ is-natural-number@^4.0.1: integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== is-number-object@^1.0.4: version "1.0.6" @@ -4032,11 +4038,11 @@ is-utf8@^0.2.0: integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== dependencies: - call-bind "^1.0.0" + call-bind "^1.0.2" is-windows@^1.0.2: version "1.0.2" @@ -4464,10 +4470,10 @@ jest@^22.1.4: import-local "^1.0.0" jest-cli "^22.4.4" -jmespath@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= +jmespath@0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" + integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -4540,12 +4546,12 @@ json-cycle@^1.3.0: integrity sha512-FD/SedD78LCdSvJaOUQAXseT8oQBb5z6IVYaQaCrVUlu9zOAr1BDdKyVYQaSD/GDsAMrXpKcOyBD4LIl8nfjHw== json-fixer@^1.5.1: - version "1.6.12" - resolved "https://registry.yarnpkg.com/json-fixer/-/json-fixer-1.6.12.tgz#352026c905c6366e214c9f10f77d6d7f93c48322" - integrity sha512-BGO9HExf0ZUVYvuWsps71Re513Ss0il1Wp7wYWkir2NthzincvNJEUu82KagEfAkGdjOMsypj3t2JB7drBKWnA== + version "1.6.13" + resolved "https://registry.yarnpkg.com/json-fixer/-/json-fixer-1.6.13.tgz#27d2f0e837aec54afbc9ec1cd8c1dd965bf534c9" + integrity sha512-DKQ71M+0uwAG3QsUkeVgh6XREw/OkpnTfHfM+sdmxRjHvYZ8PlcMVF4ibsHQ1ckR63NROs68qUr1I0u6yPVePQ== dependencies: "@babel/runtime" "^7.14.6" - chalk "^4.1.1" + chalk "^4.1.2" pegjs "^0.10.0" json-refs@^3.0.15: @@ -4572,10 +4578,10 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= +json-schema@0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" @@ -4607,9 +4613,9 @@ json5@^1.0.1: minimist "^1.2.0" jsonata@^1.8.3: - version "1.8.5" - resolved "https://registry.yarnpkg.com/jsonata/-/jsonata-1.8.5.tgz#c656c929c92b3fb097792cef661c27c52dfa5148" - integrity sha512-ilDyTBkg6qhNoNVr8PUPzz5GYvRK+REKOM5MdOGzH2y6V4yvPRMegSvbZLpbTtI0QAgz09QM7drDhSHUlwp9pA== + version "1.8.6" + resolved "https://registry.yarnpkg.com/jsonata/-/jsonata-1.8.6.tgz#e5f0e6ace870a34bac881a182ca2b31227122791" + integrity sha512-ZH2TPYdNP2JecOl/HvrH47Xc+9imibEMQ4YqKy/F/FrM+2a6vfbGxeCX23dB9Fr6uvGwv+ghf1KxWB3iZk09wA== jsonfile@^4.0.0: version "4.0.0" @@ -4624,13 +4630,13 @@ jsonify@~0.0.0: integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + version "1.4.2" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== dependencies: assert-plus "1.0.0" extsprintf "1.3.0" - json-schema "0.2.3" + json-schema "0.4.0" verror "1.10.0" jszip@^3.5.0: @@ -4815,11 +4821,6 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - lodash.defaults@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" @@ -4878,15 +4879,15 @@ log@^6.0.0: type "^2.5.0" uni-global "^1.0.0" -logform@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.3.0.tgz#a3997a05985de2ebd325ae0d166dffc9c6fe6b57" - integrity sha512-graeoWUH2knKbGthMtuG1EfaSPMZFZBIrhuJHhkS5ZseFBrc7DupCzihOQAzsK/qIKPQaPJ/lFQFctILUY5ARQ== +logform@^2.1.1, logform@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.0.tgz#131651715a17d50f09c2a2c1a524ff1a4164bcfe" + integrity sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw== dependencies: - colors "^1.2.1" + "@colors/colors" "1.5.0" fecha "^4.2.0" ms "^2.1.1" - safe-stable-stringify "^1.1.0" + safe-stable-stringify "^2.3.1" triple-beam "^1.3.0" long@^4.0.0: @@ -5002,7 +5003,7 @@ merge-stream@^1.0.1: dependencies: readable-stream "^2.0.1" -merge2@^1.2.3, merge2@^1.3.0: +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -5063,17 +5064,17 @@ micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" -mime-db@1.50.0, mime-db@^1.28.0: - version "1.50.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" - integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== +mime-db@1.51.0, mime-db@^1.28.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.51.0.tgz#d9ff62451859b18342d960850dc3cfb77e63fb0c" + integrity sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g== -mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.33" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" - integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g== +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.34" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.34.tgz#5a712f9ec1503511a945803640fafe09d3793c24" + integrity sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A== dependencies: - mime-db "1.50.0" + mime-db "1.51.0" mime@^1.4.1: version "1.6.0" @@ -5096,9 +5097,9 @@ mimic-response@^1.0.0, mimic-response@^1.0.1: integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + version "3.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" + integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== dependencies: brace-expansion "^1.1.7" @@ -5190,22 +5191,23 @@ natural-compare@^1.4.0: integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= ncjsm@^4.0.1, ncjsm@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/ncjsm/-/ncjsm-4.2.0.tgz#7b2d752c3a42db5f6a2c5ff6934cf66fb1bb5e38" - integrity sha512-L2Qij4PTy7Bs4TB24zs7FLIAYJTaR5JPvSig5hIcO059LnMCNgy6MfHHNyg8s/aekPKrTqKX90gBGt3NNGvhdw== + version "4.3.0" + resolved "https://registry.yarnpkg.com/ncjsm/-/ncjsm-4.3.0.tgz#ec2301ad67475f414a50de34fae00ebc31527e38" + integrity sha512-oah6YGwb4Ern2alojiMFcjPhE4wvQBw1Ur/kUr2P0ovKdzaF5pCIsGjs0f2y+iZeej0/5Y6OOhQ8j30cTDMEGw== dependencies: builtin-modules "^3.2.0" deferred "^0.7.11" es5-ext "^0.10.53" es6-set "^0.1.5" + ext "^1.6.0" find-requires "^1.0.0" fs2 "^0.3.9" type "^2.5.0" -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== neo-async@^2.6.0: version "2.6.2" @@ -5235,9 +5237,9 @@ node-dir@^0.1.17: minimatch "^3.0.2" node-fetch@^2.6.0, node-fetch@^2.6.1: - version "2.6.5" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd" - integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ== + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== dependencies: whatwg-url "^5.0.0" @@ -5343,9 +5345,9 @@ object-hash@^2.1.1: integrity sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw== object-inspect@^1.11.0, object-inspect@^1.9.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" - integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg== + version "1.12.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" + integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -5679,7 +5681,7 @@ path-loader@^1.0.10: native-promise-only "^0.8.1" superagent "^3.8.3" -path-parse@^1.0.5, path-parse@^1.0.6: +path-parse@^1.0.5, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -5721,9 +5723,9 @@ performance-now@^2.1.0: integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pify@^2.0.0, pify@^2.3.0: version "2.3.0" @@ -5802,9 +5804,9 @@ prettier-linter-helpers@^1.0.0: fast-diff "^1.1.2" prettier@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" - integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== + version "2.5.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.5.1.tgz#fff75fa9d519c54cf0fce328c1017d94546bc56a" + integrity sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg== pretty-format@^22.4.0, pretty-format@^22.4.3: version "22.4.3" @@ -5896,16 +5898,16 @@ punycode@^2.1.0, punycode@^2.1.1: integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@^6.5.1: - version "6.10.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.1.tgz#4931482fa8d647a5aab799c5271d2133b981fb6a" - integrity sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg== + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== dependencies: side-channel "^1.0.4" qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + version "6.5.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== query-string@^5.0.1: version "5.1.1" @@ -6174,12 +6176,13 @@ resolve@1.1.7: integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= resolve@^1.10.0, resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" responselike@1.0.2, responselike@^1.0.2: version "1.0.2" @@ -6252,16 +6255,16 @@ rxjs@^6.4.0, rxjs@^6.6.0, rxjs@^6.6.2: dependencies: tslib "^1.9.0" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -6269,10 +6272,10 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -safe-stable-stringify@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz#c8a220ab525cd94e60ebf47ddc404d610dc5d84a" - integrity sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw== +safe-stable-stringify@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73" + integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg== "safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" @@ -6466,9 +6469,9 @@ side-channel@^1.0.4: object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.5" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" - integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== simple-git@^1.132.0: version "1.132.0" @@ -6604,9 +6607,9 @@ source-map-support@^0.4.15: source-map "^0.5.6" source-map-support@^0.5.0, source-map-support@^0.5.19: - version "0.5.20" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" - integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" @@ -6648,9 +6651,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.10" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz#0d9becccde7003d6c658d487dd48a32f0bf3014b" - integrity sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA== + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -6679,9 +6682,9 @@ sprintf-kit@^2.0.1: es5-ext "^0.10.53" sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + version "1.17.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== dependencies: asn1 "~0.2.3" assert-plus "^1.0.0" @@ -6943,18 +6946,22 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + symbol-tree@^3.2.2: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^6.0.9: - version "6.7.2" - resolved "https://registry.yarnpkg.com/table/-/table-6.7.2.tgz#a8d39b9f5966693ca8b0feba270a78722cbaf3b0" - integrity sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g== + version "6.8.0" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.0.tgz#87e28f14fa4321c3377ba286f07b79b281a3b3ca" + integrity sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA== dependencies: ajv "^8.0.1" - lodash.clonedeep "^4.5.0" lodash.truncate "^4.4.2" slice-ansi "^4.0.0" string-width "^4.2.3" @@ -7111,10 +7118,10 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0: version "2.5.0" @@ -7153,15 +7160,15 @@ trim-right@^1.0.1: resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= -triple-beam@^1.2.0, triple-beam@^1.3.0: +triple-beam@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -tsconfig-paths@^3.11.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz#954c1fe973da6339c78e06b03ce2e48810b65f36" - integrity sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA== +tsconfig-paths@^3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz#19769aca6ee8f6a1a341e38c8fa45dd9fb18899b" + integrity sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.1" @@ -7238,14 +7245,14 @@ type@^1.0.1: integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== type@^2.0.0, type@^2.1.0, type@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" - integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== uglify-js@^3.1.4: - version "3.14.2" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.2.tgz#d7dd6a46ca57214f54a2d0a43cad0f35db82ac99" - integrity sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A== + version "3.15.1" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.15.1.tgz#9403dc6fa5695a6172a91bc983ea39f0f7c9086d" + integrity sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ== unbox-primitive@^1.0.1: version "1.0.1" @@ -7510,12 +7517,13 @@ widest-line@^2.0.0: string-width "^2.1.1" winston-transport@^4.3.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" - integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== + version "4.5.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa" + integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q== dependencies: - readable-stream "^2.3.7" - triple-beam "^1.2.0" + logform "^2.3.2" + readable-stream "^3.6.0" + triple-beam "^1.3.0" winston@3.2.1: version "3.2.1" @@ -7588,9 +7596,9 @@ ws@^5.2.0: async-limiter "~1.0.0" ws@^7.2.1, ws@^7.3.0, ws@^7.3.1: - version "7.5.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881" - integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w== + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== ws@~7.4.2: version "7.4.6"